Code link: https://github.com/zhangKunUserGit/vue-component
Effect picture:
You can run it online: https://zhangkunusergit.github.io/vue-component/dist/btnRipple.html to see the effect (be sure to click hard).
Let's talk about usage first:
<zk-button class = " btn btn-default " >Default button</zk-button> <zk-button class="btn btn-default btn-round">默认按钮</zk-button> <zk-button class = " btn btn-default btn-round " :speed= " 4 " :opacity= " 0.6 " >Define speed and initial wave opacity</zk-button>
principle:
The ripples drawn by canvas + requestAnimationFrame (compatibility can be found online) are used here, and some are made with css transform + setTimeout. I don't feel very good.
Template:
<template> <button class="zk-btn"> <canvas class="zk-ripple" @click="ripple"></canvas> <slot></slot> </button> </template>
The click code is as follows (I have added detailed comments)
ripple(event) { // Clear the animation that was not executed last time if ( this .timer) { window.cancelAnimationFrame(this.timer); } this.el = event.target; // 执行初始化 if (!this.initialized) { this.initialized = true; this.init(this.el); } this.radius = 0; // 点击坐标原点 this.origin.x = event.offsetX; this.origin.y = event.offsetY; this.context.clearRect(0, 0, this.el.width, this.el.height); this.el.style.opacity = this.opacity; this.draw(); },
Here, the canvas is mainly initialized and the position coordinates of the user's click are obtained, and the drawing is started.
loop drawing
draw() { this .context.beginPath(); // Draw ripples this .context.arc( this .origin.x, this .origin.y, this .radius, 0, 2 * Math.PI, false ); this .context.fillStyle = this .color; this .context.fill(); // Define the next drawing radius and transparency this .radius += this .speed; this .el.style.opacity -= this .speedOpacity; / / By judging that the radius is smaller than the element width or still has transparency, the circle is continuously drawn if ( this .radius < this .el.width ||this.el.style.opacity > 0) { this.timer = window.requestAnimationFrame(this.draw); } else { // 清除画布 this.context.clearRect(0, 0, this.el.width, this.el.height); this.el.style.opacity = 0; } }
Summarize:
I did not copy the above code completely, if you want to see the source code, you can download it and have a look
This is the last day of work in April, so take a good rest on 5.1.