「庆余年2」 终于开播了~最近起点读书APP内上架了庆余年典藏书,最大的特色是里面新加入了全新的阅读皮肤,一个拟物化的卷轴滚动效果,效果如下:
就是在拖动页面时,卷轴会随着页面的滚动而展开或卷起,就像在拖动真的画布一样,非常舒适,录屏可能看着不是很清晰,强烈建议去端内自行体验。
当时看到这个效果时就在思考,如何在 web 中也实现这样一个效果呢?
经过一番琢磨,发现仅使用 CSS 就能完成这样的效果。下面是我复刻的效果。
这是如何实现呢?一起看看吧
首先 CSS 中并没有真正的 3d 滚动,立方体还可以勉强拼接,这种圆形的不行,因此我们需要用其他方式来实现。
这里其实是一个最简单的平移动画,只需要将纹理上下无缝平移,结合渐变和阴影,就能得到看似滚动的效果了。
先简单布局一下。
<div class="reel"> <div class="reel-bg"></div></div>
这里要用到卷轴的素材图片,是这样的。
这样就能得到卷轴的结构了。
效果如下:
现在看着非常扁平,没有立体感,主要是纹理没有融入到背景之中。
如何将纹理完美的融合到后面的背景呢?没错,需要用到混合模式,这里用正片叠底就行了。
.reel-bg{ /**/ mix-blend-mode: multiply;}
效果就好很多了。
最后给卷轴加点阴影,超出隐藏。
.reel{ /**/ overflow: hidden; box-shadow: 0 5px 10px 5px rgba(0,0,0,.3), 0 10px 20px 10px rgba(0,0,0,.5);}
这样就比较真实了。
滚动效果出来了,如何和页面滚动关联起来呢?接着往下看。
回到这里,先把整个布局完善一下。
<body> <div class="reel"> <div class="reel-bg"></div> </div> <article> <p>范慎很困难地撑着上眼皮,看着指头算自己这辈子做过些什么有意义的事情,结果右手五根瘦成筷子一样的指头还没有数完,他就叹了一口气,很伤心地放弃了这个工作。病房里的药水味总是这么刺鼻,旁边那床的老爷子前两天已经去地藏王菩萨那里报道了,大概再过几天就轮到自己吧。他得了某种怪病,重症肌无力,就是特别适合言情小说男主角的那种病。据说没得医,将来嗝屁的那天什么都动不了,只有眼泪可以流下来。痛!</p> <p>范慎很困难地撑着上眼皮,看着指头算自己这辈子做过些什么有意义的事情,结果右手五根瘦成筷子一样的指头还没有数完,他就叹了一口气,很伤心地放弃了这个工作。病房里的药水味总是这么刺鼻,旁边那床的老爷子前两天已经去地藏王菩萨那里报道了,大概再过几天就轮到自己吧。他得了某种怪病,重症肌无力,就是特别适合言情小说男主角的那种病。据说没得医,将来嗝屁的那天什么都动不了,只有眼泪可以流下来。痛!</p> <!--很多文本--> </article></body>
简单修饰一下,由于卷轴要固定到顶部,可以采用sticky布局。
html{ background-color: #22312D; font-family: cursive;}body{ margin: 0;}article{ background-color: #F5EBD4; padding: 1em 0.5em; border-left: 10px solid #405C53; border-right: 10px solid #405C53; margin: 0 15px;}p{ margin: 0; padding: 0.2em 0; color: #2C402E; line-height: 150%; text-indent: 2em;}h1{ text-align: center; color: #F5EBD4;}
效果如下:
不过这里还有点问题,由于是整个页面在滚动,内容滚到顶部会漏出来,如下:
现在就让卷轴滚动和页面滚动联动起来, 非常简单,只需要添加animation-timeline属性就行了,设置滚动时间线为root,如下:
.reel-bg{ animation: scroll 1s linear forwards; animation-timeline: scroll(root);}
这样在页面滚动时卷轴也跟着“转动”了。
但看着卷轴转地是不是有点慢了?
确实是这样,这个时候表示页面从头滚到到底部,执行一次动画,也就是滚动一圈,所以页面内容越多,滚动距离越长,那么卷轴转的也就越慢。
下面来修复这个问题
简单来处理,可以给个合适的动画次数,比如:
.reel-bg{ animation: scroll 1s linear forwards 5; animation-timeline: scroll(root);}
这样表示页面从头滚到到底部,会执行5次动画,也就是相当于会滚动5圈,所以看着速度就变快了。
现在就舒服多了。
不过这种处理方式有个问题,动画次数是跟内容长度强相关的,如果在向下滚动时动态加载内容,就需要更新这个值,稍显麻烦。
那么,有没有办法让滚动速度保持均衡呢?也就是无论内容多少,速度都是一致的。
这就需要用到 CSS 动画范围区间了,也就是animation-range,简单来讲就是设置滚动区间。
核心实现其实就这几行,是不是非常简单。
.reel-bg{ --s: 999999; animation: scroll 1s linear forwards calc(var(--s)/184/3.14); animation-timeline: scroll(root); animation-range: 0 calc(var(--s) * 1px);}
虽然 CSS
实现很简单,但是兼容性还不行,截至目前(2024年4月27日)仅支持Chrome 115+。
你也可以访问以下链接查看真实效果。
以上就是本文的全部内容了,一个有趣的交互效果,你学到了吗,下面总结一下本文重点。
[1]CSS QYN book (juejin.cn): https://code.juejin.cn/pen/7362400098958966793。
[2]CSS QYN book (codepen.io): https://codepen.io/xboxyan/pen/VwNqEoE。
本文链接://www.dmpip.com//www.dmpip.com/showinfo-26-91369-0.html一篇带你学习 CSS 实现卷轴滚动效果
声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com
上一篇: Python虚拟环境的15个管理技巧
下一篇: 12306技术内幕,你知道吗?