代码之家  ›  专栏  ›  技术社区  ›  Todd Main

放弃所有SourceGraphic颜色/alpha和Reclor?

  •  0
  • Todd Main  · 技术社区  · 5 年前

    我有一个笔画的形状。填充为橙色,不透明度为50%(因此alpha=0.5和rgb(255112,0)),笔划为蓝色(无透明度)。

    使用滤镜,我一直在尝试复制(类似于阴影,但没有模糊)。我想要一份纯橙色的。

    但我似乎无法理解这一点 feColorMatrix 继续使用 SourceGraphic 价值观

    不知道为什么,但如果我的形状填充没有透明度,我也会使用 feComponentTransfer 同样,我可以得到实体形状的副本。

    无论形状/笔划填充/不透明度如何,右侧的形状都是我想要制作纯橙(或我选择的任何颜色和不透明度)的形状。

    <svg xmlns:xlink="http://www.w3.org/1999/xlink" width="960" height="540" class="slide" shape-rendering="geometricPrecision" fill-rule="evenodd">
          <rect width="960" height="540" stroke="#385D8A" fill="white" stroke-width="3" class="testSlideBorder" />
    
          <svg x="10" y="10" overflow="visible" stroke="#0000FF" stroke-miterlimit="8" stroke-width="4">
            <defs>
            <filter id="offsetColoredShape" height="500%" width="500%" x="-275%" y="-275%">
             <feColorMatrix in="SourceAlpha" type="matrix" values="
                                            0 0 0 0 1 
                                            0 0 0 0 0.439
                                            0 0 0 0 0 
                                            0 0 0 1 0"
                                           result="changeToOrangeFill"/>
    
        	<feComponentTransfer result="changedAgain">
                <feFuncR type="linear" slope="1" />
                <feFuncG type="linear" slope="0.439" />
                <feFuncB type="linear" slope="0" />
                <feFuncA type="linear" slope="1" />
    </feComponentTransfer>
    
        	<feOffset dx="120"/>
    	    </filter>               
      </defs>
    <use xlink:href="#star" filter="url(#offsetColoredShape)" />
            <path id="star" fill="rgb(255,112,0)" fill-opacity="0.5" d="M0,63.904L17.609,51.5L8.562,31.952L30.014,30.014L31.952,8.562L51.5,17.609L63.904,0L76.309,17.609L95.857,8.562L97.795,30.014L119.247,31.952L110.199,51.5L127.809,63.904L110.199,76.309L119.247,95.857L97.795,97.795L95.857,119.247L76.309,110.199L63.904,127.809L51.5,110.199L31.952,119.247L30.014,97.795L8.562,95.857L17.609,76.309Z" />
          </svg>
    
        </svg>

    注意 <path/> 那个 fill-opacity="0.5" .如果我改成 fill-opacity="1" ,它按预期工作。下面是它的样子:

          <svg x="10" y="10" overflow="visible" fill="#4472C4" stroke="#0000FF" stroke-miterlimit="8" stroke-width="4">
            <defs>
            <filter id="offsetColoredShape" height="500%" width="500%" x="-275%" y="-275%">
             <feColorMatrix in="SourceAlpha" type="matrix" values="
                                            0 0 0 0 1 
                                            0 0 0 0 0.439
                                            0 0 0 0 0 
                                            0 0 0 1 0"
                                           result="changeToOrangeFill"/>
    
        	<feComponentTransfer result="changedAgain">
                <feFuncR type="linear" slope="1" />
                <feFuncG type="linear" slope="0.439" />
                <feFuncB type="linear" slope="0" />
                <feFuncA type="linear" slope="1" />
            </feComponentTransfer>
    
        	<feOffset dx="120"/>
    	    </filter>               
            </defs>
            <use xlink:href="#star" filter="url(#offsetColoredShape)" />
            <path id="star" fill="rgb(255,112,0)" fill-opacity="1" d="M0,63.904L17.609,51.5L8.562,31.952L30.014,30.014L31.952,8.562L51.5,17.609L63.904,0L76.309,17.609L95.857,8.562L97.795,30.014L119.247,31.952L110.199,51.5L127.809,63.904L110.199,76.309L119.247,95.857L97.795,97.795L95.857,119.247L76.309,110.199L63.904,127.809L51.5,110.199L31.952,119.247L30.014,97.795L8.562,95.857L17.609,76.309Z" />
          </svg>
    这就是我所追求的,无论形状是否充满不透明。

    关于如何获得纯色(如黑色)和alpha=100%的颜色,有什么想法吗 源图形 ,然后可以将颜色和不透明度修改为我喜欢的任何颜色/不透明度?

    0 回复  |  直到 5 年前
        1
  •  3
  •   Michael Mullany    5 年前

    在最初的feColorMatrix中,您没有将alpha设置为100%——而是将alpha乘以1。如果要将alpha设置为100%,则应将第五列设置为1(而不是第四列)。

    现在的问题是,它将所有的背景设置为100%不透明度,这样你就可以得到剩下的图形颜色为纯黑。

    但是,我们有一个解决办法。不要使用SourceAlpha——使用SourceGraphic,并使用alpha行的前三列将彩色像素的alpha提高到100%。结果有点脆(因为我们使用了核消除混叠技术),但它确实能满足您的需求,适用于各种颜色,包括rgb(1,1,1)。

    如果你知道你的颜色不会接近黑色,那么你可以把255调低到更合理的颜色(比如5或10);至少保留一些抗锯齿功能。

          <svg x="10" y="10" overflow="visible" stroke="#0000FF" stroke-miterlimit="8" stroke-width="4" style="background:grey" color-interpolation-filters="sRGB">
            <defs>
            <filter id="offsetColoredShape" height="500%" width="500%" x="-275%" y="-275%">
             <feColorMatrix in="SourceGraphic" type="matrix" values="
                                            0 0 0 0 1 
                                            0 0 0 0 0.439
                                            0 0 0 0 0 
                                            255 255 255 1 0"
                                           result="changeToOrangeFill"/>
    
    
        	<feOffset dx="80"/>
    	    </filter>               
      </defs>
    <use xlink:href="#star" filter="url(#offsetColoredShape)" />
            <path id="star" fill="rgb(255,112,0)" fill-opacity="0.5" d="M0,63.904L17.609,51.5L8.562,31.952L30.014,30.014L31.952,8.562L51.5,17.609L63.904,0L76.309,17.609L95.857,8.562L97.795,30.014L119.247,31.952L110.199,51.5L127.809,63.904L110.199,76.309L119.247,95.857L97.795,97.795L95.857,119.247L76.309,110.199L63.904,127.809L51.5,110.199L31.952,119.247L30.014,97.795L8.562,95.857L17.609,76.309Z" />
          </svg>
        2
  •  2
  •   enxaneta    5 年前

    你可以把 #star 道路 <defs> 没有填充或笔划,你可以在第一次使用 fill-opacity="0.5" 蓝色笔划和第二次使用过滤器,如果这是你需要的。

    svg{border:1px solid}
    <svg xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="-10 -10 360 150" class="slide" shape-rendering="geometricPrecision" fill-rule="evenodd">
         
    
            <defs>
              <path id="star" stroke-miterlimit="8" d="M0,63.904L17.609,51.5L8.562,31.952L30.014,30.014L31.952,8.562L51.5,17.609L63.904,0L76.309,17.609L95.857,8.562L97.795,30.014L119.247,31.952L110.199,51.5L127.809,63.904L110.199,76.309L119.247,95.857L97.795,97.795L95.857,119.247L76.309,110.199L63.904,127.809L51.5,110.199L31.952,119.247L30.014,97.795L8.562,95.857L17.609,76.309Z" />
            <filter id="offsetColoredShape" height="500%" width="500%" x="-275%" y="-275%">
             <feColorMatrix in="SourceAlpha" type="matrix" values="
                                            0 0 0 0 1 
                                            0 0 0 0 0.439
                                            0 0 0 0 0 
                                            0 0 0 1 0"
                                           result="changeToOrangeFill"/>
    
        	<feComponentTransfer result="changedAgain">
                <feFuncR type="linear" slope="1" />
                <feFuncG type="linear" slope="0.439" />
                <feFuncB type="linear" slope="0" />
                <feFuncA type="linear" slope="1" />
    </feComponentTransfer>
    
        	<feOffset dx="120"/>
    	    </filter>               
      </defs>
    <use xlink:href="#star" filter="url(#offsetColoredShape)" />
    <use xlink:href="#star" fill="rgb(255,112,0)" fill-opacity="0.5" stroke="#0000FF"  stroke-width="4" />
          </svg>

    使现代化

    评论如下:

    我想知道为什么,尽管在feColorMatrix中丢弃了所有颜色值并将alpha设置为100%,但alpha值仍保留了下来。

    这是因为使用的元素(即 #明星 )有 填充不透明度=“0.5” .您需要使用不带 fill-opacity 属性

    在这个简单的例子中,你可以看到我不能修改 fill 关于 <use> 因为使用的元素有一个填充。不过,我可以添加一个笔划,因为 <使用> 元素没有笔划:

    <svg viewBox="0 0 100 50">
        <circle  id="c" fill="deepPink"  stroke-width="5" cx="20" cy="25" r="10"></circle>
      <use xlink:href="#c" x="50" fill="gold" stroke="skyBlue" />
    </svg>

    OP还评论说,之前的解决方案

    在生成形状并在事实发生后简单插入过滤器时不起作用。

    在下一个演示中,我将生成 #明星 .接下来我将生成过滤后的 <使用> 元素,它可以工作

    const SVG_NS = 'http://www.w3.org/2000/svg';
    const SVG_XLINK = "http://www.w3.org/1999/xlink";
    const svg = document.querySelector("svg")
    let d = "M0,63.904 L17.609,51.5L8.562,31.952L30.014,30.014L31.952,8.562L51.5,17.609L63.904,0L76.309,17.609L95.857,8.562L97.795,30.014L119.247,31.952L110.199,51.5L127.809,63.904L110.199,76.309L119.247,95.857L97.795,97.795L95.857,119.247L76.309,110.199L63.904,127.809L51.5,110.199L31.952,119.247L30.014,97.795L8.562,95.857L17.609,76.309Z"
    
    let star = drawSVGelmt({d:d,id:"star"},"path", theDefs);
    
    
    
    let use1 = document.createElementNS(SVG_NS, 'use');
    use1.setAttributeNS(SVG_XLINK, 'xlink:href', '#star');
    use1.setAttribute('class', 'filtered');
    
    svg.appendChild(use1)
    
    
    function drawSVGelmt(o,tag, parent) {
      
      let elmt = document.createElementNS(SVG_NS, tag);
      for (let name in o) {
        if (o.hasOwnProperty(name)) {
          elmt.setAttributeNS(null, name, o[name]);
        }
      }
      parent.appendChild(elmt);
      return elmt;
    }
    .filtered{filter:url(#offsetColoredShape)}
    <svg xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="-10 -10 360 150" class="slide" shape-rendering="geometricPrecision" fill-rule="evenodd">
         
    
            <defs id="theDefs">
    
            <filter id="offsetColoredShape" height="500%" width="500%" x="-275%" y="-275%">
             <feColorMatrix in="SourceAlpha" type="matrix" values="
                                            0 0 0 0 1 
                                            0 0 0 0 0.439
                                            0 0 0 0 0 
                                            0 0 0 1 0"
                                           result="changeToOrangeFill"/>
    
        	<feComponentTransfer result="changedAgain">
                <feFuncR type="linear" slope="1" />
                <feFuncG type="linear" slope="0.439" />
                <feFuncB type="linear" slope="0" />
                <feFuncA type="linear" slope="1" />
    </feComponentTransfer>
    
        	<feOffset dx="120"/>
    	    </filter>               
      </defs>
    
    <use xlink:href="#star" fill="rgb(255,112,0)" fill-opacity="0.5" stroke="#0000FF"  stroke-width="4" />
          </svg>