admin管理员组

文章数量:1401617

Is it possible to blur or fade out an SVG path? I have a bunch of lines that I would ideally like to fade out at the beginning or end (i.e. just on one side), or at the very least blur them so it looks like one half is more in focus than the other.

If it's not possible, how could I go about changing the SVG to make it possible?

var bodyElement = document.querySelector("body");
bodyElement.addEventListener("mousemove", getMouseDirection, false);

var xDirection = "";
var yDirection = "";

var oldX = 0;
var oldY = 0;

function getMouseDirection(e) {
  if (oldX < e.pageX) {
    xDirection = "right";
  } else {
    xDirection = "left";
  }
  if (oldY < e.pageY) {
    yDirection = "down";
  } else {
    yDirection = "up";
  }
  oldX = e.pageX;
  oldY = e.pageY;
}

var tl;

$('g')
.on('mouseover', function() {
  tl = new TimelineLite();
  if (yDirection === "down") {
    tl.to($(this), 1, {
      y: 10
    });
  }
  if (yDirection === "up") {
    tl.to($(this), 1, {
      y: -10
    });
  }
})
.on('mouseout', function() {
  tl = new TimelineLite();
  tl.to($(this), 1, {
    y: 0,
    x: 0
  });
});
body {
  background: #000;
}

.f0 {
  filter: url(#f0);
  animation-delay: .5s;
}

.f1 {
  filter: url(#f1);
  animation-delay: 1s;
}

.f2 {
  filter: url(#f2);
  animation-delay: 2s;
}

.f3 {
  filter: url(#f3);
  animation-delay: 3s;
}

.line {
  opacity: 0;
  animation-name: fadeIn;
  animation-duration: 2s;
  animation-fill-mode: forwards;
}

@keyframes fadeIn {
  to {
    opacity: 1;
  }
}
<script src=".1.1/jquery.min.js"></script>
<script src=".18.2/TweenMax.min.js"></script>

<svg height="480" version="1.1" width="640" xmlns="">
  <defs>
    <filter id="f0">
      <feGaussianBlur in="SourceGraphic" stdDeviation="1" />
    </filter>
    <filter id="f1">
      <feGaussianBlur in="SourceGraphic" stdDeviation="2" />
    </filter>
    <filter id="f2">
      <feGaussianBlur in="SourceGraphic" stdDeviation="7" />
    </filter>
    <filter id="f3">
      <feGaussianBlur in="SourceGraphic" stdDeviation="15" />
    </filter>
  </defs>
  <g>
    <path class="hitbox" fill="none" stroke="transparent" d="M11,163S538,357,192,108" stroke-width="5"></path>
    <path class="line" fill="none" stroke="#ffffff" d="M11,163S538,357,192,108" stroke-width="1"></path>
  </g>
  <g>
    <path class="hitbox" fill="none" stroke="transparent" d="M11,163S626,299,507,115" stroke-width="5"></path>
    <path class="line f1" fill="none" stroke="#ffffff" d="M11,163S626,299,507,115" stroke-width="1"></path>
  </g>
  <g>
    <path class="hitbox" fill="none" stroke="transparent" d="M11,163S620,182,612,189" stroke-width="5"></path>
    <path class="line f2" fill="none" stroke="#ffffff" d="M11,163S620,182,612,189" stroke-width="1"></path>
  </g>
  <g>
    <path class="hitbox" fill="none" stroke="transparent" d="M11,163S55,480,558,56" stroke-width="5"></path>
    <path class="line f2" fill="none" stroke="#ffffff" d="M11,163S55,480,558,56" stroke-width="1"></path>
  </g>
  <g>
    <path class="hitbox" fill="none" stroke="transparent" d="M11,163S654,86,533,328" stroke-width="5"></path>
    <path class="line f1" fill="none" stroke="#ffffff" d="M11,163S654,86,533,328" stroke-width="1"></path>
  </g>
  <g>
    <path class="hitbox" fill="none" stroke="transparent" d="M11,163S397,248,466,162" stroke-width="5"></path>
    <path class="line f3" fill="none" stroke="#ffffff" d="M11,163S397,248,466,162" stroke-width="1"></path>
  </g>
  <g>
    <path class="hitbox" fill="none" stroke="transparent" d="M11,163S651,181,569,111" stroke-width="5"></path>
    <path class="line f3" fill="none" stroke="#ffffff" d="M11,163S651,181,569,111" stroke-width="1"></path>
  </g>
  <g>
    <path class="hitbox" fill="none" stroke="transparent" d="M11,163S599,394,220,338" stroke-width="5"></path>
    <path class="line f0" fill="none" stroke="#ffffff" d="M11,163S599,394,220,338" stroke-width="1"></path>
  </g>
</svg>

Is it possible to blur or fade out an SVG path? I have a bunch of lines that I would ideally like to fade out at the beginning or end (i.e. just on one side), or at the very least blur them so it looks like one half is more in focus than the other.

If it's not possible, how could I go about changing the SVG to make it possible?

var bodyElement = document.querySelector("body");
bodyElement.addEventListener("mousemove", getMouseDirection, false);

var xDirection = "";
var yDirection = "";

var oldX = 0;
var oldY = 0;

function getMouseDirection(e) {
  if (oldX < e.pageX) {
    xDirection = "right";
  } else {
    xDirection = "left";
  }
  if (oldY < e.pageY) {
    yDirection = "down";
  } else {
    yDirection = "up";
  }
  oldX = e.pageX;
  oldY = e.pageY;
}

var tl;

$('g')
.on('mouseover', function() {
  tl = new TimelineLite();
  if (yDirection === "down") {
    tl.to($(this), 1, {
      y: 10
    });
  }
  if (yDirection === "up") {
    tl.to($(this), 1, {
      y: -10
    });
  }
})
.on('mouseout', function() {
  tl = new TimelineLite();
  tl.to($(this), 1, {
    y: 0,
    x: 0
  });
});
body {
  background: #000;
}

.f0 {
  filter: url(#f0);
  animation-delay: .5s;
}

.f1 {
  filter: url(#f1);
  animation-delay: 1s;
}

.f2 {
  filter: url(#f2);
  animation-delay: 2s;
}

.f3 {
  filter: url(#f3);
  animation-delay: 3s;
}

.line {
  opacity: 0;
  animation-name: fadeIn;
  animation-duration: 2s;
  animation-fill-mode: forwards;
}

@keyframes fadeIn {
  to {
    opacity: 1;
  }
}
<script src="https://ajax.googleapis./ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/gsap/1.18.2/TweenMax.min.js"></script>

<svg height="480" version="1.1" width="640" xmlns="http://www.w3/2000/svg">
  <defs>
    <filter id="f0">
      <feGaussianBlur in="SourceGraphic" stdDeviation="1" />
    </filter>
    <filter id="f1">
      <feGaussianBlur in="SourceGraphic" stdDeviation="2" />
    </filter>
    <filter id="f2">
      <feGaussianBlur in="SourceGraphic" stdDeviation="7" />
    </filter>
    <filter id="f3">
      <feGaussianBlur in="SourceGraphic" stdDeviation="15" />
    </filter>
  </defs>
  <g>
    <path class="hitbox" fill="none" stroke="transparent" d="M11,163S538,357,192,108" stroke-width="5"></path>
    <path class="line" fill="none" stroke="#ffffff" d="M11,163S538,357,192,108" stroke-width="1"></path>
  </g>
  <g>
    <path class="hitbox" fill="none" stroke="transparent" d="M11,163S626,299,507,115" stroke-width="5"></path>
    <path class="line f1" fill="none" stroke="#ffffff" d="M11,163S626,299,507,115" stroke-width="1"></path>
  </g>
  <g>
    <path class="hitbox" fill="none" stroke="transparent" d="M11,163S620,182,612,189" stroke-width="5"></path>
    <path class="line f2" fill="none" stroke="#ffffff" d="M11,163S620,182,612,189" stroke-width="1"></path>
  </g>
  <g>
    <path class="hitbox" fill="none" stroke="transparent" d="M11,163S55,480,558,56" stroke-width="5"></path>
    <path class="line f2" fill="none" stroke="#ffffff" d="M11,163S55,480,558,56" stroke-width="1"></path>
  </g>
  <g>
    <path class="hitbox" fill="none" stroke="transparent" d="M11,163S654,86,533,328" stroke-width="5"></path>
    <path class="line f1" fill="none" stroke="#ffffff" d="M11,163S654,86,533,328" stroke-width="1"></path>
  </g>
  <g>
    <path class="hitbox" fill="none" stroke="transparent" d="M11,163S397,248,466,162" stroke-width="5"></path>
    <path class="line f3" fill="none" stroke="#ffffff" d="M11,163S397,248,466,162" stroke-width="1"></path>
  </g>
  <g>
    <path class="hitbox" fill="none" stroke="transparent" d="M11,163S651,181,569,111" stroke-width="5"></path>
    <path class="line f3" fill="none" stroke="#ffffff" d="M11,163S651,181,569,111" stroke-width="1"></path>
  </g>
  <g>
    <path class="hitbox" fill="none" stroke="transparent" d="M11,163S599,394,220,338" stroke-width="5"></path>
    <path class="line f0" fill="none" stroke="#ffffff" d="M11,163S599,394,220,338" stroke-width="1"></path>
  </g>
</svg>

http://codepen.io/anon/pen/rxKvMj

Share Improve this question edited Feb 1, 2016 at 8:42 Mosh Feu 29.4k18 gold badges93 silver badges141 bronze badges asked Jan 31, 2016 at 21:07 daveycroqetdaveycroqet 2,7277 gold badges38 silver badges61 bronze badges 4
  • Do you want a progressive blur along the actual path of the path or do you just want e.g. just the right half of the path's bounding box to be blurred? The first is extremely difficult without chopping your path into sub-paths with different size blurs applied. The second is very easy. (If you want the first, you might be better off using Canvas.) – Michael Mullany Commented Feb 1, 2016 at 0:04
  • @MichaelMullany The first would be ideal. I have no idea how to go about programmatically chopping it into pieces though, and I feel like that would also be a significant performance hit. – daveycroqet Commented Feb 1, 2016 at 4:03
  • @MichaelMullany What about a gradient fade to transparent along the paths? Is that possible? – daveycroqet Commented Feb 1, 2016 at 4:12
  • If you just want a fade out, then there is a kind of hacky method using stroke-dash-array and a filter. I've added it as an answer below. – Michael Mullany Commented Feb 2, 2016 at 1:22
Add a ment  | 

3 Answers 3

Reset to default 3

This is a way to hack a progressive blur along a path by abusing stroke-dash-array and opacity manipulation within an SVG filter. Basically, you carefully construct a stroke dash array of increasing spaces, then use a large blur to "fill in the gaps". Then you boost the opacity using a ponent transfer and then use the original graphic to mask out the overflow. Note you must first draw your path in white (or your background color) and then the stroke dashed path over it so you have the proper selection for positing. For a general solution, you'd need to construct the stroke-dash array and the filter using JavaScript because it and the stdDeviation you want to use are going to be dependent on the path length.

<svg width="800px" height="600px" color-interpolation-filters="sRGB" viewBox="0 0 1600 1200">
  <defs>
    <filter id="fade-out">
      
      <feGaussianBlur in="SourceGraphic" stdDeviation="16" result="blur-source"/>
    
      <feComponentTransfer result="fader">
        <feFuncA type="gamma" exponent=".5" amplitude="2"/>
      </feComponentTransfer>
          
      <feComposite operator="in" in="fader" in2="SourceGraphic"/>    
  
    </filter>
  </defs>

<g filter="url(#fade-out)">
   <path d="M200,300 Q400,50 600,300 T1000,300" stroke-width="5" fill="none" stroke="white"/> 
  
  <path d="M200,300 Q400,50 600,300 T1000,300"
        fill="none" stroke="red" stroke-width="5" stroke-dasharray="10,1,8,3,8,5,7,7,7,9,6,11,6,13,5,15,5,17,5,19,5,21,5,23,5,25,5,27,5,29,5"/> 
  </g>
</svg>

Sure you can.. Using css3 keyframes like in this tutorial:

https://css-tricks./animating-svg-css/

var gs = $('g');

function fade(index) {
  gs.eq(index).css('opacity', Math.random());
  setTimeout(function(){
    fade(++index);
  }, 500);
}

fade(0);
body {
  background:#000;
}

g {
  opacity:0;
  transition:all .5s ease;
}

g:hover {
  opacity:1 !important;
}
<script src="https://ajax.googleapis./ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<svg height="480" version="1.1" width="640" xmlns="http://www.w3/2000/svg">
  <defs>
    <filter id="f1" x="10" y="10">
      <feGaussianBlur in="SourceGraphic" stdDeviation="15" />
    </filter>
  </defs>
  <g>
    <path class="hitbox" fill="none" stroke="transparent" d="M11,163S538,357,192,108" stroke-width="5"></path>
    <path class="line" fill="none" stroke="#ffffff" d="M11,163S538,357,192,108" stroke-width="1"></path>
  </g>
  <g>
    <path class="hitbox" fill="none" stroke="transparent" d="M11,163S626,299,507,115" stroke-width="5"></path>
    <path class="line" fill="none" stroke="#ffffff" d="M11,163S626,299,507,115" stroke-width="1"></path>
  </g>
  <g>
    <path class="hitbox" fill="none" stroke="transparent" d="M11,163S620,182,612,189" stroke-width="5"></path>
    <path class="line" fill="none" stroke="#ffffff" d="M11,163S620,182,612,189" stroke-width="1"></path>
  </g>
  <g>
    <path class="hitbox" fill="none" stroke="transparent" d="M11,163S55,480,558,56" stroke-width="5"></path>
    <path class="line" fill="none" stroke="#ffffff" d="M11,163S55,480,558,56" stroke-width="1"></path>
  </g>
  <g>
    <path class="hitbox" fill="none" stroke="transparent" d="M11,163S654,86,533,328" stroke-width="5"></path>
    <path class="line" fill="none" stroke="#ffffff" d="M11,163S654,86,533,328" stroke-width="1"></path>
  </g>
  <g>
    <path class="hitbox" fill="none" stroke="transparent" d="M11,163S397,248,466,162" stroke-width="5"></path>
    <path class="line" fill="none" stroke="#ffffff" d="M11,163S397,248,466,162" stroke-width="1"></path>
  </g>
  <g>
    <path class="hitbox" fill="none" stroke="transparent" d="M11,163S651,181,569,111" stroke-width="5"></path>
    <path class="line" fill="none" stroke="#ffffff" d="M11,163S651,181,569,111" stroke-width="1"></path>
  </g>
  <g>
    <path class="hitbox" fill="none" stroke="transparent" d="M11,163S599,394,220,338" stroke-width="5"></path>
    <path class="line" fill="none" stroke="#ffffff" d="M11,163S599,394,220,338" stroke-width="1"></path>
  </g>
</svg>

Update Now the snippet is present ,delay, fade at the start and fade on :hover with your SVG. Hopefully that's you are looking for.

You can do lot of things using feGaussianBlur filter (as you did in the pen) and css animation. In this pen there is an example, creating something like depth of field using different filters.

本文标签: javascriptIs blurring or fading out an SVG path possibleStack Overflow