Como posso animar um desenho progressivo do caminho svg?

Eu quero animar um desenho progressivo de uma linha usando apenas css com svg / canvas e js maximum. Uma ideia da linha que quero desenhar pode ser encontrada aqui

   Layer 1    

Existem três técnicas listadas nesta resposta:


Existe uma solução totalmente SVG que envolve a modificação progressiva da stroke-dasharray para que a forma desenhe um ‘traço’ mais longo e mais longo, seguido por uma enorme lacuna.

Demonstração: http://phrogz.net/svg/progressively-drawing-svg-path-via-dasharray.html

Código relevante:

 var distancePerPoint = 1; var drawFPS = 60; var orig = document.querySelector('path'), length, timer; orig.addEventListener('mouseover',startDrawingPath,false); orig.addEventListener('mouseout', stopDrawingPath, false); function startDrawingPath(){ length = 0; orig.style.stroke = '#f60'; timer = setInterval(increaseLength,1000/drawFPS); } function increaseLength(){ var pathLength = orig.getTotalLength(); length += distancePerPoint; orig.style.strokeDasharray = [length,pathLength].join(' '); if (length >= pathLength) clearInterval(timer); } function stopDrawingPath(){ clearInterval(timer); orig.style.stroke = ''; orig.style.strokeDasharray = ''; } 

Como alternativa, você ainda pode usar todo o SVG e optar por criar o comando SVG path one de cada vez:

Demonstração: http://phrogz.net/svg/progressively-cloning-svg-path.html

Código relevante:

 // Assumes 'orig' and dup' are SVG paths function addNextPathSegment(){ var nextIndex = dup.pathSegList.numberOfItems; if (nextIndex 

Finalmente, você pode escolher desenhar seu caminho para uma canvas HTML5, testando o caminho SVG periodicamente e desenhando na canvas. (Observe que o caminho SVG não precisa ser exibido para que isso aconteça; você pode construir um elemento de caminho SVG inteiramente em JavaScript e testá-lo):

Demonstração: http://phrogz.net/svg/progressively-drawing-svg-path.html

Código relevante:

 function startDrawingPath(){ points = []; timer = setInterval(buildPath,1000/drawFPS); } // Assumes that 'orig' is an SVG path function buildPath(){ var nextPoint = points.length * distancePerPoint; var pathLength = orig.getTotalLength(); if (nextPoint <= pathLength){ points.push(orig.getPointAtLength(nextPoint)); redrawCanvas(); } else stopDrawingPath(); } function redrawCanvas(){ clearCanvas(); ctx.beginPath(); ctx.moveTo(points[0].x,points[0].y); for (var i=1;i 

Então, há essa pergunta semelhante com essa resposta .


Peguei o seu caminho e coloquei no código nessa resposta.

demo jsfiddle

Html:

   

Hover over me

Javascript (Observe que o JQuery 1.8.3 e o Raphael 1.5.2 foram usados ​​no exemplo) :

 $(function() { animateLine = function(canvas, hoverDivName, colorNumber, pathString) { $('#' + hoverDivName).hover( function() { var line = canvas.path(pathString).attr({ stroke: colorNumber }); var length = line.getTotalLength(); $('path[fill*="none"]').animate({ 'to': 1 }, { duration: 5000, step: function(pos, fx) { var offset = length * fx.pos; var subpath = line.getSubpath(0, offset); canvas.clear(); canvas.path(subpath).attr({ 'stroke-width': 5, stroke: colorNumber }); }, }); }, function() { $('path[fill*="none"]').stop(true, false).fadeOut(); }); }; var canvas = Raphael('canvas', 200, 200); var pathString = "m33,104c1,0 2.1306,-0.8037 23,3c9.07012,1.65314 10,2 24,2c7,0 29,0 33,0c8,0 9,0 11,0c2,0 8,0 11,0c9,0 17,0 18,0c10,0 12,0 20,0c1,0 6,0 7,0c2,0 3.07613,0.38268 4,0c2.61313,-1.08239 2,-3 2,-6c0,-1 0,-2 0,-3c0,-1 0,-2 0,-3c0,-1 0,-2 0,-3c0,-1 0.30745,-3.186 -1,-5c-0.8269,-1.14727 -0.09789,-2.82443 -2,-4c-0.85065,-0.52573 -2.82443,-0.09789 -4,-2c-0.52573,-0.85065 -2.58578,-0.58578 -4,-2c-0.70711,-0.70711 -1.81265,-1.20681 -4,-3c-2.78833,-2.28588 -3.64749,-2.97251 -8,-4c-2.91975,-0.68926 -4.82375,-2.48626 -7,-3c-2.91975,-0.68926 -5.15224,-0.23463 -7,-1c-1.30656,-0.5412 -4.38687,-1.91761 -7,-3c-1.84776,-0.76537 -5.03609,0.37821 -7,0c-5.28799,-1.01837 -8,-3 -9,-3c-2,0 -5.0535,-0.54049 -7,-1c-2.17625,-0.51374 -4.15224,-0.23463 -6,-1c-1.30656,-0.54119 -3,-1 -4,-1c-2,0 -5,-1 -6,-1c-1,0 -3,-2 -6,-2c-2,0 -5,-2 -6,-2c-2,0 -2.02583,-0.67963 -4,-1c-3.12144,-0.50654 -4.15224,-0.23463 -6,-1c-1.30656,-0.54119 -2,-1 -3,-1c-2,0 -3,0 -5,0c-1,0 -2,0 -3,0c-1,0 -2,0 -3,0c-1,0 -2,0 -3,0c-2,0 -3.85273,0.1731 -5,1c-1.81399,1.30745 -5.18601,1.69255 -7,3c-1.14727,0.8269 -1.82375,2.48626 -4,3c-0.97325,0.22975 -1.69344,1.45881 -3,2c-0.92388,0.38268 -1.45951,1.0535 -1,3c0.51374,2.17625 3.07844,2.78985 6,4c2.06586,0.85571 3.38688,1.91761 6,3c1.84776,0.76537 5.2987,-1.05146 7,0c1.90211,1.17557 3.82375,2.48626 6,3c0.97325,0.22975 3.29289,0.29289 4,1c0.70711,0.70711 4,2 9,4c5,2 8,4 11,4c2,0 5,0 7,0c3,0 5,0 7,0c2,0 4,0 7,0c2,0 4,0 8,0c3,0 7,0 10,0c4,0 7,0 12,0c3,0 5,0 6,0c2,0 3,0 5,0c1,0 1.09789,-0.82443 3,-2c0.85065,-0.52573 3.07613,0.38268 4,0c1.30656,-0.5412 0.71022,-2.04291 1,-3c1.04483,-3.45084 2.84723,-5.04132 4,-9c0.88414,-3.03616 1.85194,-5.22836 3,-8c0.5412,-1.30656 1.5405,-2.0535 2,-4c0.51375,-2.17625 2.71413,-4.21167 5,-7c2.68979,-3.28101 4,-6 5,-7c1,-1 2,-2 2,-4c0,-1 0.70711,-2.29289 0,-3c-0.70711,-0.70711 -2.07613,0.38268 -3,0c-1.30656,-0.54119 -2,-1 -4,-1c-3,0 -6.87856,-2.49346 -10,-3c-2.96126,-0.48055 -6.71201,-0.98162 -12,-2c-2.94586,-0.56732 -5,-1 -9,-1c-3,0 -6,-1 -8,-1c-2,0 -5,-3 -7,-3c-2,0 -5.38687,-0.91761 -8,-2c-0.92388,-0.38268 -3.0535,-0.54049 -5,-1c-2.17625,-0.51374 -4.58578,0.41421 -6,-1c-0.70711,-0.70711 -1,-1 -2,-1c-1,0 -2,0 -3,0c-1,0 -2,0 -4,0c-1,0 -2,0 -3,0c-1,0 -2,0 -4,0c-1,0 -2,0 -3,0c-2,0 -3,0 -5,0c-1,0 -2,0 -3,0c-1,0 -3,0 -4,0c-3,0 -5,0 -7,0c-2,0 -4,0 -6,0c-2,0 -3,0 -5,0c-1,0 -2,0 -3,0c-2,0 -4,0 -5,0c-1,0 -2,0 -4,0c-1,0 -2,0 -3,1l-1,0"; animateLine(canvas, "canvas", "#000", pathString); }); 
  • Eu peguei o caminho do atributo [ d ] e coloquei dentro da variável pathString .
  • Eu também adicionei uma linha para definir o [ stroke-width ]

Eu apenas brinquei com o raphael muito brevemente uma vez, mas verificar os exemplos e observar como o código é construído (a from page source ) leva você muito longe (eu não conseguia lembrar como / onde colocar a stroke-width do stroke-width , então Eu verifiquei o método da fonte da página deste exemplo .


Você pode encontrar raphael + mais informações a partir daqui.


Só por diversão, eu fiz o meu próprio caminho …

Usando a excelente técnica Phrogz, criei uma animação muito básica do GreenSock usando TweenLite para interpolar o valor length para o valor getTotalLength ().

Como você pode ver na demonstração, conectá-lo a um mecanismo de interpolação oferece muito controle e envolve muito pouco código.

 var orig = document.querySelector('path'), length, timer; var obj = {length:0, pathLength:orig.getTotalLength()}; orig.style.stroke = '#f60'; var t = TweenMax.to(obj, 10, {length:obj.pathLength, onUpdate:drawLine, ease:Linear.easeNone}) function drawLine() { orig.style.strokeDasharray = [obj.length,obj.pathLength].join(' '); updateSlider(); } 

Muito respeito a Phrogz pela ideia e código impressionantes.

http://codepen.io/GreenSock/pen/zLiux

Eu fiz algo semelhante no ano passado para animar um desenho em canvas. Os caminhos são todos os caminhos do tipo SVG com curvas e linhas, para que você possa retirá-los diretamente do arquivo SVG e colocá-los no array Javascript.

http://www.ashleysheridan.co.uk/coding/javascript/Animated+Glowing+Line+Drawing+in+Canvas