600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > 制作一个广告字幕滚动效果的网页的心路历程

制作一个广告字幕滚动效果的网页的心路历程

时间:2019-06-19 03:36:52

相关推荐

制作一个广告字幕滚动效果的网页的心路历程

先看效果

刚开始的需求是,制作一个类似电视广告字幕的效果,我没什么思路,后来看了字幕的实现方式,就是用css动画的移动实现,于是我开始了对这段动画的驾驭。

技术:万能的vue.js html5 css3

首先我们要提取到一个html文件中,在文件中引用需要的CDN

<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><title>demo</title></head><script src="/vue/dist/vue.js"></script><link rel="stylesheet" href="/element-ui/lib/theme-chalk/index.css"><script src="/element-ui/lib/index.js"></script><style lang='scss' scoped></style><body><div id="app"></div></body><script src="/axios/dist/axios.min.js"></script><script src="/jquery-3.6.0.slim.js"integrity="sha256-HwWONEZrpuoh951cQD1ov2HUK5zA5DwJ1DNUXaM6FsY=" crossorigin="anonymous"></script><script>new Vue({el: '#app',data: function () {return {}},mounted() {},methods: {}})</script></html>

我们写一个外面的块,宽度是100%,再写一个里面的块,再里面的块里放置内容。内容部分暂且不管,我主要讲实现思路。

<body><div id="app"><template><div class="marquee-outer-wrapper"><div class="marquee-inner-wrapper"><div class="span first-marquee"><div class="item" v-for="item in cionList" :key="item.id"><img :src="item.icon" alt="" class="icon" /><div class="title">{{item.name}}</div><div class="text">[{{item.crypto}}]</div><div class="pre">${{item.a}}</div><div :class="item.isRed > 0 ? 'green' : 'red'"><i:class="item.isRed > 0 ? 'el-icon-caret-top' : 'el-icon-caret-bottom'">{{item.isRed}}%</i></div></div></div></div></div></template></div></body>

.marquee-outer-wrapper {width: 100%;overflow: hidden;position: absolute;top: 0;left: 0;}.marquee-inner-wrapper {background: #1D2330;height: 50px;line-height: 50px;margin: 0 auto;white-space: nowrap;position: relative;}.marquee-inner-wrapper .span {position: absolute;top: 0;left: 100%;/* right: 100%; */height: 100%;display: flex;flex-direction: row;justify-content: space-evenly;}.item {display: flex;flex-direction: row;justify-content: start;}.first-marquee {-webkit-animation: 20s first-marquee linear infinite normal;animation: 20s first-marquee linear infinite normal;padding-left: 20%;}.icon {width: 22px;height: 22px;margin-top: 14px;margin-left: 20px;}.title {line-height: 50px;font-size: 14px;color: #2D74C4;margin-left: 6px;}.text {line-height: 50px;font-size: 12px;color: #939494;margin-left: 4px;}.pre {line-height: 50px;font-size: 14px;color: white;font-weight: bold;margin-left: 6px;}.red {line-height: 50px;font-size: 10px;color: #E5541E;margin-left: 4px;}.green {line-height: 50px;font-size: 10px;color: #049E62;margin-left: 4px;}@keyframes first-marquee {0% {-webkit-transform: translate3d(0, 0, 0);transform: translate3d(0, 0, 0);}/* 向左移动 */100% {-webkit-transform: translate3d(-200%, 0, 0);transform: translate3d(-200%, 0, 0);display: none;}}

这里的思路主要是把里面的div放在屏幕的最右侧,然后设置向左迅速运动的动画,达到字幕滚动的效果。

但是问题来了,动画只运行一次,结束后才运行第二次。功能达到了但是效果不够完美。

于是,我想再写一个里面的div,但是是在第一个div先运行一段时间后再跑起来,思路有了,开始实现。

<body><div id="app"><template><div class="marquee-outer-wrapper"><div class="marquee-inner-wrapper"><div class="span first-marquee"><div class="item" v-for="item in cionList" :key="item.id"><img :src="item.icon" alt="" class="icon" /><div class="title">{{item.name}}</div><div class="text">[{{item.crypto}}]</div><div class="pre">${{item.a}}</div><div :class="item.isRed > 0 ? 'green' : 'red'"><i:class="item.isRed > 0 ? 'el-icon-caret-top' : 'el-icon-caret-bottom'">{{item.isRed}}%</i></div></div></div><div class="span second-marquee"><div class="item" v-for="item in cionList" :key="item.crypto"><img :src="item.icon" alt="" class="icon" /><div class="title">{{item.name}}</div><div class="text">[{{item.crypto}}]</div><div class="pre">${{item.a}}</div><div :class="item.isRed > 0 ? 'green' : 'red'"><i:class="item.isRed > 0 ? 'el-icon-caret-top' : 'el-icon-caret-bottom'">{{item.isRed}}%</i></div></div></div></div></div></template></div></body>

.second-marquee {-webkit-animation: 20s first-marquee linear 8s infinite normal;animation: 20s first-marquee linear 8s infinite normal;padding-left: 20%;}

在原有的基础上,又添加了一个类是span的div。不同的是它运行的动画是.second-marquee。这个动画和原有的动画区别就在于,这个动画相对上一个动画延时8s播放,达到一前一后的效果。

现在动画动起来了,但是需求又增加了。

大致内容就是在地址栏输入参数,根据参数的值可以修改一些属性,比如整体的高度,滚动条的颜色,运行的速度,运行的方向,甚至字体的大小。那么先来处理参数。

getParams() {let str = window.location.hrefif (str.indexOf("?") == -1) {return} else {let params = str.split('?')[1]let paramsList = params.split('&')let paramsObj = {}for (let i = 0; i < paramsList.length; i++) {const item = paramsList[i];paramsObj[item.split('=')[0]] = item.split('=')[1]}// console.log(paramsObj);this.params = paramsObjthis.size = this.params.size}}

这时,我们不知道传来的参数都是什么,除了size,因为是后加的,我就直接提取了出来。

那么接下来考虑的是怎么改这些属性。因为这些属性都是写在样式里面的,我首先想到vue和jquery混写,但是网上都说尽量避免这种写法。那就另辟蹊径,利用document.styleSheets获取当前文件的所有css,再利用deleteRule方法和insertRule方法修改。继续实现。

setStyle() {if (!this.params) {return} else {console.log(document.styleSheets[1]);var style = document.styleSheets[1];// 控制向左向右if (!this.params.direction) {return} else if (this.params.direction == "left") {style.deleteRule(2)style.insertRule(".marquee-inner-wrapper .span { position: absolute; top: 0px; left: 100%; height: 100%; display: flex; flex-direction: row; justify-content: space-evenly; }", 2);style.deleteRule(12)style.insertRule("@keyframes first-marquee { \n 0% { transform: translate3d(0px, 0px, 0px); }\n 100% { transform: translate3d(-200%, 0px, 0px); display: none; }\n}", 12)} else {style.deleteRule(2)style.insertRule(".marquee-inner-wrapper .span { position: absolute; top: 0px; right: 100%; height: 100%; display: flex; flex-direction: row; justify-content: space-evenly; }", 2);style.deleteRule(12)style.insertRule("@keyframes first-marquee { \n 0% { transform: translate3d(0px, 0px, 0px); }\n 100% { transform: translate3d(200%, 0px, 0px); display: none; }\n}", 12)}// 控制高度if (!this.params.height) {return} else {style.deleteRule(11)style.insertRule(".green { line-height: " + this.params.height + "px; font-size: " + this.size * 0.7 + "px; color: rgb(4, 158, 98); margin-left: 4px; }", 11)style.deleteRule(10)style.insertRule(".red { line-height: " + this.params.height + "px; font-size: " + this.size * 0.7 + "px; color: rgb(229, 84, 30); margin-left: 4px; }", 10)style.deleteRule(9)style.insertRule(".pre { line-height: " + this.params.height + "px; font-size: " + this.size + "px; color: white; font-weight: bold; margin-left: 6px; }", 9)style.deleteRule(8)style.insertRule(".text { line-height: " + this.params.height + "px; font-size: " + this.size * 0.8 + "px; color: rgb(147, 148, 148); margin-left: 4px; }", 8)style.deleteRule(7)style.insertRule(".title { line-height: " + this.params.height + "px; font-size: " + this.size + "px; color: rgb(45, 116, 196); margin-left: 6px; }", 7)style.deleteRule(6)style.insertRule(".icon { width: " + this.size * 1.5 + "px; height: " + this.size * 1.5 + "px; margin-top: " + (this.params.height - this.size * 1.5) / 2 + "px; margin-left: 20px; }", 6)style.deleteRule(1)style.insertRule(".marquee-inner-wrapper { background: rgb(29, 35, 48); height: " + this.params.height + "px; line-height: " + this.params.height + "px; margin: 0px auto; white-space: nowrap; position: relative; }", 1)}// 控制背景颜色if (!this.params.backgroundColor) {return} else {document.getElementsByClassName("marquee-inner-wrapper")[0].style.backgroundColor = "rgb(" + this.params.backgroundColor + ")"}// 控制速度if (!this.params.speed) {return} else {style.deleteRule(4)style.insertRule(".first-marquee { animation: " + this.params.speed + "s linear 0s infinite normal none running first-marquee; padding-left: 20%; }", 4)style.deleteRule(5)style.insertRule(".second-marquee { animation: " + this.params.speed + "s linear " + (this.params.speed) / 2 + "s infinite normal none running first-marquee; padding-left: 20%; }", 5)}}}

这里应该是有优化的空间,我说一下我这种写法的坑。注意一下控制高度的地方,这里顺序是从高到低,为什么这样操作呢,因为当你使用deleteRule方法后,样式的数量会减少,下标也会随之变化,那为什么要用deleteRule方法呢,因为insertRule方法是插入一条,覆盖之前的,这样我们就先发制人,先删除再插入就ok了。

再来说一下insertRule后面跟的字符串就是这个样式的并行字符串,非常容易写错,怎么办呢,就是打印document.styleSheets,这里面每个样式都写的一清二楚,复制过来再把变量替换进去就ok啦。

现在是两列“小火车”交替行进,如何控制他们的距离呢,也就是两列小火车的距离,就在这里

.first-marquee {-webkit-animation: 0s first-marquee linear infinite normal;animation: 0s first-marquee linear infinite normal;padding-left: 20%;}.second-marquee {-webkit-animation: 0s first-marquee linear 0s infinite normal;animation: 0s first-marquee linear 0s infinite normal;padding-left: 20%;}

注意看这个padding-left: 20%;,你可以试试其他的值有什么意想不到的效果。

这里也是经历了我的魔改最后实现一个完美的效果。

最后再来看一遍成品

最后的最后,这个数据接口还是自己找吧,网络上应该不少,或者使用假数据练习。

能读到这的都是大牛,哈哈哈哈我废话贼多

拓展

你觉得这种滚动效果可以做什么有趣的功能呢?

鼠标悬停可以暂停动画,配合点击事件,做一个小小的播放器怎么样。

放一些链接进去,点击之后在小窗里面显示网页内容。

还能怎么玩?

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。