前置知识
追踪鼠标位置
通过js去追踪鼠标经过按钮是的x轴和y轴的位置:
var card =document.querySelector('.card')
document.querySelector('.card').onmousemove = (e) => {
const x = e.pageX; // 鼠标位置x轴
const y = e.pageY; // 鼠标位置y轴
card.style.setProperty(...); // 设置样式
}
获取当前元素距离视窗的距离
网上查一查,有很多都是通过offsetTop、offsetLeft来计算出来的。我按照网上的查到的资料用了一次,算出来了一堆错误答案。需要注意的是scrolltop 和 offsettop 是距离父元素的。下面我要分享的这个方法,兼容性很好(ie4都ok),而且很方便,不会算错。
Element.getBoundingClientRect()
方法返回一个DOMRect 对象,是一组矩形集合,返回值主要包含left
、top
、bottom
、right
、width
、height
、x
、y
等。
使用方法如下:
let elementToTop = element.getBoundingClientRect().top // element的顶边到视口顶部的距离
let elementToLeft = element.getBoundingClientRect().left // element的左边到视口左边的距离
let elementToBottom = element.getBoundingClientRect().bottom // element的底边到视口「顶部」的距离
let elementToRight = element.getBoundingClientRect().right // element的右边到视口「左边」的距离
得到的值是相对于视口而言的,即如果页面的滚动位置发生变化,那么得到的top、left也会发生变化;如果需要计算到body边框的距离,需要再加上网页滚动条的长度。
旋转与透视属性
不了解这块儿的同学可以看一下这篇文章
需要注意的是,perspective
属性要设置在需要透视效果的元素的父元素上。
代码实现
来看一个Demo~
floatWithPoint.html
如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="./floatWithPoint.css">
</head>
</style>
<body>
<br/><br/><br/><br/><br/>
<div class="wrap">
<div class="card">Card</div>
<div class="card">Card</div>
<div class="card">Card</div>
</div>
</body>
<script type="text/javascript" src="./floatWithPoint.js"></script>
</html>
floatWithPoint.css
如下:
*{
margin: 0;
padding: 0;
}
.wrap{
perspective: 800px;
perspective-origin: center;
display: flex;
}
.card{
background-color: blanchedalmond;
width: 200px;
height: 80px;
border: 1px solid pink;
text-align: center;
color: coral;
font-size: 24px;
font-family: 'Helvetica Neue', Helvetica;
line-height: 80px;
transition: box-shadow 0.35s ease, transform 0.15s;
box-shadow: 1px 1px 10px rgba(255, 157, 157, 10%);
}
.card:hover{
transition: box-shadow 0.25s ease;
box-shadow: 4px 4px 30px 2px rgba(255, 157, 157, 0.2);
}
.card:active{
transition: box-shadow 0.25s ease;
box-shadow: 1px 1px 10px rgba(255, 157, 157, 10%);
}
floatWithPoint.js
如下:
let cards = document.querySelectorAll('.card');
cards.forEach((card) => {
var _x = card.getBoundingClientRect().left + card.offsetWidth / 2; // 目标元素的中心位置
var _y = card.getBoundingClientRect().top + card.offsetHeight / 2; // 目标元素的中心位置
card.onmousemove = (e) => {
const x = e.pageX; // 鼠标位置x轴
const y = e.pageY; // y轴
card.style.setProperty('transform', `rotateX(${-(_y - y) / 4}deg) rotateY(${-(x - _x) / 8}deg)`);
// console.log({_X: (_y-y)/4, Y: (x-_x)/8, xp: x, yp: y, _x, _y});
}
// 监听鼠标移出事件
card.onmouseout = (e) => {
card.style.setProperty('transform', `rotateX(${0}deg) rotateY(${0}deg)`);
}
})
坑
let elementToTop = element.getBoundingClientRect().top // element的顶边到视口顶部的距离
用getBoundingClientRect()
需要注意,其视口是你刷新页面时候的位置!
所以,当你滚动页面以后刷新页面,其值会发生改变!这一点不如offsetTop好使。
Comments NOTHING