眼球根据鼠标相对眼睛角度的不同以及距离的不同移动而移动。
这里涉及到三角函数的问题,因为我们不仅需要让眼球与鼠标方向相同,还要让眼球收放自如。也就是眼球与眼睛里可以任意移动,而不是单一的在眼睛边上旋转。因此不会只是求出角度然后transform:rotate就能解决的,需要具体计算眼珠相对眼睛中心的x,y(直角三角形中对边与临边)。
这其实相当于一道三角函数数学题。已知眼睛中心到鼠标的 x0、y0的距离,求出与该鼠标相同弧度的眼球的位置x1、y1。对于眼珠半径的话是一个变量随着鼠标的半径变化为变化。幸运的是我们不需要太多的运算,计算机会帮我们处理他们。
提示已知x0,y0可以求出夹脚的弧度和半径;已知弧度和半径可以求出x1, y1.
弧度:园的周期为2π 360°,1π相当于180deg,如果需要的话转换公式如下
- 角度 = 180° × 弧度 ÷ π
- 弧度 = 角度 × π ÷ 180°
步骤
- 求弧度 Math.atan2()传入x0,y0轴返回弧度。
Math.atan2(point_x, point_y);
- 勾股定理求半径(半径及代表直线距离,如果你不希望眼球的半径被固定的话。眼球的半径相对于鼠标的半径按比例变化)
function radius(pos) {
return Math.sqrt(Math.pow(pos.x, 2) + Math.pow(pos.y, 2));
}
- 求出:sin,cos ,对应的:对边/斜边,临边/斜边 ,参数传入弧度,返回边的比值,与半径(斜边)相乘即可,即可得到对应的x1,y1。
function pos_xy(radius, radian) {
return {
x: Math.sin(radian) * radius,
y: Math.cos(radian) * radius,
}
}
注意:这里传入的半径是鼠标的半径,将鼠标半径除以一个固定的值从而达到随着鼠标的半径变化,眼球半径不断变化,进而计算出的不同x1、y1.
下面这段代码是将鼠标半径/15,并控制了眼球最大的可以移动半径。
Math.min(eye_ball_canMove_max, point_radius / 15)
源码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Js动画</title>
<style>
#eyes {
width: 100px;
height: 100px;
border-radius: 50%;
border: 5px solid rgb(182, 221, 41);
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
#eye-ball {
border-radius: 50%;
background-color: black;
height: 25px;
width: 25px;
position: absolute;
transition: .1s;
}
</style>
</head>
<body>
<div id="eyes">
<div id="eye-ball"></div>
</div>
</body>
<script>
var eyes, eye_ball, eyes_L, eye_T, eye_ball_L, eye_ball_T;
eyes = document.getElementById('eyes');//眼睛
eye_ball = document.getElementById('eye-ball');//眼球
eyes_L = eyes.offsetLeft - eyes.offsetWidth / 2;//眼睛中心位置
eyes_T = eyes.offsetTop - eyes.offsetHeight / 2;
eye_ball_L = eye_ball.offsetLeft - eye_ball.offsetWidth / 2;//眼球中心位置
eye_ball_T = eye_ball.offsetTop - eye_ball.offsetHeight / 2;
addEventListener('mousemove', function(e) {
var e = e || window.event;
let point_y, point_x, point_radius, point_radian, eye_ball_pos, eye_ball_canMove_max;
//计算眼珠可移动的的最大半径范围
eye_ball_canMove_max = eyes.clientWidth / 2 - eye_ball.offsetWidth / 2;
[point_y ,point_x ]=[e.clientY - eyes_T,e.clientX - eyes_L];
point_radius = Math.floor(radius({
x: point_x,
y: point_y
}));
point_radian = Math.atan2(point_x, point_y);
//计算眼球的位置,眼球半径随着鼠标与眼睛中心的半径以的1:15的变化率变化,不得超过出眼睛,限制最小值
eye_ball_pos = pos_xy(Math.min(eye_ball_canMove_max, point_radius / 15), point_radian);
eye_ball.style.cssText = `left:${eye_ball_pos.x+eye_ball_canMove_max}px;
top: ${eye_ball_pos.y+eye_ball_canMove_max}px;`;
},false)
//传入半径,弧度.计算x,y坐标
function pos_xy(radius, radian) {
return {
x: Math.sin(radian) * radius,
y: Math.cos(radian) * radius,
}
}
// 勾股定理计算半径
function radius(pos) {
return Math.sqrt(Math.pow(pos.x, 2) + Math.pow(pos.y, 2));
}
</script>
</html>
``