使用 pasition 制作酷炫Path过渡动画

lhg888 7年前
   <p><img src="https://simg.open-open.com/show/fc5df32e5d0e5c7315efe46557f7cbe4.gif"> <img src="https://simg.open-open.com/show/a3f4ba7c30e1f0bbcf4281c8e08898e4.gif"></p>    <h2>pasition</h2>    <p>Pasition – Path Transition with little JS code, render to anywhere – 超小尺寸的Path过渡动画类库</p>    <ul>     <li><a href="/misc/goto?guid=4959750232355243560" rel="nofollow,noindex">Github源代码</a></li>     <li><a href="/misc/goto?guid=4959750232446850970" rel="nofollow,noindex">在线演示</a></li>    </ul>    <p>最近和贝塞尔曲线杠上了,如 <a href="/misc/goto?guid=4959750232533236555" rel="nofollow,noindex">curvejs</a> 和 <a href="/misc/goto?guid=4959750232355243560" rel="nofollow,noindex">pasition</a> 都是贝塞尔曲线的应用案例,未来还有一款和贝塞尔曲线相关的开源的东西,暂时保密。</p>    <h2>安装</h2>    <pre>  <code class="language-javascript">npm install pasition     </code></pre>    <p>CDN地址下载下来使用:</p>    <p><a href="/misc/goto?guid=4959750232620444363" rel="nofollow,noindex">https://unpkg.com/pasition@1.0.1/dist/pasition.js</a></p>    <h2>使用指南</h2>    <h3>pasition.lerp</h3>    <p>你可以通过 pasition.lerp 方法拿到插值中的shapes:</p>    <pre>  <code class="language-javascript">var shapes  = pasition.lerp(pathA, pathB, 0.5)  //拿到shapes之后你可以在任何你想要渲染的地方绘制,如canvas、svg、webgl等  ...     </code></pre>    <h3>pasition.animate</h3>    <pre>  <code class="language-javascript">pasition.animate({      from : fromPath,      to : toPath,      time : time,      easing : function(){ },      begin :function(shapes){ },      progress : function(shapes, percent){ },      end : function(shapes){ }  })     </code></pre>    <p>path从哪里来?你可以从svg的path的d属性获取。</p>    <p>支持所有的SVG Path命令:</p>    <pre>  <code class="language-javascript">M/m = moveto  L/l = lineto  H/h = horizontal lineto  V/v = vertical lineto  C/c = curveto  S/s = smooth curveto  A/a = elliptical Arc  Z/z = closepath  Q/q = quadratic Belzier curve  T/t = smooth quadratic Belzier curveto     </code></pre>    <p>举个例子:</p>    <pre>  <code class="language-javascript">pasition.animate({      from: 'M 40 40 Q 60 80 80 40T 120 40 T 160 40 z',      to: 'M32,0C14.4,0,0,14.4,0,32s14.3,32,32,32 s32-14.3,32-32S49.7,0,32,0z',      time: 1000,      easing : function(){ },      begin:function(shapes){ },      progress : function(shapes, percent){          //你可以在任何你想绘制的地方绘制,如canvas、svg、webgl      },      end : function(shapes){ }  });     </code></pre>    <p>对上面传入的配置项目一一解释下:</p>    <ul>     <li>from 起始的路径</li>     <li>to 终点的路径</li>     <li>time 从from到to所需要的时间</li>     <li>easing 缓动函数(不填默认是匀速运动)</li>     <li>begin 开始运动的回调函数</li>     <li>progress 运动过程中的回调函数</li>     <li>end 运动结束的回调函数</li>    </ul>    <p>在progress里可以拿到path转变过程中的shapes和运动进度percent(范围是0-1)。下面来看看shapes的结构:</p>    <pre>  <code class="language-javascript">[      [         [],    //curve         [],    //curve         []    //curve         ],      //shape            [[],[],[],[],[]],     //shape            [[],[],[],[],[]]     //shape      ]     </code></pre>    <p>在开发者工具里截图:</p>    <p><img src="https://simg.open-open.com/show/9902148e72d56d8931eebc9111256d12.jpg"></p>    <p>每条curve都包含8个数字,分别代表三次贝塞尔曲线的 起点 控制点 控制点 终点。</p>    <p><img src="https://simg.open-open.com/show/c5532f0e2f093a740221961865490263.png"></p>    <p>每个shape都是闭合的,所以shape的基本规则是:</p>    <ul>     <li>每条curve的终点就是下一条curve的起点</li>     <li>最后一条curve的终点就是第一条curve的起点</li>    </ul>    <p>知道基本规则之后,我们可以进行渲染,这里拿canvas里渲染为例子:</p>    <p>Fill模式:</p>    <pre>  <code class="language-javascript">function renderShapes(context, curves, color){      context.beginPath();      context.fillStyle = color||'black';      context.moveTo(curves[0][0], curves[0][1]);      curves.forEach(function(points){          context.bezierCurveTo(points[2], points[3], points[4], points[5], points[6], points[7]);      })      context.closePath();      context.fill();  }     shapes.forEach(function(curves){      renderShapes(context,curves,"#006DF0")  })     </code></pre>    <p>Stroke模式:</p>    <pre>  <code class="language-javascript">function renderCurve(context, points, color){      context.beginPath();      context.strokeStyle = color||'black';      context.moveTo(points[0], points[1]);      context.bezierCurveTo(points[2], points[3], points[4], points[5], points[6], points[7]);      context.stroke();  }     shapes.forEach(function(curves){      curves.forEach(function (curve) {          renderCurve(context, curve, "#006DF0")      })    })     </code></pre>    <p>当然你也可以把shapes转成SVG的命令在SVG渲染,这应该不是什么困难的事情:</p>    <pre>  <code class="language-javascript">    function toSVGPath(shapes){          //把 shapes数组转成 M....C........C........Z M....C.....C....C...Z 的字符串。      }     </code></pre>    <p>这个函数可以自行尝试一下,生成出的字符串赋值给SVG的Path的d就可以了。</p>    <p>更新: <a href="/misc/goto?guid=4959750232716478546" rel="nofollow,noindex">liyongleihf2006 的SVG解决方案</a></p>    <h2>Github</h2>    <p><a href="/misc/goto?guid=4959750232355243560" rel="nofollow,noindex">https://github.com/AlloyTeam/pasition</a></p>    <h2>License</h2>    <p>This content is released under the <a href="/misc/goto?guid=4958849120936875745" rel="nofollow,noindex">MIT</a> License.</p>    <p>  </p>   <p> </p>    <p></p>