<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Geometric Button Animation</title>
<style>
.btn-wrapper {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background: #f0f0f0;
}
.geometric-btn {
position: relative;
padding: 15px 30px;
font-size: 18px;
color: #fff;
background: #2196f3;
border: none;
border-radius: 5px;
cursor: pointer;
overflow: hidden;
}
.geometric-btn:focus {
outline: none;
}
.square {
position: absolute;
background: transparent;
border: 2px solid rgba(255, 255, 255, 0.8);
pointer-events: none;
transform-origin: center center;
}
@keyframes squareClockwise {
0% {
opacity: 1;transform: translate(-50%, -50%) rotate(var(--initialRotation)) scale(1);
}
50% {
opacity: 0.8;transform: translate(-50%, -50%) rotate(calc(var(--initialRotation) + 90deg)) scale(0.5);
}
100% {
opacity: 0;transform: translate(-50%, -50%) rotate(calc(var(--initialRotation) + 180deg)) scale(0);
}
}
@keyframes squareCounterClockwise {
0% {
opacity: 1;transform: translate(-50%, -50%) rotate(var(--initialRotation)) scale(1);
}
50% {
opacity: 0.8;transform: translate(-50%, -50%) rotate(calc(var(--initialRotation) - 90deg)) scale(0.5);
}
100% {
opacity: 0;transform: translate(-50%, -50%) rotate(calc(var(--initialRotation) - 180deg)) scale(0);
}
}
</style>
</head>
<body>
<div class="btn-wrapper">
<button class="geometric-btn">Click Me</button>
</div>
<script>
const btn = document.querySelector('.geometric-btn');
btn.addEventListener('click', function(e) {
const rect = btn.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
for(let i = 0; i < 4; i++) {
const square = document.createElement('div');
square.className = 'square';
const size = Math.max(30 - i * 10, 1);
square.style.width = `${size}px`;
square.style.height = `${size}px`;
square.style.left = `${x}px`;
square.style.top = `${y}px`;
const initialRotation = -45 + (i * 45);
square.style.transform = `translate(-50%, -50%) rotate(${initialRotation}deg)`;
square.style.setProperty('--initialRotation', `${initialRotation}deg`);
const animationName = i % 2 === 0 ? 'squareClockwise' : 'squareCounterClockwise';
square.style.animation = `${animationName} 0.75s linear forwards`;
btn.appendChild(square);
square.addEventListener('animationend', () => {
square.remove();
});
}
});
</script>
</body>
</html>
CSS 部分
.btn-wrapper
:使用 Flexbox 布局将按钮居中显示在页面上,背景颜色为浅灰色。
.geometric-btn
:定义按钮的基本样式,包括内边距、字体大小、颜色、背景颜色、边框和圆角等。
.square
:定义方块的基本样式,使用绝对定位,背景透明,有白色边框。
@keyframes squareClockwise
和 @keyframes squareCounterClockwise
:定义两个关键帧动画分别实现方块顺时针和逆时针旋转并缩小消失的效果。
JavaScript 部分
const btn = document.querySelector('.geometric-btn');
:获取按钮元素。
btn.addEventListener('click', function(e) {... });
:为按钮添加点击事件监听器。
const rect = btn.getBoundingClientRect();
:获取按钮的位置和大小信息。
const x = e.clientX - rect.left;
和 const y = e.clientY - rect.top;
:计算点击位置相对于按钮左上角的坐标。
for(let i = 0; i < 4; i++) {... }
:循环创建 4 个不同大小的方块。
square.style.animation =
${animationName} 0.75s linear forwards;
:为方块添加动画效果。
square.addEventListener('animationend', () => { square.remove(); });
:动画结束后移除方块,避免占用过多 DOM 元素。