下面的配图仅供卖萌

很久没有写博客了,今天给大家带来一个小折腾。 虽然说是小折腾,但还是废了不少劲,某位大神的博客写得好: 前端工程师要想脱颖而出,就要拿出草稿纸,所以有了如下这个丑陋无比的配图:
以上内容是文章摘要

此次折腾的相关信息如下:
cute-qq-redpoint
SVG+JS实现新版手机QQ的手势消除红点消息的动画。 可以打开手机QQ,在底部菜单消息一栏的红点上进行拖拽体验。 本插件欲实现的就是这个效果。
原理及部分代码
做的比较粗糙,但是基本效果已经实现了。 通过计算草稿中四个坐标位置,然后在touchmove中更新path d即可,两条二次贝塞尔曲线是关键。 二次贝塞尔曲线的参考坐标可以轻松得出: 两个圆心相连线的中心即为该参考点。 故得到代码如下:
1 (function(){
2 'use strict';
3
4 var initCircle = document.getElementById('initCircle');
5 var finalCircle = document.getElementById('finalCircle');
6 var aPath = document.getElementById('animationPath');
7
8 var touchFingers; //缓存touches队列
9
10 //初始圆坐标
11 var x0 = parseInt(initCircle.getAttribute('cx'));
12 var y0 = parseInt(initCircle.getAttribute('cy'));
13 var r0 = parseInt(initCircle.getAttribute('r'));
14
15 //最终圆坐标
16 var x1;
17 var y1;
18 var r1 = parseInt(finalCircle.getAttribute('r'));
19
20 //setter
21 Element.prototype._setter = function (options) {
22 var attr;
23 for(attr in options){
24 if(options.hasOwnProperty(attr)){
25 this.setAttribute(attr, options[attr]);
26 }
27 }
28 };
29
30 var updateF = function updateTouches(event) {
31 touchFingers = event.touches[0];
32 };
33
34
35 var renderThing = function () {
36
37 x1 = touchFingers.clientX;
38 y1 = touchFingers.clientY;
39
40 //二次贝赛尔曲线参考点
41 var pX = x0 - ((x0 - x1) / 2);
42 var pY = y0 - ((y0 - y1) / 2);
43
44 //勾股x,y
45 var _gX = Math.abs(x0 - x1);
46 var _gY = Math.abs(y0 - y1);
47
48 //勾股定理斜线长度长
49 var longL = Math.sqrt(_gX * _gX + _gY * _gY);
50
51 var sinX = _gY / longL;
52 var cosX = _gX / longL;
53
54 //四个点的路径构建
55 var fourPoints = [
56 'M',
57 x0 + r0 * sinX,
58 y0 + r0 * cosX,
59 'Q',
60 pX,
61 pY,
62 x1 + r1 * sinX,
63 y1 + r1 * cosX,
64 'L',
65 x1 - r1 * sinX,
66 y1 - r1 * cosX,
67 'Q',
68 pX,
69 pY,
70 x0 - r0 * sinX,
71 y0 - r0 * cosX,
72 'Z'
73 ];
74
75 finalCircle._setter({
76 cx: x1,
77 cy: y1
78 });
79
80 //设置路径
81 aPath._setter({
82 d: fourPoints.join(' ')
83 });
84
85 };
86
87 document.addEventListener('touchstart', function (e) {
88 e.preventDefault();
89 touchFingers = e.touches[0];
90 });
91
92 document.addEventListener('touchmove', function (e) {
93 e.preventDefault(); //屏蔽掉默认的滚动行为
94 updateF(e);
95 renderThing();
96 });
97
98
99 }());演示
用手机打开 codepen在线Demo
TODO
- 实现弹性系数K,模拟拉断的情况,加入初始圆的半径缩小控制
- 插件化处理