【问题标题】:Centered background image within SVGSVG 中的居中背景图像
【发布时间】:2020-01-22 08:50:09
【问题描述】:

我想在 SVG 中添加一个居中的图像。

它将充当用户头像但未能这样做

.body {
  width: 100%;
  height: 100%;
  background: #1f1b33;
  padding: 2rem;
}

svg {
width: 120px;
}
<div class="body">
    <svg viewBox="0 0 121.375 125.397">
      <g
        id="blank"
        transform="translate(-1460.94 -927.887)"
      >
        <path
          id="wrapper"
          data-name="Caminho 2257"
          d="M80.617,78.013C67.787,91.6,11.606,90.985-8.689,69.872s-20.527-73.915,0-90.659S66.834-47.3,87.13-26.188,93.447,64.424,80.617,78.013Z"
          transform="translate(1484.938 966.119)"
          fill="#fff"
          opacity="0.2"
        />
        <rect
          id="within"
          data-name="Retângulo 365"
          width="97"
          height="97"
          rx="37"
          transform="translate(1475 945)"
          fill="#fff"
        />
      </g>
    </svg>
  </div

我已经尝试在 SVG 中创建一个图像元素并将其引用为填充,但图像未居中。

【问题讨论】:

  • 没有得到你想要的,你需要居中SVGSVG中的一部分居中?
  • @Zuber 在rect 而不是fill=color 需要fill=image
  • 您可以在wrapper 中使用csssvg 用作background-image,并使用padding。将 avatar image 放入该包装器中。
  • @Zuber你不懂,我需要图片和矩形一样的形状,我只需要用居中的图片替换颜色。

标签: html css svg


【解决方案1】:

可以通过多种方式将图像插入到任何 SVG 形状中:

  1. 使用 clipPath
  2. 使用面具
  3. 使用模式

使用任何插入图像的方法,您都需要关注模板的形状。

如果模板为对称形状,则需要选择长宽比相同的原图。

也就是说,如果裁剪图案是圆形或正多边形,则需要选择宽度和高度相同的图像。

使用掩码

我选择了一张方形图片

.body {
  
  padding: 2rem;
  background-color:#1f1b33;
}

svg {
width: 25%;
height:25%;
} 
image {
width:100%;
height:100%;
mask:url(#msk1);
}
<div class="body">
    <svg  viewBox="0 0 121.375 125.397" preserveAspectRatio="xMinYMin meet">
	 <defs> 
  <mask id="msk1"> 
    <rect width="100%" height="100%" fill="black" />
   <rect
          id="within"
          data-name="Retângulo 365"
		   x="10" y="10"
          width="97"
          height="97"
          rx="37"
          fill="white"
		  stroke="#d5d5d5"
		  stroke-width="4"
        />
  </mask>
</defs> 
  <rect width="100%" height="100%" fill="#1f1b33" />
      <g
        id="blank"
        transform="translate(-1460.94 -927.887)"
      >
        <path
          id="wrapper"
          data-name="Caminho 2257"
          d="M80.617,78.013C67.787,91.6,11.606,90.985-8.689,69.872s-20.527-73.915,0-90.659S66.834-47.3,87.13-26.188,93.447,64.424,80.617,78.013Z"
          transform="translate(1484.938 966.119)"
          fill="#fff"
          opacity="0.2"
        /> 
		</g>
        <rect
          id="within"
          data-name="Retângulo 365"
          x="10" y="10"
		  width="97"
          height="97"
          rx="37"
         
          fill="none"
		  stroke="black"
		  stroke-width="2"
        />
       
	   <image xlink:href="https://i.stack.imgur.com/UsGg5.jpg" x="0" y="0"/>	
    </svg>
  </div>

2.#悬停时图片旋转动画

CSS规则用于实现图片的旋转

#img {
transform-origin:125px 125px;
  -webkit-transition: -webkit-transform 1s ease-in-out;
          transition:         transform 1s ease-in-out;
}

#img:hover {
  -webkit-transform: rotate(360deg);
          transform: rotate(360deg);
}

.body {
  
  padding: 2rem;
  background-color:#1f1b33;
}

svg {
width: 25%;
height:25%;
} 


#img {
width:100%;
height:100%;
mask:url(#msk1);
transform-box: fill-box;
transform-origin:50% 50%;
  -webkit-transition: -webkit-transform 1s ease-in-out;
          transition:         transform 1s ease-in-out;
}

#img:hover {
  -webkit-transform: rotate(360deg);
          transform: rotate(360deg);
}
<div class="body">
    <svg  viewBox="0 0 121.375 125.397" preserveAspectRatio="xMinYMin meet">
	 <defs> 
  <mask id="msk1"> 
    <rect width="100%" height="100%" fill="black" />
   <rect
          id="within"
          data-name="Retângulo 365"
		   x="10" y="10"
          width="97"
          height="97"
          rx="37"
          fill="white"
		  stroke="#d5d5d5"
		  stroke-width="4"
        />
  </mask>
</defs> 
 
      <g
        id="blank"
        transform="translate(-1460.94 -927.887)"
      >
        <path
          id="wrapper"
          data-name="Caminho 2257"
          d="M80.617,78.013C67.787,91.6,11.606,90.985-8.689,69.872s-20.527-73.915,0-90.659S66.834-47.3,87.13-26.188,93.447,64.424,80.617,78.013Z"
          transform="translate(1484.938 966.119)"
          fill="#fff"
          opacity="0.2"
        /> 
		</g>
               
	   <image id="img" xlink:href="https://i.stack.imgur.com/UsGg5.jpg" x="0" y="0"/>	
    </svg>
  </div>

【讨论】:

    【解决方案2】:

    使用图案填充是可行的方法 - 如果您的图像纵横比是方形的,它会很好地工作。请注意,图案的宽度和高度与您的矩形相同。在这种情况下,将patternUnits 设置为userSpaceOnUse 很重要,这为简单起见防止图案填充缩放到对象边界框。

    .body {
      width: 100%;
      height: 100%;
      background: #1f1b33;
      padding: 2rem;
    }
    
    svg {
      width: 120px;
    }
    <div class="body">
        <svg viewBox="0 0 121.375 125.397">
          <defs>
            <pattern id="patt" patternUnits="userSpaceOnUse" width="97" height="97">
              <image xlink:href="https://s3-us-west-2.amazonaws.com/s.cdpn.io/17496/flace.jpg" width="97" height="97"></image>
            </pattern>
          </defs>
          <g
            id="blank"
            transform="translate(-1460.94 -927.887)"
          >
            <path
              id="wrapper"
              data-name="Caminho 2257"
              d="M80.617,78.013C67.787,91.6,11.606,90.985-8.689,69.872s-20.527-73.915,0-90.659S66.834-47.3,87.13-26.188,93.447,64.424,80.617,78.013Z"
              transform="translate(1484.938 966.119)"
              fill="#fff"
              opacity="0.2"
            />
            <rect
              id="within"
              data-name="Retângulo 365"
              width="97"
              height="97"
              rx="37"
              transform="translate(1475 945)"
              fill="url(#patt)"
            />
          </g>
        </svg>
    </div>

    【讨论】:

      【解决方案3】:

      我设法让图像保持在白色的位置。

      .body {
        width: 100%;
        height: 100%;
        background: #1f1b33;
        padding: 2rem;
      }
      
      svg {
        width: 120px;
      }
      <div class="body">
      <svg
            xmlns="http://www.w3.org/2000/svg"
            xmlns:xlink="http://www.w3.org/1999/xlink"
            width="121.375"
            height="125.397"
            viewBox="0 0 121.375 125.397"
          >
            <defs>
              <clipPath id="clip-path">
                <rect
                  id="Retângulo_365"
                  data-name="Retângulo 365"
                  width="97"
                  height="97"
                  rx="37"
                  transform="translate(-932 2753)"
                  fill="#fff"
                />
              </clipPath>
              <pattern
                id="pattern"
                preserveAspectRatio="xMidYMid slice"
                width="100%"
                height="100%"
                viewBox="0 0 450 450"
              >
                <image
                  width="450"
                  height="450"
                  xlink:href="https://www.espacoluzevida.com.br/wp-content/uploads/2016/05/default-female-avatar.png"
                />
              </pattern>
            </defs>
            <g
              id="profile-image-customized"
              transform="translate(-152.94 -170.887)"
            >
              <path
                id="Caminho_2257"
                data-name="Caminho 2257"
                d="M80.617,78.013C67.787,91.6,11.606,90.985-8.689,69.872s-20.527-73.915,0-90.659S66.834-47.3,87.13-26.188,93.447,64.424,80.617,78.013Z"
                transform="translate(176.938 209.119)"
                fill="#fff"
                opacity="0.2"
              />
              <g
                id="Grupo_de_máscara_7"
                data-name="Grupo de máscara 7"
                transform="translate(1099 -2565)"
                clip-path="url(#clip-path)"
              >
                <path
                  id="_32814145-woman-avatar-profile-picture-icon-on-light-gray-background"
                  data-name="32814145-woman-avatar-profile-picture-icon-on-light-gray-background"
                  d="M0,0H97V97H0Z"
                  transform="translate(-932 2753)"
                  fill="url(#pattern)"
                />
              </g>
            </g>
          </svg>
      </div>

      【讨论】:

        【解决方案4】:

        正如@Zuber 在他的cmets 上所建议的那样,您可以学习如何做到这一点here

        代码示例:

        .body {
          width: 100%;
          height: 100%;
          background: #1f1b33;
          padding: 2rem;
        }
        
        svg { width: 120px; }
        <div class="body">
          <svg viewBox="0 0 121.375 125.397">
            <defs>
              <pattern id="img1" patternUnits="userSpaceOnUse" width="100" height="100">
                <image xlink:href="https://cdn.pixabay.com/photo/2019/09/14/21/47/dog-4476989_960_720.jpg" x="0" y="0" width="100" height="100" />
              </pattern>
            </defs>
            <g
                id="blank"
                transform="translate(-1460.94 -927.887)"
            >
              <path
                  id="wrapper"
                  data-name="Caminho 2257"          d="M80.617,78.013C67.787,91.6,11.606,90.985-8.689,69.872s-20.527-73.915,0-90.659S66.834-47.3,87.13-26.188,93.447,64.424,80.617,78.013Z"
                  transform="translate(1484.938 966.119)"
                  fill="#fff"
                  opacity="0.2"
              />
              <rect
                  id="within"
                  data-name="Retângulo 365"
                  width="97"
                  height="97"
                  rx="37"
                  transform="translate(1475 945)"
        
                  fill="url(#img1)"
              />
            </g>
          </svg>
        </div>

        【讨论】:

        • 图片没有占颜色的100%。
        • 我一定不明白,你要求填充图像而不是白色,不是吗?你想让它得到整个形状吗?
        • 显然我说我需要图片而不是颜色,我已经解决了这个问题,感谢所有帮助。
        【解决方案5】:

        如何使用伪元素 ::After 或 ::Before,将其设置为相对,然后给它一个背景图像并将不透明度或 z-index 设置为您想要的任何值?只是在外面拍一枪。

        【讨论】:

        • 最好在答案中添加一些代码...在这种情况下,您可以按照您描述的方式编辑他的代码并将其添加到答案中...干杯