下面的配图仅供卖萌
很久没有写博客了,今天给大家带来一个小折腾。 虽然说是小折腾,但还是废了不少劲,某位大神的博客写得好: 前端工程师要想脱颖而出,就要拿出草稿纸,所以有了如下这个丑陋无比的配图:
此次折腾的相关信息如下:
cute-qq-redpoint
SVG + JS 实现新版手机 QQ 的手势消除红点消息的动画。 可以打开手机 QQ,在底部菜单消息一栏的红点上进行拖拽体验。 本插件欲实现的就是这个效果。
原理及部分代码
做的比较粗糙,但是基本效果已经实现了。 通过计算草稿中四个坐标位置,然后在 touchmove 中更新 path d 即可,两条二次贝塞尔曲线是关键。 二次贝塞尔曲线的参考坐标可以轻松得出: 两个圆心相连线的中心即为该参考点。 故得到代码如下:
(function () {
"use strict";
var initCircle = document.getElementById("initCircle");
var finalCircle = document.getElementById("finalCircle");
var aPath = document.getElementById("animationPath");
var touchFingers; // 缓存 touches 队列
// 初始圆坐标
var x0 = parseInt(initCircle.getAttribute("cx"));
var y0 = parseInt(initCircle.getAttribute("cy"));
var r0 = parseInt(initCircle.getAttribute("r"));
// 最终圆坐标
var x1;
var y1;
var r1 = parseInt(finalCircle.getAttribute("r"));
//setter
Element.prototype._setter = function (options) {
var attr;
for (attr in options) {
if (options.hasOwnProperty(attr)) {
this.setAttribute(attr, options[attr]);
}
}
};
var updateF = function updateTouches(event) {
touchFingers = event.touches[0];
};
var renderThing = function () {
x1 = touchFingers.clientX;
y1 = touchFingers.clientY;
// 二次贝赛尔曲线参考点
var pX = x0 - (x0 - x1) / 2;
var pY = y0 - (y0 - y1) / 2;
// 勾股 x, y
var _gX = Math.abs(x0 - x1);
var _gY = Math.abs(y0 - y1);
// 勾股定理斜线长度长
var longL = Math.sqrt(_gX * _gX + _gY * _gY);
var sinX = _gY / longL;
var cosX = _gX / longL;
// 四个点的路径构建
var fourPoints = [
"M",
x0 + r0 * sinX,
y0 + r0 * cosX,
"Q",
pX,
pY,
x1 + r1 * sinX,
y1 + r1 * cosX,
"L",
x1 - r1 * sinX,
y1 - r1 * cosX,
"Q",
pX,
pY,
x0 - r0 * sinX,
y0 - r0 * cosX,
"Z",
];
finalCircle._setter({
cx: x1,
cy: y1,
});
// 设置路径
aPath._setter({
d: fourPoints.join(" "),
});
};
document.addEventListener("touchstart", function (e) {
e.preventDefault();
touchFingers = e.touches[0];
});
document.addEventListener("touchmove", function (e) {
e.preventDefault(); // 屏蔽掉默认的滚动行为
updateF(e);
renderThing();
});
})();
演示
用手机打开 codepen 在线 Demo
TODO
- 实现弹性系数 K,模拟拉断的情况,加入初始圆的半径缩小控制
- 插件化处理
留下评论