我试图使SVG的眼睛瞳孔跟随光标使用本教程:
https://dev.to/anomaly3108/make-svg-follow-cursor-using-css-and-js-2okp
我们有4个分区:
1.眼球_左侧
1.眼球_右侧
1.瞳孔_左侧
1.瞳孔_右侧
看起来js起作用了,但是Angular 不是很准确。学生们走得太高了,他们没有停留在正确的位置。
let eyeball_left = document.querySelector("#eyeball_left"),
pupil_left = document.querySelector("#pupil_left"),
eyeArea_left = eyeball_left.getBoundingClientRect(),
pupil_leftArea = pupil_left.getBoundingClientRect(),
R_left = eyeArea_left.width / 2,
r_left = pupil_leftArea.width / 2,
centerX_left = eyeArea_left.left + R_left,
centerY_left = eyeArea_left.top + R_left;
console.log(centerX_left)
console.log(centerY_left)
let eyeball_right = document.querySelector("#eyeball_right"),
pupil_right = document.querySelector("#pupil_right"),
eyeArea_right = eyeball_right.getBoundingClientRect(),
pupil_rightArea = pupil_right.getBoundingClientRect(),
R_right = eyeArea_right.width / 2,
r_right = pupil_rightArea.width / 2,
centerX_right = eyeArea_right.left + R_right,
centerY_right = eyeArea_right.top + R_right;
console.log(centerX_right)
console.log(centerY_right)
document.addEventListener("mousemove", (e) => {
let x_left = e.clientX - centerX_left,
y_left = e.clientY - centerY_left,
theta_left = Math.atan2(y_left, x_left),
angle_left = (theta_left * 180) / Math.PI + 360;
let x_right = e.clientX - centerX_right,
y_right = e.clientY - centerY_right,
theta_right = Math.atan2(y_right, x_right),
angle_right = (theta_right * 180) / Math.PI + 360;
pupil_left.style.transform = `translateX(${
R_left - r_left + "px"
}) rotate(${angle_left + "deg"})`;
pupil_left.style.transformOrigin = `${r_left + "px"} center`;
pupil_right.style.transform = `translateX(${
R_right - r_right + "px"
}) rotate(${angle_right + "deg"})`;
pupil_right.style.transformOrigin = `${r_right + "px"} center`;
});
#monster {
height: 100px;
width: 400px;
}
<div id="monster">
<svg xmlns="http://www.w3.org/2000/svg" data-name="Layer 1" viewBox="168.88 0 290.9 400.77">
<g>
<title>Layer 1</title>
<path
id="svg_1"
fill="#6c63ff"
d="m296.30999,388.65991l0,-67.88825l-22,0l0,67.88825a13.98286,13.98286 0 0 0 -7,12.11175l36,0a13.98286,13.98286 0 0 0 -7,-12.11175z"
/>
<path
id="svg_2"
fill="#6c63ff"
d="m355.30999,388.65991l0,-67.88825l-22,0l0,67.88825a13.98286,13.98286 0 0 0 -7,12.11175l36,0a13.98286,13.98286 0 0 0 -7,-12.11175z"
/>
<circle
id="svg_3"
fill="#6c63ff"
r="145.45113"
cy="238.54887"
cx="314.33362"
/>
<ellipse
id="svg_4"
fill="#fff"
ry="19.21053"
rx="57.63158"
cy="311.43609"
cx="314.33362"
/>
<circle
id="svg_5"
fill="#fff"
r="24.69925"
cy="205.61654"
cx="262.19076"
/>
<circle
id="svg_6"
fill="#fff"
r="24.69925"
cy="205.61654"
cx="366.47648"
/>
{/* eyebol */}
<circle
id="eyeball_left"
fill="#3f3d56"
r="19.21053"
cy="205.31579"
cx="262.67948"
/>
<circle
id="eyeball_right"
fill="#3f3d56"
r="19.21053"
cy="205.31579"
cx="366.73212"
/>
{/* eyebol */}
<ellipse
id="svg_9"
fill="#3f3d56"
ry="74.09774"
rx="96.05263"
cy="87.09774"
cx="314.33362"
/>
<ellipse
id="svg_10"
fill="#3f3d56"
ry="18"
rx="38"
cy="18"
cx="314.33362"
/>
<path
id="svg_11"
fill="#3f3d56"
d="m315.39428,259.75517c6.323,-6.40629 16.04713,-6.53419 24.2561,-4.42458c9.786,2.51489 18.116,8.57423 27.17791,12.79851a49.55555,49.55555 0 0 0 14.58024,4.54776a38.27945,38.27945 0 0 0 36.63871,-17.0858a38.7584,38.7584 0 0 0 4.54212,-30.91717a1.50128,1.50128 0 0 0 -2.89283,0.79752a35.70693,35.70693 0 0 1 -3.34417,27.11259a35.29669,35.29669 0 0 1 -35.30417,17.03843a49.62651,49.62651 0 0 1 -14.22886,-4.81212c-8.76148,-4.28973 -16.98465,-10.00419 -26.54935,-12.41745c-9.21411,-2.32481 -19.9481,-1.90083 -26.997,5.241c-1.35753,1.37543 0.76245,3.4981 2.12132,2.12132l-0.00002,-0.00001z"
/>
<path
id="svg_12"
fill="#3f3d56"
d="m315.39428,257.63384c-6.22928,-6.31139 -15.3898,-7.36984 -23.77027,-5.92682c-9.6154,1.65567 -17.88675,6.88869 -26.379,11.36988c-8.6772,4.57879 -17.92825,8.08187 -27.8912,6.48578a35.20905,35.20905 0 0 1 -23.1751,-14.039a35.77653,35.77653 0 0 1 -5.208,-30.05228a1.50128,1.50128 0 0 0 -2.89283,-0.79752a38.80889,38.80889 0 0 0 2.82291,27.89016a37.47231,37.47231 0 0 0 20.97865,18.1838c9.41409,3.348 19.35061,2.63 28.52089,-1.11613c9.42621,-3.85066 17.77515,-10.13661 27.45644,-13.36827c8.93708,-2.98324 20.2603,-3.75844 27.41619,3.49176c1.3583,1.37619 3.47944,-0.7453 2.12132,-2.12132l0,-0.00004z"
/>
<circle
id="svg_13"
fill="#3f3d56"
r="11"
cy="258.5"
cx="314.36371"
/>
{/* PUPIL */}
<circle
id="pupil_left"
fill="#fff"
r="4"
cy="198.77165"
cx="254.31"
/>
<circle
id="pupil_right"
fill="#fff"
r="4"
cy="198.77165"
cx="376.31"
/>
{/* PUPIL */}
</g>
</svg>
2条答案
按热度按时间o4tp2gmn1#
这里的基本思想是,我使用一个线元素来决定眼睛的旋转/方向。一条线可以在两端和中间有一个标记。在这个例子中,眼球是一个标记,然后我根据鼠标的位置更新线的末端。
首先是一个带有轮廓的简单示例,然后是完整示例:
一个一个二个一个一个一个三个一个一个一个一个一个四个一个
f0brbegy2#
备选方案:更新
<circle>
cx
和cy
属性这种方法需要计算
1.光标坐标和眼球中心之间的Angular
1.圆上的新点位置(基于Angular 、半径
演示示例
上面的脚本可以通过使用类"eye"将所有眼球和瞳孔 Package 在一个组中来应用,如下所示:
就像@chrwahl的示例一样,我们需要将HTML DOM坐标转换为SVG用户单位。
计算Angular
微调眼球区域内的瞳孔定位
计算光标和眼球中心之间的距离,允许我们进一步调整瞳孔运动:如果光标在眼球内,瞳孔将以当前鼠标坐标为中心。
圆上的点
由于我们希望圆形被放置在眼球的边界内,因此我们需要使用一个减小的半径来进行计算(根据瞳孔的半径)。