在逛codepen的时候,发现一个很不错背景移动的动画效果:
从上面图片所示的效果可以看到,当鼠标移动到图片区域的时候图片会跟随鼠标在图片上移动的范围有一个移动的视差动画效果。看了下源码不是很复杂,下面就来简单的分析下它的实现原理。
结构和样式就不阐述来,可以点击下面的链接去查看。
javascript
代码准备
首先是做一个基本的准备:
// 初始化鼠标的x和y的坐标
var mousePos = {
x: -10,
y: -10
};
// 选择图片所在的节点元素并缓存起来
var boxElements = document.getElementsByClassName('box');
// 把所有的图片节点存入一个名为 boxes 的数组,以及它的位置信息比如宽等尺寸信息
var boxes = [];
for (var i = 0; i < boxElements.length; i++) {
boxes.push({
el: boxElements[i],
targetX: 0,
targetY: 0,
prevX: 0,
prevY: 0,
x: 0,
y: 0,
left: boxElements[i].offsetLeft,
top: boxElements[i].offsetTop,
size: boxElements[i].offsetWidth
})
}
function mousemove(e) {
// 实时监听鼠标的坐标位置
mousePos.x = e.pageX;
mousePos.y = e.pageY;
}
具体代码的功能都写在注释里了。
监听并实时更新获取鼠标的位置信息
function updateBox(box) {
// 检测鼠标是否在图片所在的元素区域内,这里主要是使用鼠标的位置和图片元素区域与浏览器左边距离的对比来判断,如果大于则表示鼠标是在元素区域内,则触发鼠标的hover事件
if (mousePos.x > box.left && mousePos.x < (box.left+box.size) &&
mousePos.y > box.top && mousePos.y < (box.top+box.size)) {
// 下面代码是用来获取鼠标在图片区域中心点到图片边界的距离的值
box.targetX = (box.size/2 - (mousePos.x - box.left)) * 0.1;
box.targetY = (box.size/2 - (mousePos.y - box.top)) * 0.1;
} else {
// 如果鼠标不再图片区域内,则设为0
box.targetX = 0;
box.targetY = 0;
}
// 获取lerping 效果所需要的值,详细分析可以去下面的链接看看
// http://codepen.io/rachsmith/post/animation-tip-lerp
box.x += (box.targetX - box.x)*0.2;
box.y += (box.targetY - box.y)*0.2;
// 检测box.x的值的绝对值,是否大于.001,
if(Math.abs(box.x) < .001) box.x = 0;
if(Math.abs(box.y) < .001) box.y = 0;
// 由于视差滚动效果是使用css的transform来实现,所以要实时更新图片的transform的值
if (box.prevX !== box.x && box.prevY !== box.y)
box.el.children[0].children[0].style.transform = 'translate3d('+box.x+'px, '+box.y+'px, 0)';
}
// 每次更新的时候,缓存一次
box.prevX = box.x;
box.prevY = box.y;
}
循环
function loop() {
for (var i = 0, l = boxes.length; i < l; i++) {
updateBox(boxes[i]);
}
requestAnimationFrame(loop);
}
loop 方法中使用了 requestAnimationFrame方法来不断根据鼠标位置信息来更新图片的transform的值,从而达到视差移动的动画效果。
详细代码可以查看链接。