HTML:
<div onclick="animationColor(this)">点 击</div>
CSS:
div { width: 320px; height: 80px; line-height: 80px; text-align: center; font-size: 40px; color: white; border-radius: 8px; box-shadow: 5px 5px 10px #888888; background-color: #017EFF; cursor: pointer; }
JS:
function animationColor(obj) { // 最短总时长,在正中间点击时的时长,越向长边的两端,时长越短,最短为初始的一半 // 总长度 / 步长 * 间隔 = 总时长,如果总长度不变,总时长随点击位置变化,那么步长越大,间隔越大 // 间隔 = 总时长 / 总长度 / 步长 // 获取鼠标点击的控件位置,也就是阴影的起始位置(百分比) const objRect = obj.getBoundingClientRect(); const maxSide = objRect.width * 1.5; // 先写死宽是最宽边 const x = Math.round((event.clientX - objRect.x) / objRect.width * 100); // (鼠标点击的位置 - 控件的位置) / 控件大小 * 100 const y = Math.round((event.clientY - objRect.y) / objRect.height * 100); // (鼠标点击的位置 - 控件的位置) / 控件大小 * 100 const beginOpacity = 0.7; // 点击透明的初始值 const runTime = 300; // 效果运行总时长,值越小速度越快 const step = 4; // 阴影扩大步长 const offset = parseFloat((1 - Math.abs(50 - x) / 100).toFixed(1)); // 鼠标点击距中心的偏移量,50 表示中间,这里减去 x 是因为控件“宽”是最长边,如果控件“高”是最长边,你知道怎么做 const totalTime = runTime * offset; // 距离中心越远速度越快,值越小 const shadowRange = 20; // 弥散度,值越小弥散越明显 const maxLength = maxSide / offset; // 阴影执行的最大长度,确保完全填充整个控件,需要根据点击的位置处理,离中心越远,此值越大 const intervalTime = totalTime / (maxSide / step); // setInterval 方法的第二个参数,重复执行行的间隔 const totalRunTimes = maxLength / step; // 执行的总次数,透明度 opacity 还原时使用 // 初始化一些要用到的值 let size = 0; // 记录当前阴影大小 obj.style.opacity = beginOpacity; // 初始透明度,从0开始太难看 if (obj.intervalId === undefined) { obj.intervalId = 0; // setInterval 的返回值,停止时使用 } if (obj.intervalId === 0) { obj.intervalId = setInterval(function() { obj.style.opacity = parseFloat(obj.style.opacity) + ((1- beginOpacity) / totalRunTimes); obj.style.backgroundImage = "radial-gradient(circle " + size + "px at " + x + "% " + y + "%, #017EFF " + shadowRange + "%, #2CDCB1)"; // 这里的50%是比较舒服的值,可以根据感觉修改 size += step; if (size > maxLength) { // 这里总长度需要根据鼠标点击距中心的偏移量增加,这里用 objRect.width 也是因为 宽 是最长边 clearInterval(obj.intervalId); obj.style.backgroundImage = ""; obj.intervalId = 0; obj.style.opacity = 1; } }, intervalTime); } else { clearInterval(obj.intervalId); obj.style.backgroundImage = ""; obj.intervalId = 0; obj.style.opacity = 1; animationColor(obj); } }