PK创意闹新春,我正在参加「春节创意投稿大赛」,详情请看:春节创意投稿大赛
前言
为了这次掘金的闹新春活动,我也算是苦思冥想了两天,因为现在西安的疫情,西安还在隔离中,所以想为西安加加油,希望疫情早日结束。
结果
下面是我实现的两个简单的效果图
参考
谢谢这位大神(德育处主任)给的思路!!!
实现
html
<div class="card">
<p>西安加油</p>
<img src="./img/dyt.png" alt="大雁塔">
</div>
css
* {
margin: 0;
padding: 0;
}
html,
body {
position: relative;
height: 100%;
}
body {
background: #fff;
font-family: Georgia, "Times New Roman", Times, serif;
font-size: 14px;
color: #fff;
margin: 0;
padding: 0;
vertical-align: middle;
display: flex;
align-items: center;
justify-content: center;
perspective: 50vw;
perspective-origin: 50% 50%;
}
.card {
position: relative;
width: 185px;
height: 260px;
overflow: hidden;
background-image: url(./img/xianrichu.jpg);
background-repeat: no-repeat;
background-position: 50% 50%;
background-size: 110% 110%;
transform-origin: 50% 50%;
perspective: 1800px;
transform-style: preserve-3d;
border-radius: 8px;
box-shadow: 0px 10px 20px 20px rgba(0, 0, 0, 0.17);
}
.card img {
height: 40%;
position: absolute;
bottom: 5px;
left: 80px;
}
.card p {
text-align: center;
margin-top: 50px;
color: #fff700;
font-size: 20px;
}
静态效果
在HTML中写上上面的代码效果如下:
js(重点)
- 引入animejs
<script src="./js/anime.min.js"></script>
- 编写js
let clientWidth = document.body.clientWidth;
let clientHeight = document.body.clientHeight;
document.onmousemove = function (e) {
e = e || window.event;
let movex = 0;
let movey = 0;
if (e.pageX || e.pageY) {
movex = e.pageX;
movey = e.pageY
}
anime({
targets: '.card',
translateX: movex / 30 - 20,
translateY: movey / 30 - 20,
rotateX: (movey > clientHeight / 2 ? -1 : 1) * 5 + 'deg',
rotateY: (movex > clientWidth / 2 ? 1 : -1) * 5 + 'deg',
duration: 1000,
easing: 'easeOutCirc'
});
anime({
targets: '.card img',
translateX: (movex - clientWidth / 2) / 30,
translateY: (movey - clientHeight / 2) / 30,
duration: 1000,
easing: 'easeOutCirc'
});
anime({
targets: '.card p',
translateX: (movex - clientWidth / 2) / 30,
translateY: (movey - clientHeight / 2) / 30,
duration: 1000,
easing: 'easeOutCirc'
});
}
这样就可以实现了!
创新
通过上面的代码编写,我们只是实现了PC端,鼠标滑动时的动态效果,于是我先手机和pad上怎么办了?
- 答案: 手机有陀螺仪
说干就干,话不多说,先看图
参考
手机实现
html
因为不好测试,我自己写了一个简单的工具:
<div class="tool">
<p>左右:<span id="alpha">0</span>
</p>
<p>前后:<span id="beta">0</span>
</p>
<p>扭转:<span id="gamma">0</span>
</p>
</div>
css
.tool {
position: absolute;
top: 0;
left: 0;
background: rebeccapurple;
display: none;
}
@media screen and (max-width: 400px) {
.tool {
display: block;
}
}
js
// 获取手机陀螺仪
var updateGravity = function (event) {
let x = Math.ceil(event.alpha * 100) / 100;
let y = Math.ceil(event.beta * 100) / 100;
let z = Math.ceil(event.gamma * 100) / 100;
document.getElementById("alpha").innerHTML = x;
document.getElementById("beta").innerHTML = y;
document.getElementById("gamma").innerHTML = z;
anime({
targets: '.card',
rotateX: (y > 0 ? 1 : -1) * 5 + 'deg',
rotateY: (z > 0 ? 1 : -1) * 5 + 'deg',
duration: 1000,
easing: 'easeOutCirc'
});
anime({
targets: '.card img',
translateX: z % 180 / 5,
translateY: y / 10,
duration: 1000,
easing: 'easeOutCirc'
});
anime({
targets: '.card p',
translateX: z % 180 / 5,
translateY: y / 10,
duration: 1000,
easing: 'easeOutCirc'
});
};
// 监听 window 的 deviceorientation 事件
window.addEventListener('deviceorientation', updateGravity, false);
调试
结果
重点
手机陀螺仪需要https环境,本地可以修改host解决
优化
增加红灯笼
因为是过年,想增加过年的气氛,所以增加了红灯笼,红灯笼的代码如下:
anime({
targets: ['.deng', '.shui-a', '.shui-b', '.shui-c'],
rotate: ['0deg', '10deg', '-10deg'],
duration: 3000,
loop: true,
easing: 'easeInOutQuad'
});
推荐
日常开发中很少直接用原生的方式去实现视差效果的。
这里推荐一个 轻量JS动画库:『Anime.js』
这个库的用法太简单了,直接看 《官方文档》 就知道怎么用了,本文不进行讲解。