前言
今天为大家制作一个动若脱兔的转换视差效果,当鼠标在目标上左右移动时除了背景产生的位移视差效果外,里面的兔子也会跟着鼠标的位置来作出不同的动作
实现效果:
图片处理
先准备好四个不同动作兔子的图片和背景图
打开 ps 将新建一个 1920 * 500 的图层,将背景图拖进去铺满,然后分别将四个兔子放在指定的位置保存,最后就得到了四张带有背景和兔子的图片
实现效果
html 部分加入 section 标签,在里面分别加入弄好的图片设置不同的 class,并用一个 div 标签将图片都包起来
<section>
<div class="view">
<img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a5c8e6a91c4641fab1cb04f1769ca09e~tplv-k3u1fbpfcp-zoom-1.image" class="sleep" alt="">
<img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/407c35ce4b78485d9226e42a822911ee~tplv-k3u1fbpfcp-zoom-1.image" class="look" alt="">
<img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/b698b8b66e6448a69611d4b31a7079cf~tplv-k3u1fbpfcp-zoom-1.image" class="jump" alt="">
<img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/032fbcb3beae4d04aaab7f269568c98e~tplv-k3u1fbpfcp-zoom-1.image" class="stop" alt="">
</div>
</section>
复制代码
然后来到 css 部分,为 body 标签设置内外边距为 0,最小高度 100vh,将里面的元素垂直居中
body {
margin: 0;
padding: 0;
min-height: 100vh;
display: flex;
align-items: center;
background-color: #fffefa;
}
复制代码
加入 section 选择器,宽度设为 100vw,高 300px,设置相对定位,overflow 设为 hidden
然后加入 section .view 选择器,设置绝对定位,上下左右都为 0,display 设定为 flex,justify-content 和 align-items 都设为 center
再将里面的图片重叠,display 设为 block,为了鼠标移动所产生的位移将图片宽度设大一点为 120%,高度设为 100%,但是图片比例不对,加入 object-fit: cover 图片就会按比例放大填满
section {
width: 100vw;
height: 300px;
position: relative;
overflow: hidden;
}
section .view{
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
display: flex;
justify-content: center;
align-items: center;
}
section img{
position: absolute;
display: block;
width: 120%;
height: 100%;
object-fit: cover;
}
复制代码
然后调整图片的前后排序,当鼠标从左至右移动时候,兔子会由睡觉,转换为站立张望,再转换跳跃,最后结束,所以 class 为 sleep 的图片在最顶,其他的依次排序
section .sleep {
z-index: 9;
}
section .look {
z-index: 8;
}
section .jump {
z-index: 7;
}
section .stop {
z-index: 6;
}
复制代码
然后来到 js 部分,定义一个常量将 section 获取回来,为 section 新增 mousemove 监听鼠标移动的事件,在事件里将鼠标 X 的位置 e.clientX 除以浏览器视窗的宽度 window.outerWidth 的结果保存到变量 percentage 里,这样鼠标移到最左的时候 percentage 是 0,最右是 1,然后将 percentage 的值写到 css 中
const section = document.querySelector('section')
section.addEventListener('mousemove', (e) => {
let percentage = e.clientX / window.outerWidth
section.style.setProperty('--percentage', percentage)
})
复制代码
首先处理背景图的位移效果,section .view 选择器设置属性 transform,设定值为水平移动 translatex(),通过 calc()计算,将 percentage * 100px,即位移最大距离为 100px
section .view {
transform: translatex(calc(var(--percentage) * 100px));
}
复制代码
下一步处理图片的变化了,只需调整透明度就可以达到想要的效果了
一开始四张图片都是显示的,只是 section .sleep 的层级比较高所以显示在最上面,例如 section .sleep 这张图片,当鼠标越往右移动的时候 opacity 的值就越小,percentage 值为 0.1 及以上的时候,section .sleep 这张图片就变透明了,就显示出 section .look 的图片,最后一张照片 opacity 只需设置为 calc(1 + var(--percentage))就行了
section .sleep {
z-index: 9;
opacity: calc(1 - (var(--percentage) - 0.1 ) / 0.1); //percentage为0.1+时逐渐变透明
}
section .look {
z-index: 8;
opacity: calc(1 - (var(--percentage) - 0.25 ) / 0.25);//percentage为0.25+时逐渐变透明
}
section .jump {
z-index: 7;
opacity: calc(1 - (var(--percentage) - 0.4 ) / 0.4);//percentage为0.4+时逐渐变透明
}
section .stop {
z-index: 6;
opacity: calc(1 + var(--percentage)); //一直显示
}
复制代码
当鼠标移出的时候会回复到原来的位置,新增一个 mouseout 事件,设置 percentage 为 0.1,这样鼠标移出的时候就会复原
但是移出的时候比较生硬,需要加点动画过渡,为 section 里的每一个元素都添加 transition 过渡,但是会影响位移的效果,需要在鼠标移动的时候不套用过渡效果
所以得新增一个 mouseenter 事件,当鼠标进入的时候为 section 添加一个 moving 的 class,在 mouseout 事件中再将 moving 移除,当 section 标签有 moving 的时候里面的元素都设置 transition 为 none,就不会影响位移的效果了,完整的转换视差效果就完成了
section.addEventListener('mouseenter', (e) => {
section.classList.add('moving')
})
section.addEventListener('mouseout', (e) => {
section.classList.remove('moving')
section.style.setProperty('--percentage', 0.1)
})
复制代码
section .view,
section .sleep,
section .look,
section .jump,
section .stop {
transition: .2s all ease-in;
}
section.moving .view,
section.moving .sleep,
section.moving .look,
section.moving .jump,
section.moving .stop {
transition: none;
}
复制代码
评论