js 實(shí)現(xiàn)Material UI點(diǎn)擊漣漪效果示例
正文
我個(gè)人而言還是挺喜歡Material UI這套設(shè)計(jì)風(fēng)格的。一些細(xì)節(jié)方面做的還不錯(cuò)。就比如今天要給大家分享的點(diǎn)擊漣漪效果。Material UI里面叫做Ripples。好了,話不多說,開始吧。
HTML
<div class="example">Click me</div>
CSS
.example {
position: relative;
width: 300px;
height: 300px;
line-height: 300px;
text-align: center;
margin-top: 30px;
box-shadow: 0 2px 4px -1px #0003, 0 4px 5px #00000024, 0 1px 10px #0000001f;
overflow: hidden;
cursor: pointer;
user-select: none;
-webkit-tap-highlight-color: transparent;
}
.ripple {
position: absolute;
border-radius: 50%;
background-color: #0000001a;
animation: ripple 225ms cubic-bezier(0, 0, .2, 1) forwards;
transform: scale3d(0, 0, 0);
pointer-events: none;
}
@keyframes ripple {
from {
transform: scale3d(0, 0, 0);
}
to {
transform: scale3d(1, 1, 1);
}
}
JS
const exampleEl = document.querySelector('.example');
// 移動(dòng)端觸發(fā)順序 touchstart => touchend => mousemove => mousedown => mouseup => click
// 文檔https://w3c.github.io/touch-events/#mouse-events
let rippleEl = null, startTime, isMouseup = false;
// touchstart
function handleTouchstart(e) {
createRipple(e);
}
// touchend
function handleTouchend(e) {
removeRipple(e);
// 阻止mouse事件觸發(fā)
e.preventDefault();
}
// touchcancel
function handleTouchcancel(e) {
removeRipple(e);
}
// mousedown
function handleMousedown(e) {
// 避免mouseup,mouseleave重復(fù)執(zhí)行
isMouseup = false;
createRipple(e);
}
// mouseup
function handleMouseup(e) {
isMouseup = true;
removeRipple(e);
}
// mouseleave
function handleMouseleave(e) {
if (isMouseup || rippleEl === null) {
return;
}
removeRipple(e)
}
// 創(chuàng)建ripple
function createRipple(e) {
startTime = e.timeStamp;
const current = { x: e.clientX, y: e.clientY }
if (e.type === 'touchstart') {
current.x = e.touches[0].clientX;
current.y = e.touches[0].clientY;
}
const rect = exampleEl.getBoundingClientRect();
const vertex = {
nw: { x: rect.left, y: rect.top },
ne: { x: rect.left + rect.width, y: rect.top },
se: { x: rect.left + rect.width, y: rect.top + rect.height },
sw: { x: rect.left, y: rect.top + rect.height }
}
let max = 0;
for (const key in vertex) {
// ripple半徑
const radius = getDistance({ x: current.x, y: current.y }, vertex[key]);
max = Math.max(max, radius);
}
rippleEl = document.createElement('div');
rippleEl.className = 'ripple';
rippleEl.style.left = (current.x - rect.left - max) + 'px';
rippleEl.style.top = (current.y - rect.top - max) + 'px';
rippleEl.style.width = (max * 2) + 'px';
rippleEl.style.height = (max * 2) + 'px';
exampleEl.appendChild(rippleEl);
}
// 移除ripple
function removeRipple(e) {
if (e.timeStamp - startTime > 225) {
rippleEl.remove();
rippleEl = null;
} else {
// 采用animation屬性實(shí)現(xiàn)動(dòng)畫效果。相比transition的好處在于不用手動(dòng)觸發(fā)重繪
rippleEl.addEventListener('animationend', function () {
this.remove();
if (this === rippleEl) {
rippleEl = null;
}
});
}
}
// 綁定事件
exampleEl.addEventListener('mousedown', handleMousedown);
exampleEl.addEventListener('mouseup', handleMouseup);
exampleEl.addEventListener('mouseleave', handleMouseleave);
exampleEl.addEventListener('touchstart', handleTouchstart);
exampleEl.addEventListener('touchend', handleTouchend);
exampleEl.addEventListener('touchcancel', handleTouchcancel);
/**
* 獲取兩點(diǎn)間距離
* @param {object} a 第一個(gè)點(diǎn)坐標(biāo)
* @param {object} b 第二個(gè)點(diǎn)坐標(biāo)
* @returns
*/
function getDistance(a, b) {
const x = a.x - b.x;
const y = a.y - b.y;
return Math.hypot(x, y); // Math.sqrt(x * x + y * y);
}實(shí)現(xiàn)效果

以上就是js 實(shí)現(xiàn)Material UI點(diǎn)擊漣漪效果示例的詳細(xì)內(nèi)容,更多關(guān)于js Material UI點(diǎn)擊漣漪效果的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
微信小程序 使用騰訊地圖SDK詳解及實(shí)現(xiàn)步驟
這篇文章主要介紹了微信小程序 使用騰訊地圖SDK詳解及實(shí)現(xiàn)步驟的相關(guān)資料,需要的朋友可以參考下2017-02-02
mini?webpack打包基礎(chǔ)解決包緩存和環(huán)依賴
這篇文章主要為大家介紹了mini?webpack打包基礎(chǔ)解決包緩存和環(huán)依賴示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09
lodash內(nèi)部方法getData和setData實(shí)例解析
本篇章我們將了解lodash里內(nèi)部關(guān)于Data的操作方法,重點(diǎn)關(guān)注getData、setData兩個(gè)內(nèi)部方法,同時(shí)由實(shí)現(xiàn)上引申其他內(nèi)部封裝的方法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08

