tz歌词淡入淡出+闪烁动画实现代码
<div class="codebox" data-prev="1"><style>
/* 帖子元素(模拟) */
.pa {
margin: 20px auto;
width: 100% ;
min-height: 600px;
display: grid;
place-items: center;
position: relative;
}
/* 总文本容器 */
#ma { position: absolute; }
/* 单个文本容器 */
.char {
display: block;
padding: 0 2px;
font: bold 2.4em sans-serif;
text-shadow: 1px 1px 2px black;
opacity: 0;
transform: translate(var(--x), var(--y));
animation: fadeIn 1.5s var(--delay) forwards, flash 1s infinite alternate;
}
/* 行内块class : 横排使用 */
.inline-block { display: inline-block; }
/* 文本淡入动画 */
@keyframes fadeIn {
to { transform: translate(0, 0); opacity: 1; }
}
/* 文本闪烁动画 */
@keyframes flash {
to { filter: hue-rotate(360deg); }
}
</style>
<div id="pa" class="pa">
<div id="ma" class="wrapper"></div>
</div>
<p style="text-align:center;">
<input id="inline" type="checkbox" value="0" />
<label for="inline">横排</label>
<button id="btnDo" type="button">再来一次</button>
</p>
<script>
const text = '本是後山人偶做前堂客'; // 待处理的文本内容
breakup(text, ma); // 运行文本特效
btnDo.onclick = () => breakup(text, ma);
// 处理文本函数(打散、封装)
function breakup(str, targetElm) {
targetElm.innerHTML = ''; // 清空总文本容器内容
// 拆解文本为单个、置入数组(同时处理空格以兼顾拼音类语言文本)
const chars = str.split('').map(c => c === ' ' ? ' ' : c);
const frg = document.createDocumentFragment(); // 创建文档碎片
// 遍历文本数组,使用span标签逐一封装文本
chars.forEach((char, idx) => {
const span = document.createElement('span'); // 创建span标签
span.innerHTML = char; // 单个文本置入span标签
span.classList.add('char'); // span标签的class类名(重要,文本样式和动画高度依赖)
const x = Math.random() * (Math.random() > 0.5 ? 300 : -300); // 随机水平位置
const y = Math.random() * (Math.random() > 0.5 ? 300 : -300); // 随机垂直位置
// 追加差异化CSS样式
span.style.cssText += `
display: ${inline.checked ? 'inline-block' : 'block'}; /* 横排或竖排 */
color: hsl(${Math.floor(Math.random() * 360)}, 100%, 50%); /* 随机前景色 */
--x: ${x}px;
--y: ${y}px;
--delay: ${Math.random() * 0.5}s; /* 动画延时 : 主意配套duration-time */
`;
frg.appendChild(span); // span标签加入文档碎片
});
targetElm.appendChild(frg); // 文档碎片加入总文本容器
}
</script>
</div>
<script type="module">
import linenumber from 'https://638183.freep.cn/638183/web/js/linenumber.js';
linenumber();
</script> 这是最初尝试时的结构性代码,部分细节重新做了调整。发出来供感兴趣的朋友研究、扩展。
需要说明:
(一)歌词横排竖排这里单独设置了一个 CSS class 类选择器是出于演示需要,实际应用时只需给 .char 选择器设置好 display 属性即可;
(二)由于闪烁动画需要用到 filter: hue-rotate(360deg); 设置色相滤镜,随机文本颜色(即前景色,color)最好使用 hsl 颜色模型,固定饱和度(s)和 亮度(l),色相(h)随机,这样将不会得到灰度的颜色,hue-rotate 色相转换可以确保作用于每一个文本字节。最初我使用16进制随机颜色,它和 rgb 颜色空间一样都有一定概率得到灰度颜色,hue-rotate 色相转换函数对这类灰度颜色的作用肉眼很难辨识。具体代码在 72 行。 淡入淡出动画解析:
文本字串按自然字符拆分为独立字符,汉字按字拆分,拼音类语言按字母拆分,空格算一个字符。拆分出来的字符由 class="char" 的 span 标签包裹。
每一个 span 标签按自然文本流自动排列,但通过 CSS 的 transform 属性设置其初始位置(代码在第 22 行),然后通过淡入淡出动画 fadeIn 令其各归其位(代码在第 23 行),fadeIn 动画的设置在第 30~32 行代码)。span 的初始位置由 JS 随机进行动态设置,代码 67、68 行分别计算出xy方向随机值,限定在 正负 300px 之内。 马老师辛苦了!我昨天和今天的帖子想套用您的Tz4版代码,但是不会放入mp4视频,只好用您原来没有套装的代码。 我只会套用代码,因为看不懂代码{:5_106:} 寒冬残荷 发表于 2025-12-5 13:11
马老师辛苦了!我昨天和今天的帖子想套用您的Tz4版代码,但是不会放入mp4视频,只好用您原来没有套装的代码 ...
和加mp3差不多,就改两三个参数:
音频:
tz.add('audio', '', '', {src: 'mp3地址'});
视频:
tz.add('video', '', 'pd-vid', {src: 'mp4地址'});
红色部分是标签固定名称,红紫色的部分对应视频选择器 .pd-vid {} 或其它合适的 马老师的演示让我基本理解了字幕实现的条件,我留存好好学习弄懂相互关联的关系。,以后好用。谢谢你,辛苦了,晚上好!{:4_204:}{:4_190:}
本帖最后由 杨帆 于 2025-12-5 19:27 编辑
加入歌词淡入淡出及闪烁动画效果更养眼,谢谢马老师精彩讲授与演示{:4_176:} 杨帆 发表于 2025-12-5 19:22
加入歌词淡入淡出及闪烁动画效果更养眼,谢谢马老师精彩讲授与演示
{:4_190:} 马黑黑 发表于 2025-12-5 18:15
和加mp3差不多,就改两三个参数:
音频:
谢谢老师的回复!问好! 马黑黑 发表于 2025-12-5 12:13
这是最初尝试时的结构性代码,部分细节重新做了调整。发出来供感兴趣的朋友研究、扩展。
需要说明:
是的,在预览里能切换横排和竖排。文本的淡入淡出其实主要是淡入呢,从opacity: 0变为1{:4_204:} 红影 发表于 2025-12-5 21:09
是的,在预览里能切换横排和竖排。文本的淡入淡出其实主要是淡入呢,从opacity: 0变为1
对,所以CSS选择器叫 fadeIn,没有 out 寒冬残荷 发表于 2025-12-5 20:28
谢谢老师的回复!问好!
{:4_190:} 马黑黑 发表于 2025-12-5 12:22
淡入淡出动画解析:
文本字串按自然字符拆分为独立字符,汉字按字拆分,拼音类语言按字母拆分,空格算一 ...
打散的字的初始位置都在300到-300的范围内的任意位置,然后归位。不知歌词很短的时候是否来得及{:4_173:} 这样的讲解十分详细,非常好。黑黑辛苦{:4_187:} 红影 发表于 2025-12-5 21:15
打散的字的初始位置都在300到-300的范围内的任意位置,然后归位。不知歌词很短的时候是否来得及
如果酱紫,可以重设 .char 的 animation 属性,使用较短的时间。不过模块已经设置了很短的 duration-time,0.3s;此外,即便来不及,估计也没关系 红影 发表于 2025-12-5 21:16
这样的讲解十分详细,非常好。黑黑辛苦
手掌辛苦
页:
[1]