<svg> <filter id="blur"> <feGaussianBlur in="SourceGraphic" stdDeviation="0 2" /> </filter> </svg>
|
直截了当,没错是用 svg 来实现,其实 css 的样式与 svg 还是蛮接近的(一模一样)
效果
使用
未使用(使用 blur)
鸿蒙开机效果
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <title>Title</title> </head>
<style> body { margin: 0; height: 100vh; display: block; }
.ct-circle-content { --circle-width: 100px; --circle-height: 100px; display: flex; flex-direction: column; gap: 16px; margin: 100px auto; width: 30%; height: 40%; }
.ct-circle-container { display: flex; align-items: center; justify-content: center; background: black; }
.circle-wrap { width: var(--circle-width, 100px); height: calc(var(--circle-height) / 2); padding: 40px; overflow: hidden; }
.circle { height: var(--circle-height); border: 10px solid #fff; border-radius: 50%; box-shadow: 0 0 10px 0 #fff, inset 0 0 10px 0 #fff; box-sizing: border-box; }
.circle-wrap:first-of-type { padding-bottom: 0; }
.circle-wrap:first-of-type .circle { transform: translateY(calc(var(--circle-height) / 2)); animation: 1.2s ease forwards; animation-name: move; }
.circle-wrap:last-of-type { transform: rotate(180deg); padding-bottom: 0; }
.circle-wrap:last-of-type .circle { transform: translateY(calc(var(--circle-height) / 2)); animation: 1.2s ease forwards; animation-name: move; filter: url(#blur); }
svg { width: 0; height: 0; }
@keyframes move { to { transform: translateY(0px); } } </style>
<body> <div class="ct-circle-content"> <div class="ct-circle-actions"> <button class="ct-circle-start">start</button> <button class="ct-circle-pause">pause</button> </div>
<div class="ct-circle-container"> <div class="ct-circle-wrap"> <div class="circle-wrap"> <div class="circle"></div> </div>
<div class="circle-wrap"> <div class="circle"></div> </div> </div>
<svg class="ct-circle-blur"> <filter id="blur"> <feGaussianBlur in="SourceGraphic" stdDeviation="0 2" /> </filter> </svg> </div> </div> </body>
<script> const svgBlur = document.querySelector('#blur feGaussianBlur'); const startButton = document.querySelector('.ct-circle-start'); const pauseButton = document.querySelector('.ct-circle-pause'); const firstCircle = document.querySelector('.circle-wrap:first-of-type .circle'); const lastCircle = document.querySelector('.circle-wrap:last-of-type .circle'); const animationRunStatusMap = { running: 'running', paused: 'paused', start: 'start', end: 'end' } let animationRunStatus; let blurValue = 2;
const getCurrentElBlur = () => { return svgBlur.getAttribute('stdDeviation').split(' ')[1]; };
const setCircleRunStatus = (status) => { document.querySelector('.circle-wrap:first-of-type .circle').style.animationPlayState = status; document.querySelector('.circle-wrap:last-of-type .circle').style.animationPlayState = status; };
const clearBlur = () => { if (animationRunStatus === animationRunStatusMap.paused) { return; } if (animationRunStatus === animationRunStatusMap.end) { blurValue = 0; svgBlur.setAttribute('stdDeviation', `0 0`); return; }
const value = getCurrentElBlur() - 0.01; blurValue = value; if (value > 0 && animationRunStatus === animationRunStatusMap.running) { svgBlur.setAttribute('stdDeviation', `0 ${value}`); } else { return; } requestAnimationFrame(clearBlur); };
startButton.addEventListener('click', () => { if (animationRunStatus === animationRunStatusMap.running) { return; }
if (blurValue === 0) { firstCircle.style.animationName = 'none'; lastCircle.style.animationName = 'none'; svgBlur.setAttribute('stdDeviation', `0 2`); lastCircle.offsetWidth; firstCircle.style.animationName = 'move'; lastCircle.style.animationName = 'move'; } else { setCircleRunStatus('running'); clearBlur(); } });
pauseButton.addEventListener('click', () => { if (animationRunStatus !== animationRunStatusMap.running) { return; }
animationRunStatus = animationRunStatusMap.paused;
setCircleRunStatus('paused'); });
lastCircle.addEventListener('animationstart', (event) => { console.log('animationstart', event); animationRunStatus = animationRunStatusMap.running; clearBlur(); });
lastCircle.addEventListener('animationend', (event) => { console.log('animationend', animationRunStatus, event); animationRunStatus = animationRunStatusMap.end; blurValue = 0; clearBlur(); }); </script> </html>
|