如何为我的SVG路径设置动画

时间:2018-03-16 23:58:02

标签: javascript html svg svg-animate anime.js

我有一个SVG我试图用animejs制作动画。

基本上是一个选择路径图。

我设法制作动画,但结果是错误的。

我想要这个:

enter image description here

#include <iostream>
#include <omp.h>
#define  NUM_THREADS 1
#define PAD 8
using namespace std;
static long num_steps = 100000000;
double step;

int main(){
  omp_set_num_threads(NUM_THREADS);
  double pi;
  static double sum[NUM_THREADS][PAD];
  step = 1.0/(double) num_steps;
  double x;
  double start_time = omp_get_wtime();
  int nthreads;
  #pragma omp parallel
  {
    double partial_sum = 0.0;
    int ID = omp_get_thread_num();
    int nthrds = omp_get_num_threads();
    if (ID == 0) nthreads = nthrds;
    sum[ID][0] = 0.0;
    for (int i = ID; i < num_steps; i = i+ nthrds){
      x = (i + 0.5)*step;
      sum[ID][0] += 4.0/(1.0 + x*x);
    }
  }
  double time = omp_get_wtime() - start_time;
  for (int i = 0; i < nthreads; i++){
      pi += sum[i][0]*step;
  }
  cout << pi << endl;
  cout << time*1000 << endl;
}
var lineDrawing = anime({
  targets: 'path',
  strokeDashoffset: [anime.setDashoffset, 0],
  easing: 'easeInOutCubic',
  duration: 4000,
  begin: function(anim) {
    document.querySelector('path').setAttribute("stroke", "#4a56f2");
    document.querySelector('path').setAttribute("fill", "none");
  },
  complete: function(anim) {
  },
  autoplay: false
});

document.querySelector('.play-drawing').onclick = lineDrawing.restart;
body {
  margin: 20px;
  font-family: 'Lato';
  font-weight: 300;
  font-size: 1.2em;
}

#anime-demo {
  position: relative;
}

svg {
   padding: 10px;
}

button {
  background: orange;
  color: white;
  margin: 5px;
  padding: 10px;
  border-radius: 4px;
  font-family: 'Lato';
  cursor: pointer;
  border: none;
  outline: none;
}

button:hover {
  background: blue;
}

2 个答案:

答案 0 :(得分:5)

不幸的是,你设置它的方式 - 使用包含所有块的单个路径元素将不起作用。动画库使用笔触虚线宽度来模拟绘图块。将它们全部定义在单个路径元素中只能导致所有块同时被动画化。

将它们分成每个块的单独路径元素后,另一个问题是绘制它们的顺序 - 默认情况下,它将按照它们在HTML中的顺序从顶部到底部遍历路径元素。但是,路径元素从上到下依次以左右顺序添加,这意味着动画将从顶部中间块开始,然后在左侧,右侧,左侧等处交替。相反,要使它们生动顺时针环绕顺序我编写了一个函数来初始循环遍历所有元素,计算相对于SVG中心点的度数(0-360)(还记得你的高中三角函数?),然后根据这个元素对元素进行排序学位价值。

由于SO需要代码(但是在答案中添加所有代码太长了),这里是JavaScript,底部的JSFiddle中的完整代码:

exports.handler

JSFiddle中提供了完整的结果:https://jsfiddle.net/jimbo2150/d8gc96em/

答案 1 :(得分:3)

更新答案:对于OP正在尝试实现的目标。还是在纯粹的CSS中。

说明:

  1. 查看以前的答案&#39;关于如何让它像gif一样工作。
  2. 现在如何使每条虚线像方形一样。在蓝线中,每个破折号的length10。我们可以制作stroke-width = 10,使它们看起来像方形。现在每个方格应该只有outline而不是fill。我们将创建另一个mask来阻挡每个方块的内部部分。
  3. &#13;
    &#13;
    path {
      fill: none
    }
    
    .path {
      stroke-dasharray: 10;
      stroke: blue;
      stroke-width: 10;
    }
    
    
    /* Let the outline width of each square be 1 */
    
    .maskSquare {
      stroke: black;
      /* To block or remove inner blue portion */
      stroke-width: 8;
      /* blue-dash-length minus 2*sqaure-length = 10 - 2 */
      stroke-dasharray: 8 12;
      /* 8+12 == 20 as in blue-dash-line 10+10 == 20 */
      stroke-dashoffset: -1;
      /* To sync */
    }
    
    .maskLineLength {
      stroke: white;
      stroke-width: 11;
      animation: array 3s linear infinite;
    }
    
    @keyframes array {
      from {
        stroke-dasharray: 0 2000;
      }
      to {
        stroke-dasharray: 1000 2000;
      }
    }
    &#13;
    <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="340px" height="333px" viewBox="0 0 340 333" enable-background="new 0 0 340 333" xml:space="preserve">
      <defs>
         <mask id="mask">
               <path  class='maskLineLength' d="M66.039,133.545c0,0-21-57,18-67s49-4,65,8
              s30,41,53,27s66,4,58,32s-5,44,18,57s22,46,0,45s-54-40-68-16s-40,88-83,48s11-61-11-80s-79-7-70-41
              C46.039,146.545,53.039,128.545,66.039,133.545z"/>
           <path  class='maskSquare' d="M66.039,133.545c0,0-21-57,18-67s49-4,65,8
              s30,41,53,27s66,4,58,32s-5,44,18,57s22,46,0,45s-54-40-68-16s-40,88-83,48s11-61-11-80s-79-7-70-41
              C46.039,146.545,53.039,128.545,66.039,133.545z"/>
            </mask>
      </defs>
      <path mask="url(#mask)" class="path" d="M66.039,133.545c0,0-21-57,18-67s49-4,65,8
        s30,41,53,27s66,4,58,32s-5,44,18,57s22,46,0,45s-54-40-68-16s-40,88-83,48s11-61-11-80s-79-7-70-41
        C46.039,146.545,53.039,128.545,66.039,133.545z"/>
    </svg>
    &#13;
    &#13;
    &#13;

    以前的答案:为您提供的gif

    可以在纯CSS中完成。

    首先,蓝色短划线路径。

    &#13;
    &#13;
    .path {
      stroke-dasharray: 10;
      stroke: blue;
    }
    &#13;
    <svg width="340px" height="333px">
      <path class="path" fill="none" stroke-width="3" stroke-miterlimit="10" d="M66.039,133.545c0,0-21-57,18-67s49-4,65,8
        s30,41,53,27s66,4,58,32s-5,44,18,57s22,46,0,45s-54-40-68-16s-40,88-83,48s11-61-11-80s-79-7-70-41
        C46.039,146.545,53.039,128.545,66.039,133.545z"/>
    </svg>
    &#13;
    &#13;
    &#13;

    接下来是一个遮蔽路径,使用相同的路径1px更大的笔划宽度。

    &#13;
    &#13;
    .maskPath {
      animation: array 3s linear infinite;
    }
    
    @keyframes array {
      from {
        stroke-dasharray: 0 2000;
      }
      to {
        stroke-dasharray: 1000 2000;
      }
    }
    &#13;
    <svg width="340px" height="333px">
      
               <path fill='none' class='maskPath' stroke="darkGray" stroke-width='4' d="M66.039,133.545c0,0-21-57,18-67s49-4,65,8
              s30,41,53,27s66,4,58,32s-5,44,18,57s22,46,0,45s-54-40-68-16s-40,88-83,48s11-61-11-80s-79-7-70-41
              C46.039,146.545,53.039,128.545,66.039,133.545z"/>
    
    </svg>
    &#13;
    &#13;
    &#13;

    当蒙版应用于蓝色虚线时,结果如下。

    &#13;
    &#13;
    .path {
      stroke-dasharray: 10;
      stroke: blue;
    }
    
    .maskPath {
      animation: array 3s linear infinite;
    }
    
    @keyframes array {
      from {
        stroke-dasharray: 0 2000;
      }
      to {
        stroke-dasharray: 1000 2000;
      }
    }
    &#13;
    <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="340px" height="333px" viewBox="0 0 340 333" enable-background="new 0 0 340 333" xml:space="preserve">
      <defs>
         <mask id="mask">
               <path fill='none' class='maskPath' stroke="white" stroke-width='4' d="M66.039,133.545c0,0-21-57,18-67s49-4,65,8
              s30,41,53,27s66,4,58,32s-5,44,18,57s22,46,0,45s-54-40-68-16s-40,88-83,48s11-61-11-80s-79-7-70-41
              C46.039,146.545,53.039,128.545,66.039,133.545z"/>
            </mask>
      </defs>
      <path mask="url(#mask)" class="path" fill="none" stroke="#000000" stroke-width="3" d="M66.039,133.545c0,0-21-57,18-67s49-4,65,8
        s30,41,53,27s66,4,58,32s-5,44,18,57s22,46,0,45s-54-40-68-16s-40,88-83,48s11-61-11-80s-79-7-70-41
        C46.039,146.545,53.039,128.545,66.039,133.545z"/>
    </svg>
    &#13;
    &#13;
    &#13;

    (因为我是svg的初学者,我可能无法进一步提供帮助)