三次贝塞尔曲线练习之弹性的圆
dannypub
9年前
<p> </p> <p> </p> <blockquote> <ul> <li>效果图</li> <li>贝塞尔曲线知识讲解</li> </ul> </blockquote> <p> </p> <h3>效果图</h3> <p>开始本文之前先查看一下目标效果是如何的。</p> <p><img src="https://simg.open-open.com/show/29c62e80cf352d09ea5972f8cd191fc9.gif"></p> <p>weibo</p> <p><br> 这个动画的来源是优秀网页设计的一个<a href="/misc/goto?guid=4959670685189539704">微博</a>,看到这个效果感觉下面的圆的动画十分的赞,于是就打算模仿这个效果。</p> <p>然后接下来看我所做的简单效果吧。<br> 项目代码:<a href="/misc/goto?guid=4959670685284099430">https://github.com/DevinShine/MagicCircle</a></p> <p><img src="https://simg.open-open.com/show/6ad089de253675d51ebcdb1cf5e5654c.gif"></p> <p>diorKTU84Papple09152015022708.gif-302.1kB</p> <p><br> 因为时间缘故就简单的模仿了自己感兴趣的主要效果,并没有做到全部模仿,等以后有时间了再完善(挖坑)。</p> <h3>贝塞尔曲线知识讲解</h3> <p>将这个圆的动画效果拆解开看的画,其实会分为5个状态。</p> <p><img src="https://simg.open-open.com/show/045be217ea8735772a1fb66b456579d4.png"></p> <p>pic1.png-2kB</p> <p>状态1</p> <p><img src="https://simg.open-open.com/show/ab392a759d51dc1979fc8633e75d78ee.png"></p> <p>pic2.png-2.4kB</p> <p>状态2</p> <p><img src="https://simg.open-open.com/show/d5131db4c759f7825a1f26bed544be7b.png"></p> <p>pic3.png-2.6kB</p> <p>状态3</p> <p><img src="https://simg.open-open.com/show/0269ec52909223b9b2c8b23bdf9a58f6.png"></p> <p>pic4.png-2.4kB</p> <p>状态4</p> <p><img src="https://simg.open-open.com/show/045be217ea8735772a1fb66b456579d4.png" alt="三次贝塞尔曲线练习之弹性的圆 " width="101" height="100"></p> <p>pic1.png-2kB</p> <p>状态5<br> 注:我这里的状态4和状态5其实与原设计图是有出入的,我这里的5个状态其实是对称关系的,但是原设计图并非是对称关系,然后因为我偷懒,就做成了对称设计,这个以后再优化吧~</p> <p>也就是说,这个动画效果的实现就是不同状态之间的转化加上水平位移的实现,现在已经将动画肢解完了,那么接下来就讲解下如何实现圆的形变吧。</p> <p>开始讲解具体内容之前我们需要先了解一下如何用贝塞尔曲线画一个圆,因为我的做法是通过贝塞尔曲线来实现的。</p> <p><img src="https://simg.open-open.com/show/601666915bb8a9ee1751ec2c757b6363.png"></p> <p>stackoverflow</p> <p><br> 上图是stackoverflow上的一个<a href="/misc/goto?guid=4959670685371111476">答案</a>,这个答案可能说的不是很清楚,这里还有一篇<a href="/misc/goto?guid=4959670685442092539">文章</a>,这两个的结果都是差不多,就是所需要的数值c约等于0.551915024494f,具体的论证过程可以看这两篇文章,那么这个c的值有什么用么,我用最简单的方法来说明,就是把图中的1理解为圆的半径,那么对应的另外个值就应该是半径乘以0.551915024494f。<br> 可能有朋友还是看不懂这个c到底干啥用呢,我下面画一个图来描述下,大概是怎么个意思。</p> <p><img src="https://simg.open-open.com/show/14534c04534b29f31dad51cf34b4d443.png"></p> <p>jiangjietu.png-16.1kB</p> <p><br> 这里的坐标轴也就是Android中的坐标轴了,如果我们打算用贝塞尔曲线来画这么一个圆的话,我们需要知道这个圆的半径,以及图中的M的值,知道这两个值的话就能够知道图中12个点的坐标,知道坐标就能够用Path的cubicTo方法来使用贝塞尔曲线画出圆了。<br> 这里稍微展示点代码来说明如何绘制P0至P3这段圆弧。</p> <pre> mPath.moveTo(p0.x,p0.y); mPath.cubicTo(p1.x, p1.y, p2.x, p2.y, p3.x,p3.y);</pre> <p>这样我们就知道如何使用贝塞尔曲线来绘制一个圆了。也就是状态1和状态5我们都会绘制了,接下来看看状态2如何绘制。</p> <p><img src="https://simg.open-open.com/show/5f1d1c26c0028521b0aa0e8ef2efe02a.jpg"></p> <p>jiangjietu2.png-108.1kB</p> <p><br> 通过上图大家就能很快的明白状态2应该如何绘制,其实就是把右边的点向右移动点距离就行了。<br> 其实photoshop(sketch)这些绘图软件中的钢笔工具(Vector)就是用的贝塞尔曲线,然后这里推荐个<a href="/misc/goto?guid=4958849848767305559">网址</a>给大家,轻松上手钢笔工具的使用哦,强烈推荐!!!</p> <p>看完上面的讲解,那么状态3也就一点都不难了。</p> <p><img src="https://simg.open-open.com/show/042bf341f4fb2663ec30a7335e2245ec.jpg"></p> <p>jiangjietu3.png-111kB</p> <p><br> 看到上图就明白状态3的实现就是在状态2的基础上修改了个值,一个是M的值加大,让圆看起来跟肥一点,还有就是圈住的那些点向右移动,做到居中。</p> <p>至此,这个动画效果的分解也就完成了,其实一点都不难。写到这里的时候我才发现漏了一个回弹,也就懒得补充了QAQ,我的做法就是加个sin函数来控制,比较生硬的回弹,以后再优化吧,要去睡觉了= = 。</p> <p>参考资料:</p> <ol> <li><a href="/misc/goto?guid=4958849848767305559">http://bezier.method.ac/</a></li> <li><a href="https://simg.open-open.com/show/29c62e80cf352d09ea5972f8cd191fc9.gif">http://ww3.sinaimg.cn/mw1024/69b7d63agw1evxh2kw1bcg20m80go1l2.gif</a></li> <li><a href="/misc/goto?guid=4959670685189539704">http://weibo.com/1773655610/CzUai6Gid?type=comment#_rnd1442252060746</a></li> <li><a href="/misc/goto?guid=4959670685371111476">http://stackoverflow.com/questions/1734745/how-to-create-circle-with-b%C3%A9zier-curves</a></li> <li><a href="/misc/goto?guid=4959670685442092539">http://spencermortensen.com/articles/bezier-circle/</a></li> <li><a href="/misc/goto?guid=4959670685609920165">http://gavinliu.cn/2015/03/30/Android-Animation-%E8%B4%9D%E5%A1%9E%E5%B0%94%E6%9B%B2%E7%BA%BF%E4%B9%8B%E7%BE%8E/</a></li> <li><a href="/misc/goto?guid=4959670685697653984">http://dayu.pw/svgcontrol/</a></li> <li><a href="/misc/goto?guid=4958964900116447714">https://github.com/dodola/MetaballLoading</a></li> </ol> <p>来自: <a href="/misc/goto?guid=4959670685805129634" rel="nofollow">http://www.jianshu.com/p/791d3a791ec2#</a> </p>