CSS关键帧动画文本效果:逐行出场(封装二)
<style>#papa { width: 200px; border: 1px solid gray; padding: 10px;position: relative; margin: 30px; }
#papa p { position: relative; padding: 0; margin: 6px 0; font: normal 22px sans-serif; text-shadow: 1px 1px 1px gray; animation: 2s forwards; }
#papa p:first-of-type { font-size: 26px; font-weight: bold; text-align: center; }
#papa p:last-of-type { font-size: 16px; text-align: right; }
@keyframes move { to { transform: translate(0); } }
</style>
<div id="papa"></div>
<script>
const textAni = (ar, ele, time = 10000) => {
let tId = 0;
const ps = [];
const mkPs = (lineAr) => {
ps.length = 0;
ele.innerHTML = '';
lineAr.forEach(line => {
let p = document.createElement('p');
p.innerHTML = line;
p.style.transform = `translate(${ele.offsetWidth}px)`;
ele.appendChild(p);
ps.push(p);
});
mkAni();
};
const mkAni = () => {
ps.forEach((p, k) => {
p.onanimationend = () => {
ps[(k + 1) % ps.length].style.animationName = 'move';
if (k === ps.length - 1) setTimeout(() => reset(), time);
};
});
ps.style.animationName = 'move';
};
const reset = () => {
getText();
ps.forEach(p => {
p.style.animationName = '';
p.style.transform = 'translate(${ele.offsetWidth}px)';
setTimeout(() => {
ps.style.animationName = 'move';
}, 500);
});
};
const getText = () => {
const tstr = ar;
const lines = tstr.split('\n').filter(i => i !== '');
tId = (tId + 1) % ar.length;
mkPs(lines);
};
getText();
};
var txtAr = [
`长相思
花似伊,柳似伊。
花柳青春人别离。
低头双泪垂。
长江东,长江西。
两岸鸳鸯两处飞。
相逢知几时。
——【宋】欧阳修`,
`长相思
山一程,水一程,
身向榆关那畔行,
夜深千帐灯。
风一更,雪一更,
聒碎乡心梦不成,
故园无此声。
--【清】纳兰性德`,
];
textAni(txtAr, papa);
</script>
代码:
<style>
#papa { width: 200px; border: 1px solid gray; padding: 10px;position: relative; margin: 30px; }
#papa p { position: relative; padding: 0; margin: 6px 0; font: normal 22px sans-serif; text-shadow: 1px 1px 1px gray; animation: 2s forwards; }
#papa p:first-of-type { font-size: 26px; font-weight: bold; text-align: center; }
#papa p:last-of-type { font-size: 16px; text-align: right; }
@keyframes move { to { transform: translate(0); } }
</style>
<div id="papa"></div>
<script>
const textAni = (ar, ele, time = 10000) => {
let tId = 0;
const ps = [];
const mkPs = (lineAr) => {
ps.length = 0;
ele.innerHTML = '';
lineAr.forEach(line => {
let p = document.createElement('p');
p.innerHTML = line;
p.style.transform = `translate(${ele.offsetWidth}px)`;
ele.appendChild(p);
ps.push(p);
});
mkAni();
};
const mkAni = () => {
ps.forEach((p, k) => {
p.onanimationend = () => {
ps[(k + 1) % ps.length].style.animationName = 'move';
if (k === ps.length - 1) setTimeout(() => reset(), time);
};
});
ps.style.animationName = 'move';
};
const reset = () => {
getText();
ps.forEach(p => {
p.style.animationName = '';
p.style.transform = 'translate(${ele.offsetWidth}px)';
setTimeout(() => {
ps.style.animationName = 'move';
}, 500);
});
};
const getText = () => {
const tstr = ar;
const lines = tstr.split('\n').filter(i => i !== '');
tId = (tId + 1) % ar.length;
mkPs(lines);
};
getText();
};
var txtAr = [
`长相思
花似伊,柳似伊。
花柳青春人别离。
低头双泪垂。
长江东,长江西。
两岸鸳鸯两处飞。
相逢知几时。
——【宋】欧阳修`,
`长相思
山一程,水一程,
身向榆关那畔行,
夜深千帐灯。
风一更,雪一更,
聒碎乡心梦不成,
故园无此声。
--【清】纳兰性德`,
];
textAni(txtAr, papa);
</script>
本帖最后由 马黑黑 于 2024-6-30 11:43 编辑
本封装特色:
(一)支持多单元文本循环输出
每个单元的文本可按示例中的分行写法书写,也可以使用分行符 \n 衔接各行,例如:
var txtAr = [
`长相思\n花似伊,柳似伊。\n花柳青春人别离。\n低头双泪垂。\n长江东,长江西。\n两岸鸳鸯两处飞。\n相逢知几时。\n——【宋】欧阳修`,
`长相思\n山一程,水一程,\n身向榆关那畔行,\n夜深千帐灯。\n风一更,雪一更,\n聒碎乡心梦不成,\n故园无此声。\n--【清】纳兰性德`,
];
(二)实现功能使用嵌套函数完成,主函数名称为 textAni,其内有若干子函数。对于函数,除非特殊需求,可以不用管,甚至可以不用关心它的实现原理和机制。使用时要做的,仅是传递正确的参数,三个:
参数1 :必须,文本数组,例如上面(一)讨论的 txtAr,变量名可自定义,要求格式合法;
参数2 :必须,文本输出目标元素,可填入 id 名,或有效的其它标识;
参数3 :可选,下个单元出场的间隔时间,毫秒单位,默认 10000
其它说明:
CSS样式中:
#papa 选择器不是一定得这么命名,可以命名为其他的名称,然后,① 对应的 p 标签前面的选择器名跟着修改;② HTML使用该选择器名称做 id、JS调研函数参数使用盒子 id。该选择器的样式应根据需要修改、增删属性;
p 标签请保留 position、margin、padding 属性,可根据场景需要或审美需求更改 margin 和 padding 的属性值,但 position 属性请不要修改。
封装了,更加好用。{:4_199:} 南无月 发表于 2024-6-30 11:39
封装了,更加好用。
嵌套函数可以避免使用过多的全局变量,函数内的变量名称也不担心与页面的其他变量名重名,同时看起来也更清爽,对于开发者而言也有好处:逻辑关系更清晰、便于维护。 这个封装好,还特别设置了第一句和最后一句的格式呢,考虑很仔细{:4_199:} 文字是靠左的吧,应该也可以居中呢。特殊诗词可以的,比如一七令{:4_173:} 呵呵呵,我就是像看天书,这搬家轻松 马黑黑 发表于 2024-6-30 11:45
嵌套函数可以避免使用过多的全局变量,函数内的变量名称也不担心与页面的其他变量名重名,同时看起来也更 ...
嵌套函数,这个嵌套之前听说过。。涵数又来吓我了,还组了个团。。
艾玛,赶紧跑去细看说明。。这句
“对于函数,除非特殊需求,可以不用管,甚至可以不用关心它的实现原理和机制。”
真是太友好了。。{:4_170:} 马黑黑 发表于 2024-6-30 11:37
本封装特色:
(一)支持多单元文本循环输出
说明书太重要了。老师V5{:4_199:}细心又体贴。。 南无月 发表于 2024-6-30 17:58
说明书太重要了。老师V5细心又体贴。。
{:4_173:} 南无月 发表于 2024-6-30 17:56
嵌套函数,这个嵌套之前听说过。。涵数又来吓我了,还组了个团。。
艾玛,赶紧跑去细看说明。。这句
{:4_196:} 马黑黑 发表于 2024-6-30 17:58
表情帝上朝了{:4_170:} 马黑黑 发表于 2024-6-30 17:59
别笑得这样,我要开始看说明书了。。{:4_173:} 南无月 发表于 2024-6-30 18:18
别笑得这样,我要开始看说明书了。。
说明文档很重要 南无月 发表于 2024-6-30 18:17
表情帝上朝了
应该的 谢谢老师无私奉献!要好好好学习了! 马黑黑 发表于 2024-6-30 18:18
应该的
有事开奏。。{:4_170:} 马黑黑 发表于 2024-6-30 18:18
说明文档很重要
太重要了。。高手和小白的沟通桥梁{:4_173:} 南无月 发表于 2024-6-30 20:11
太重要了。。高手和小白的沟通桥梁
这不存在谁和谁的问题
页:
[1]
2