This content originally appeared on DEV Community and was authored by kh lemon
设计思路,增加全局的自定义命令v-ripple,使用v-ripple的元素通过element.appendChild
增加子元素,给子元素增加水波纹的动画效果,同时监听animationend,在动画结束后移除子元素
- 水波纹样式
[ripple] { position: relative; overflow: hidden; }
[ripple] .ripple {
position: absolute;
color: black;
border-radius: 100%;
transform: scale(0);
pointer-events: none;
animation: ripple .4s ease-out; }
@keyframes ripple { to {transform: scale(2); opacity: 0; } }
- 增加水波纹节点
function ripple(event, target) {
let node;
node = document.createElement("div");
node.className = "ripple";
/** 点击目标矩阵尺寸 */
const rect = target.getBoundingClientRect();
/** 当前自定义颜色值,默认是白色透明 */
const color = target.getAttribute("ripple") || "rgba(255, 255, 255, .45)";
console.log("target.getAttribute",target.getAttribute("ripple"));
console.log("color",color);
/** 波纹大小 */
let size = Math.max(rect.width, rect.height);
// 设置最大范围
if (size > 200) size = 200;
// 设置大小
node.style.height = node.style.width = size + "px";
// 设置波纹颜色
node.style.backgroundColor = color;
// 这里必须输出节点后再设置位置,不然会有问题
target.appendChild(node);
const y = event.touches ? event.touches[0].clientY : event.clientY;
const x = event.touches ? event.touches[0].clientX : event.clientX;
const top = y - rect.top - (node.offsetHeight / 2);
const left = x - rect.left - (node.offsetWidth / 2);
// console.log(top, left);
node.style.top = top + "px";
node.style.left = left + "px";
function end() {
node.removeEventListener("animationend", end);
// console.log("动画结束", node);
target.removeChild(node);
ripplePool.push(node);
}
node.addEventListener("animationend", end);
}
- 增加自定义指令
Vue.directive("ripple", {
inserted(el, binding) {
el.setAttribute("ripple", binding.value);
el.addEventListener(eventType, function (e) {
ripple(e, el);
});
}
})
This content originally appeared on DEV Community and was authored by kh lemon