Как анимировать путь SVG в IOS?

у меня есть путь SVG, как это:

<svg width="100" height="100" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" version="1.1"  baseProfile="full"> 
    <path d="M47.16,66.38c0.62,1.65-0.03,2.93-0.92,4.28c-5.17,7.8-8.02,11.38-14.99,18.84c-2.11,2.25-1.5,4.18,2,3.75c7.35-0.91,28.19-5.83,40.16-7.95" style="fill:none;stroke:black;stroke-width:2" />
</svg>

Я могу отобразить путь, но не могу найти способ сделать путь анимированным, чтобы он выглядел так, как будто он" рисуется", как будто карандашом. The animate узел работает для одиночных координат, но не для путей.

в конечном итоге я буду использовать эту анимацию в приложении iPhone либо с помощью парсера, либо с UIWebView.

3 ответов


попробовать анимировать 'stroke-dashoffset' (обратите внимание, что вам понадобится согласование 'stroke-dasharray' С ним), см. . Длина пути, который должен быть вычислен, чтобы иметь возможность использовать это успешно можно получить с помощью скрипта, как:

var pathlength = yourPathElm.getTotalLength()

просмотр источника на пример чтобы посмотреть, как это делается.


Я долгое время пытался сделать это без необходимости добавлять дополнительные скрипты в заголовок (что я понятия не имею о javascript не помогло), так что вот решение:

<path d="..." stroke-dasharray="">
  <animate attributeName="stroke-dashoffset" from="" to="0" dur="1s" begin="0s"
           onload="var length = parentNode.getTotalLength();
                   parentNode.setAttribute('stroke-dasharray',length+','+length);
                   this.setAttribute('from',length)" />
</path>

я добавил лишние разрывы строк для удобства чтения здесь.

Это законно в SVG (хотя и не в HTML), потому что на svg:animate элемент onload, чего не делает большинство HTML-элементов.


после того, как вы отобразили свой путь SVG, чтобы он выглядел так, как будто его рисуют карандашом, вы можете просто покрыть его непрозрачным слоем, а затем оживить движение этого слоя вдоль пути.

найти CGPath вдоль которого вы будете перемещать слой, вы можете использовать эту библиотеку: https://github.com/arielelkin/PocketSVG

это будет анализировать данные SVG в UIBezierPath. Затем:

SvgToBezier *myBezier = [[SvgToBezier alloc] initFromSVGPathNodeDAttr:@"M176.17,369.617c0,0,335.106-189.361,214.894,38.298s129.787,282.978,178.723,42.553C618.724,210.042,834.681,87.702,790,307.915" rect:CGRectMake(0,0,1024,768)];

UIBezierPath *myPath = myBezier.bezier;

CAKeyframeAnimation *mySVGPathAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
bounceAnimLeft.duration = 3;
bounceAnimLeft.path = myPath.CGPath;

[myObjectToMove.layer addAnimation:mySVGPathAnimation forKey:@"pathAnimation"];