Update wave
This commit is contained in:
parent
f262b771e6
commit
3ed0785aa1
198
wave
198
wave
|
|
@ -218,4 +218,202 @@
|
|||
|
||||
</body>
|
||||
|
||||
</html<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
.text-transition-container {
|
||||
width: 400px;
|
||||
padding: 40px;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
border-radius: 16px;
|
||||
color: white;
|
||||
margin: 50px auto;
|
||||
text-align: center;
|
||||
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.text-content {
|
||||
font-size: 2rem;
|
||||
font-weight: bold;
|
||||
transition: all 0.5s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 文字切换动画 */
|
||||
@keyframes textSwap {
|
||||
0% {
|
||||
transform: scaleX(1);
|
||||
filter: blur(0);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* 第一阶段:缩小+模糊 */
|
||||
40% {
|
||||
transform: scaleX(0.66);
|
||||
filter: blur(4px);
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
/* 保持缩小状态,准备切换文字 */
|
||||
45% {
|
||||
transform: scaleX(0.66);
|
||||
filter: blur(4px);
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
/* 文字切换的瞬间(透明度最低) */
|
||||
50% {
|
||||
transform: scaleX(0.66);
|
||||
filter: blur(4px);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
/* 新文字出现(仍然缩小) */
|
||||
55% {
|
||||
transform: scaleX(0.66);
|
||||
filter: blur(4px);
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
/* 第二阶段:展开+清晰 */
|
||||
100% {
|
||||
transform: scaleX(1);
|
||||
filter: blur(0);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* 应用动画 */
|
||||
.animate-swap {
|
||||
animation: textSwap 2s ease-in-out forwards;
|
||||
}
|
||||
|
||||
/* 文字容器 - 用于切换 */
|
||||
.text-wrapper {
|
||||
position: relative;
|
||||
height: 60px; /* 固定高度防止跳动 */
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.text-item {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
|
||||
.text-item.original {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.text-item.new {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
/* 动画时切换文字 */
|
||||
.animate-swap .text-item.original {
|
||||
animation: fadeOutSwap 2s ease-in-out forwards;
|
||||
}
|
||||
|
||||
.animate-swap .text-item.new {
|
||||
animation: fadeInSwap 2s ease-in-out forwards;
|
||||
}
|
||||
|
||||
@keyframes fadeOutSwap {
|
||||
0% { opacity: 1; }
|
||||
45% { opacity: 1; }
|
||||
50% { opacity: 0; }
|
||||
100% { opacity: 0; }
|
||||
}
|
||||
|
||||
@keyframes fadeInSwap {
|
||||
0% { opacity: 0; }
|
||||
45% { opacity: 0; }
|
||||
50% { opacity: 1; }
|
||||
100% { opacity: 1; }
|
||||
}
|
||||
|
||||
/* 按钮样式 */
|
||||
.trigger-button {
|
||||
display: block;
|
||||
margin: 30px auto;
|
||||
padding: 12px 30px;
|
||||
font-size: 1rem;
|
||||
background: #4f46e5;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
transition: background 0.3s ease;
|
||||
}
|
||||
|
||||
.trigger-button:hover {
|
||||
background: #4338ca;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="text-transition-container">
|
||||
<div class="text-content">
|
||||
<div class="text-wrapper">
|
||||
<div class="text-item original" id="text1">Hello World</div>
|
||||
<div class="text-item new" id="text2">Welcome Back</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button class="trigger-button" onclick="startTransition()">切换文字</button>
|
||||
|
||||
<script>
|
||||
let isAnimating = false;
|
||||
let currentText = 'original';
|
||||
|
||||
function startTransition() {
|
||||
if (isAnimating) return;
|
||||
|
||||
const textContent = document.querySelector('.text-content');
|
||||
const text1 = document.getElementById('text1');
|
||||
const text2 = document.getElementById('text2');
|
||||
|
||||
isAnimating = true;
|
||||
|
||||
// 添加动画类
|
||||
textContent.classList.add('animate-swap');
|
||||
|
||||
// 设置文字内容(可以动态变化)
|
||||
if (currentText === 'original') {
|
||||
text2.textContent = getRandomText();
|
||||
currentText = 'new';
|
||||
} else {
|
||||
text1.textContent = getRandomText();
|
||||
currentText = 'original';
|
||||
}
|
||||
|
||||
// 动画结束后重置状态
|
||||
setTimeout(() => {
|
||||
textContent.classList.remove('animate-swap');
|
||||
isAnimating = false;
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
function getRandomText() {
|
||||
const texts = [
|
||||
'Amazing!',
|
||||
'Great Job!',
|
||||
'Excellent!',
|
||||
'Well Done!',
|
||||
'Fantastic!',
|
||||
'Impressive!'
|
||||
];
|
||||
return texts[Math.floor(Math.random() * texts.length)];
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Reference in New Issue