Как создать анимацию из последовательности SVG с одинаковыми идентификаторами элементов - PullRequest
1 голос
/ 12 апреля 2019

Я пытаюсь создать несколько 2D-анимаций из последовательности файлов SVG.

Все файлы SVG имеют одинаковое количество элементов, и все соответствующие элементы имеют одинаковый идентификатор элемента.Я хотел бы создать анимацию, в которой каждый svg рассматривается как ключевой кадр, а анимация создается путем интерполяции элементов с одинаковым идентификатором между ключевыми кадрами.

Я рассмотрел использование snap.svg,но я не уверен, как связать объекты между различными SVG-файлами.

1 Ответ

1 голос
/ 12 апреля 2019

Вот как бы я это сделал:

  1. Я готовлю корневой элемент SVG, и внутри, один поверх другого, несколько элементов SVG, каждый со своим id.

  2. В css я добавляю: если элемент svg не нацелен display: none;

svg > svg:not(:target) {
        display: none;
} 
  1. Предположим, что ваш svg-файл: https://domain/.../rects.svg, если вы хотите нацелиться на один из элементов svg, вы используете svg's id следующим образом: https://domain/.../rects.svg#svg_id

Вот как будет выглядеть корневой svg:

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100px" height="100px" viewBox="-50 -50 100 100">
  <defs>
   <rect id="theRect" x="-30" y="-30" width="60" height="60" fill="none" stroke="red"></rect> 
  </defs>
  <style type="text/css">
 <![CDATA[  
    svg > svg:not(:target) {
    display: none;
    }
     ]]> 
</style>


<svg viewBox="-50 -50 100 100" x="-50" y="-50" id="_0">
    <use xlink:href="#theRect" transform="rotate(0)"></use>
</svg>
<svg viewBox="-50 -50 100 100" x="-50" y="-50" id="_1">
    <use xlink:href="#theRect" transform="rotate(6)"></use>
</svg>
<svg viewBox="-50 -50 100 100" x="-50" y="-50" id="_2">
    <use xlink:href="#theRect" transform="rotate(12)"></use>
</svg>
<svg viewBox="-50 -50 100 100" x="-50" y="-50" id="_3">
    <use xlink:href="#theRect" transform="rotate(18)"></use>
</svg>
<svg viewBox="-50 -50 100 100" x="-50" y="-50" id="_4">
    <use xlink:href="#theRect" transform="rotate(24)"></use>
</svg>
<svg viewBox="-50 -50 100 100" x="-50" y="-50" id="_5">
    <use xlink:href="#theRect" transform="rotate(30)"></use>
</svg>
<svg viewBox="-50 -50 100 100" x="-50" y="-50" id="_6">
  <use xlink:href="#theRect" transform="rotate(36)"></use>
</svg>
<svg viewBox="-50 -50 100 100" x="-50" y="-50" id="_7">
    <use xlink:href="#theRect" transform="rotate(42)"></use>
</svg>
<svg viewBox="-50 -50 100 100" x="-50" y="-50" id="_8">
    <use xlink:href="#theRect" transform="rotate(48)"></use>
</svg>
<svg viewBox="-50 -50 100 100" x="-50" y="-50" id="_9">
    <use xlink:href="#theRect" transform="rotate(54)"></use>
</svg>
<svg viewBox="-50 -50 100 100" x="-50" y="-50" id="_10">
    <use xlink:href="#theRect" transform="rotate(60)"></use>
</svg>
<svg viewBox="-50 -50 100 100" x="-50" y="-50" id="_11">
  <use xlink:href="#theRect" transform="rotate(66)"></use>
</svg>
<svg viewBox="-50 -50 100 100" x="-50" y="-50" id="_12">
    <use xlink:href="#theRect" transform="rotate(72)"></use>
</svg>
<svg viewBox="-50 -50 100 100" x="-50" y="-50" id="_13">
    <use xlink:href="#theRect" transform="rotate(78)"></use>
</svg>
<svg viewBox="-50 -50 100 100" x="-50" y="-50" id="_14">
  <use xlink:href="#theRect" transform="rotate(84)"></use>
</svg>
</svg>

А вот как я бы это оживил:

let i = 0; 
function Frame(){
  let n = i % 15;
  requestAnimationFrame(Frame);
  theImg.setAttribute("src", `https://s3-us-west-2.amazonaws.com/s.cdpn.io/222579/rects.svg#_${n}`);
  i++
 }

Frame()
img{border:10px solid #d9d9d9}
<img id="theImg" width="100" height="100" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/222579/rects.svg#_0" />

Грубо говоря, поскольку все эти элементы svg находятся в одном файле, вы не сможете использовать один и тот же id несколько раз. Вам понадобятся уникальные id с.

...