Apple官网动画风格的实现
点击公众关注号,“技术干货”及时达!前言本人非常喜欢Apple的官网动画,然后最近又正好在帮朋友做一个工厂的官网。借此机会做一个类似Apple风格的网站。
想实现的动画效果想实现一个随着鼠标滚动画线以及元素依次出现的效果
精髓在于一条公式Apple网站灵动的精髓在于有很多随鼠标滚动的动画。因此我们要处理的就是随着鼠标滚动的值与html元素之间的变化。
这条公式的作用是:随着鼠标滚动,页面从顶部到底部,scrolled会从0-1变化。
let scrolled = html.scrollTop / (html.scrollHeight - html.clientHeight)
由于我是数学菜鸡,刚开始不太理解这条公式,后面想明白了。
分享一下我的思考过程
用到的API:html.scrollTop是html页面已经滚动的值html.scrollHeight是html页面的高度html.clientHeight是页面窗口的高度,也就是我们在浏览器看到的内容高度当初的疑问html.scrollTop / (html.scrollHeight - html.clientHeight) :当滚动的像素等于页面高度的像素时,html.scrollTop / (html.scrollHeight - html.clientHeight)就等于1。为什么要 (html.scrollHeight - html.clientHeight) ,页面滚动到底时,由于html.scrollHeight得到的是页面已经滚动的像素值,但这个值并不是页面到底的值,也就是说。此时html.scrollHeight与html.scrollHeight并不相等,相差一个视窗的高度像素值,所以需要减去视窗的高度。在网页中的具体应用由于并不是整个页面滚动,所以需要把公式由原来的滚动距离相较于整个页面高度改成相较于我们需要实现效果的区域
公式就变成了这样
let parentElement = el.parentElement; //获取父元素
let htmlScrollTop = document.documentElement.scrollTop + document.documentElement.clientHeight// 页面已滚动的高度
let offsetTop = parentElement.offsetTop //元素顶部距离页面高度
if (htmlScrollTop = offsetTop && htmlScrollTop = offsetHeight) {
let scrolled = (htmlScrollTop - offsetTop) / (offsetHeight - offsetTop)
}
改动的地方:
将滚动高度改为滚动高度减去展示动画所在元素的高度(htmlScrollTop - offsetTop)将底部高度改为展示动画所在元素底部的高度判断滚动的距离是否在元素高度和元素底部高度之间这样就能实现网页滚动到展示动画所在元素时scrolled值增长,滚动到元素底部时,为1。然后就可以随着值的改变通过dom改变元素了!
效果实现片段需要注意的是这里是vue3的代码片段。
画线:通过设置长度值慢慢把线画出来el.style.height = ${scrolled * 90}%
li元素的依次出现:
计算每个元素应该出现的区间,然后通过设置 CSS 自定义属性来显示元素。
let total = 1 / liElements.length
for (let index = 0; index liElements.length; index++) {
let row = liElements[index]
let start = total * index
let end = total * (index + 1)
let progress = (scrolled - start) / (end - start)
if (progress = 1) progress = 1
if (progress = 0) progress = 0
row.style.setProperty('--progress', progress)
}
全部代码html部分:
div class="line" v-scrolling-line/div
li class="liLeft"
h22000年/h2
h2成立永发模具厂/h2
p以小作坊形式开始运作
img src="src\assets\images\page2-1.jpg" alt=""
/li
li class="liRigth"
h22006年/h2
h2引进先进设备/h2
p通过多次技改项目的投入,工厂
不断引进设备、人才、软件。
img src="src\assets\images\page2-2.jpg" alt=""
/li
li class="liLeft"
h22016年/h2
h2更名为天龙模具加工厂/h2
p现为集产品和模具开发、设计、
制造于一体的科技型企业。
img src="src\assets\images\page2-3.jpg" alt=""
/li
js部分:
const vScrollingLine = {
mounted: (el) = {
window.addEventListener('scroll', () = {
let parentElement = el.parentElement; //获取父元素
let htmlScrollTop = document.documentElement.scrollTop + document.documentElement.clientHeight// 已滚动高度
let offsetTop = parentElement.offsetTop //元素距离页面高度
let offsetHeight = offsetTop + parentElement.offsetHeight //元素底部距离页面高度,也就是顶部加上元素的高度。
let liElements = document.querySelectorAll('.page2li')
if (htmlScrollTop = offsetTop && htmlScrollTop = offsetHeight) {
let scrolled = (htmlScrollTop - offsetTop) / (offsetHeight - offsetTop)
el.style.height = `${scrolled * 90}%`
let total = 1 / liElements.length
for (let index = 0; index liElements.length; index++) {
let row = liElements[index]
let start = total * index
let end = total * (index + 1)
let progress = (scrolled - start) / (end - start)
if (progress = 1) progress = 1
if (progress = 0) progress = 0
row.style.setProperty('--progress', progress)
}
}
})
}
}
css部分:
.line {
position: absolute;
left: 50%;
top: 0%;
transform: translateX(-50%);
width: 13px;
border-bottom-left-radius: 12px;
border-bottom-right-radius: 12px;
background-color: white;
}
li {
list-style: none;
--progress: 0;
opacity: var(--progress);
img {
width: 30vw;
}
&.liLeft {
transform: scale(calc(1.8 - (0.8 * var(--progress)))) translateX(-80%) translateY(calc(-60px * (1 - var(--progress))));
}
&.liRigth {
transform: scale(calc(1.8 - (0.8 * var(--progress)))) translateX(80%) translateY(calc(-60px * (1 - var(--progress))));
}
}
附上自己在pad画的思考过程
9487e5a52d05e8d44b6c97b398239ef.jpg通过节流算法优化性能和动画卡顿什么是节流算法节流的原理是,如果你频繁触发一个函数,那么在一段时间内只执行一次,不管这段时间内触发多少次。这种技术常用于滚动事件,比如滚动加载更多,滚动监听等场景。一个经典的节流算法:
functionthrottle(func,wait){
letlastTime=0;
returnfunction(){
letnow=Date.now();
if(now-lastTimewait){
func();
lastTime=
}
}
}
具体到本案例中的使用:这段代码实现了通过节流算法,哪怕在有效范围内触发了滚动监视器,其中的回调函数也并不会一直执行,会保持17毫秒的间隔,理论上这里通过数值越小动画越流畅,但是由于对DOM的操作会消耗大量的性能,实际上反而会造成卡顿,而人眼能感知的最高帧率大约是60帧/秒,也就是每帧大约16.67毫秒。JavaScript无法处理带小数点的毫秒,所以四舍五入设置为了17
functionthorttle(func,waitTime){
letstartTime=0
returnfunction(){
letnow=Date.now()
if(now-startTime=waitTime){
func.apply(this,arguments)
startTime=now
}
}
}
letpageScroll=(el)={
returnfunction(){
letparentElement=el.parentElement;//获取父元素
lethtmlScrollTop=document.documentElement.scrollTop+document.documentElement.clientHeight//已滚动高度
letoffsetTop=parentElement.offsetTop//元素距离页面高度
letoffsetHeight=offsetTop+parentElement.offsetHeight//元素底部距离页面高度,也就是顶部加上元素的高度。
letliElements=document.querySelectorAll('.page2li')
if(htmlScrollTop=offsetTophtmlScrollTop=offsetHeight){
letscrolled=(htmlScrollTop-offsetTop)/(offsetHeight-offsetTop)
el.style.height=`${scrolled*90}%`
lettotal=1/liElements.length
for(letindex=0;indexliElements.length;index++){
letrow=liElements[index]
letstart=total*index
letend=total*(index+1)
letprogress=(scrolled-start)/(end-start)
if(progress=1)progress=1
if(progress=0)progress=0
row.style.setProperty('--progress',progress)
}
}
}
}
constvScrollingLine={
mounted:(el)={
window.addEventListener('scroll',thorttle(pageScroll(el),17))
}
}
点击公众关注号,“技术干货”及时达!
阅读原文
网站开发网络凭借多年的网站建设经验,坚持以“帮助中小企业实现网络营销化”为宗旨,累计为4000多家客户提供品质建站服务,得到了客户的一致好评。如果您有网站建设、网站改版、域名注册、主机空间、手机网站建设、网站备案等方面的需求...
请立即点击咨询我们或拨打咨询热线:13245491521 13245491521 ,我们会详细为你一一解答你心中的疑难。 项目经理在线