自适应宽度
flyKot2025/10/27
效果预览
Welcome to
分析
- 切换动画的实现
进入时添加类名 .movein ,等动画执行完毕后将该类名删掉,退出时添加.moveout 类名,执行完毕后删掉 整个元素 ,同时该元素记得设置为 block
- 宽度变化动画的实现
承载文字内容的span宽度应为 width: max-content; 保持最大宽度,这样才能用 span.scrollWidth 获取到真正的内容宽度
HTML
<div class="layout_flip_text_box">
Welcome to <div class="layout_flip_shake_text">
</div>
</div>
CSS
body,
html {
padding: 0;
margin: 0;
width: 100vw;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
.layout_flip_text_box {
font-weight: 600;
font-size: 34px;
display: flex;
justify-content: flex-start;
align-items: baseline;
gap: 6px;
}
.layout_flip_shake_text {
padding: 6px 6px;
box-shadow: 0 1px 3px 0 #0000001a, 0 1px 2px -1px #0000001a;
border: 1px solid #c9c9c9;
border-radius: 6px;
box-sizing: border-box;
height: 3rem;
line-height: 1;
overflow: hidden;
white-space: nowrap;
transition: width 0.5s ease;
}
.layout_flip_t {
width: max-content;
display: block;
transition: filter 0.5s ease;
}
.movein {
animation: text_in 0.5s ease-in forwards;
}
.moveout {
animation: text_out 0.3s ease-out forwards;
}
@keyframes text_in {
0% {
opacity: 0.2;
filter: blur(10px);
transform: translateY(-100%);
}
100% {
opacity: 1;
filter: blur(0);
transform: translateY(0);
}
}
@keyframes text_out {
0% {
opacity: 1;
filter: blur(0);
transform: translateY(0);
}
100% {
opacity: 0.2;
filter: blur(10px);
transform: translateY(100%);
}
}
JavaScript
const textArr = ["Cursor", "QWEN", "Navicat", "Nocobase"]
let index = 0
function updateWidth(span, container) {
const sWidth = span.scrollWidth
container.style.width = ((sWidth + 14) + "px")
}
function updateData() {
const container = document.querySelector(".layout_flip_shake_text")
const span_before = document.querySelector(".layout_flip_t")
if (span_before) {
span_before.classList.add("moveout")
const newSpanAfter = document.createElement("span")
newSpanAfter.className = "layout_flip_t"
newSpanAfter.classList.add("movein")
newSpanAfter.innerHTML = textArr[index]
container.appendChild(newSpanAfter)
updateWidth(newSpanAfter, container)
setTimeout(() => {
span_before.remove()
if (index < textArr.length - 1) {
index++
} else {
index = 0
}
}, 200);
} else {
const newSpanBefore = document.createElement("span")
newSpanBefore.className = "layout_flip_t"
newSpanBefore.classList.add("movein")
newSpanBefore.innerHTML = textArr[index]
container.appendChild(newSpanBefore)
updateWidth(newSpanBefore, container)
setTimeout(() => {
newSpanBefore.classList.remove("movein")
index++
}, 500);
}
}
updateData()
setInterval(() => {
updateData()
}, 3000);
