【问题标题】:SVG rounded triangle with gradient overlay and background image带有渐变叠加和背景图像的 SVG 圆角三角形
【发布时间】:2019-02-04 20:46:57
【问题描述】:

我有下面的代码创建一个带有紫色渐变的简单圆角三角形。我正在尝试插入一个背景图像,该图像将填充渐变下方的形状,以创建与下面的屏幕截图类似的效果:

我想要实现的目标:

到目前为止我的代码(不显示图像):

 <svg width="100%" viewBox="0 0 1440 742" version="1.1"
      baseProfile="full"
      xmlns="http://www.w3.org/2000/svg"
      xmlns:xlink="http://www.w3.org/1999/xlink"
      xmlns:ev="http://www.w3.org/2001/xml-events">
     <defs>
         <linearGradient x1="100%" y1="50%" x2="0%" y2="50%" id="linearGradient-1">
             <stop stop-color="#6300FF" stop-opacity="0.7" offset="0%"></stop>
             <stop stop-color="#251D4B" offset="100%"></stop>
         </linearGradient>
         <pattern id="img1" patternUnits="userSpaceOnUse" width="1400" height="742">
             <image xlink:href="https://upload.wikimedia.org/wikipedia/commons/1/11/Varkala_Beach_High_Res.jpg" x="0" y="0" width="1400" height="742" />
         </pattern>
         <path d="M526.611472,1330.75724 C526.681681,1330.68703 525.998884,-525.688822 526.611472,-525.076039 L1243.10385,191.419563 C1359.86286,308.179101 1359.86286,497.502097 1243.10385,614.261635 L526.611472,1330.75724 Z" id="path-2"></path>
     </defs>
     <g id="Desktop" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
         <g id="Knowledge-base-article">
             <g id="businessman-in-workplace-PYDTUKV" transform="translate(-209.000000, -63.000000)">
                 <mask id="mask-3" fill="white">
                     <use xlink:href="#path-2"></use>
                     <use xlink:href="#img1"></use>
                 </mask>
                 <use id="Mask" fill="url(#linearGradient-1)" transform="translate(928.513633, 402.840523) scale(-1, 1) rotate(90.000000) translate(-928.513633, -402.840523) " xlink:href="#path-2"></use>
             </g>
         </g>
     </g>
 </svg>

【问题讨论】:

    标签: css image svg mask clip-path


    【解决方案1】:

    我会使用纯 CSS 解决方案,使用如下所示的一些转换

    .container {
      width:300px;
      height:300px;
      margin:auto;
      position:relative;
      overflow:hidden;
    }
    .container > div {
      position:absolute;
      width:100%;
      height:100%;
      border-radius:80px;
      transform-origin:top left;
      transform:translateX(-20%) rotate(-45deg);
      overflow:hidden;
    }
    .container > div:before {
       content:"";
       position:absolute;
       width:calc(100% * 1.4);
       height:calc(100% * 1.4);
       transform:rotate(45deg);
      transform-origin:top left;
       background:
        linear-gradient(to top,rgba(99, 0, 255, 0.7),#251D4B),
        url(https://picsum.photos/300/300?image=1069) top/cover;
    }
    <div class="container">
      <div></div>
    </div>

    容器为全宽:

    .container {
      margin:auto;
      position:relative;
      overflow:hidden;
    }
    .container > div {
      width:100%;
      padding-top:100%;
      border-radius:15%;
      transform-origin:top left;
      transform:translateY(-15%) translateX(-21%) rotate(-45deg);
      overflow:hidden;
    }
    .container > div:before {
       content:"";
       position:absolute;
       top:0;
       left:0;
       width:calc(100% * 1.4);
       height:calc(100% * 1.4);
       transform:rotate(45deg);
       transform-origin:top left;
       background:
        linear-gradient(to top,rgba(99, 0, 255, 0.7),#251D4B),
        url(https://picsum.photos/300/300?image=1069) top/cover;
    }
    <div class="container">
      <div></div>
    </div>

    【讨论】:

    • 一个很好的解决方案,但是当将 .container 更改为 100% 宽度时,问题就开始出现了
    • 不错,看起来不错。我可以理解,什么是宽度:calc(100% * 1.4);在伪元素上做什么?
    • @egr103 好吧,您可以将其替换为 140% .. 1.4 是 sqrt(2)。如果您想了解有关计算的更多详细信息,请检查此:stackoverflow.com/a/51689026/8620333
    • 我理解它是一个计算,但它是否只是为了让图像比容器更大以便覆盖形状?
    • @egr103 是的,让它更大,但 1.4 将提供确切的尺寸需求(如您在我共享的链接中所见)
    【解决方案2】:

    &lt;path&gt; 用作&lt;mask&gt;。然后在&lt;image&gt; 上使用&lt;mask&gt;,然后在位于顶部的&lt;rect&gt; 上使用相同的&lt;mask&gt;。最后用您的&lt;gradient&gt; 填写&lt;rect&gt;

    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 800">
      <defs>
         <linearGradient x1="100%" y1="50%" x2="0%" y2="50%" id="gradient">
           <stop stop-color="#6300FF" stop-opacity="0.7" offset="0%"></stop>
           <stop stop-color="#251D4B" offset="100%"></stop>
         </linearGradient>
        <mask id="mask">
          <path d="M812.532 489.667L1306.8 -4.60034H-106L388.268 489.667C505.425 606.825 695.374 606.825 812.532 489.667Z" fill="#C4C4C4"/>
        </mask>
      </defs>
      <image xlink:href="https://upload.wikimedia.org/wikipedia/commons/1/11/Varkala_Beach_High_Res.jpg" x="0" y="0" width="1200" height="800" mask="url(#mask)" />
      <rect width="1400" height="742" mask="url(#mask)" fill="url(#gradient)"></rect>
    </svg>

    【讨论】:

    • 一个很棒的解决方案,但是一个纯 css 解决方案,虽然不是我要求的,但它是一个非常适合我的场景的奖金。
    猜你喜欢
    • 2016-11-02
    • 2016-03-18
    • 2012-06-13
    • 2011-05-16
    • 2011-08-23
    • 1970-01-01
    • 1970-01-01
    • 2015-08-29
    相关资源
    最近更新 更多