使用css制作动态壁纸
In the previous article I demonstrated how to make an element rotate to follow the position of a cursor or a touch on the screen. At the time, I explained that the technique was not necessarily limited to a single element: in this article, I'll show how to apply the code to two elements simultaneously, in the form of eyes that follow the mouse / touch position; you can also see the code at the associated CodePen demo.
在上一篇文章中,我演示了如何使元素旋转以跟随光标或屏幕上的触摸的位置 。 当时,我解释了该技术并不一定局限于单个元素:在本文中,我将展示如何以跟随鼠标/触摸位置的眼睛的形式将代码同时应用于两个元素。 您还可以在相关的CodePen演示中查看代码。
做鬼脸 (Making Faces)
First, we need to create the smiley face itself. While we could use SVG to create the shapes, it's about the same amount of effort to do so in HTML & CSS… and since the pupils will be HTML elements anyway, it makes sense to create the rest of the face in markup:
首先,我们需要创建笑脸本身。 尽管我们可以使用SVG来创建形状,但在HTML和CSS中所做的工作量几乎相同……而且由于学生还是将是HTML元素,因此在标记中创建脸部其余部分是有意义的:
<div id="face">
<div class="left eye">
<div class="pupil"></div>
</div>
<div class="right eye">
<div class="pupil"></div>
</div>
<div id="mouth"></div>
</div>
To make the face responsive, I've measured it using vw
units. (For the demo above, I've also restricted the max height and width).
为了使面部敏感 ,我使用vw
单位对其进行了测量。 (对于上面的演示,我还限制了最大高度和宽度)。
div#face {
width: 40vw;
height: 40vw;
max-width: 400px;
max-height: 400px;
margin: 0 auto;
position: relative;
background: yellow;
margin-top: 2rem;
}
All the elements are rounded using border-radius
:
所有元素都使用border-radius
进行四舍五入:
div#face, div#face * { border-radius: 50%; }
The eyes are absolute
positioned inside the face:
眼睛absolute
位于面部内部:
.eye {
width: 25%;
height: 25%;
background: #fff;
position: absolute;
top: 20%;
}
.left.eye { left: 20%; }
.right.eye { right: 20%; }
The pupils are positioned as classes inside the eyes, with their transform-origin
set at the bottom center of each circle:
将瞳Kong作为类放置在眼睛内部,其transform-origin
设置在每个圆的底部中心:
.pupil {
background: #000;
width: 50%;
height: 50%;
position: relative;
left: 25%;
transform-origin: bottom;
}
The “mouth” is an oval with a border only on the bottom edge:
“嘴”是一个椭圆形,仅在底部边缘带有边框:
#mouth {
position: relative;
width: 60%;
left: 20%;
height: 25%;
border: 1vw solid transparent;
border-radius: 50%;
top: 50%;
border-bottom-color: #000;
}
使事情变得愚蠢 (Making Things Go Googly)
The pupil elements are gathered together in a nodelist, and their centers of rotation written as properties of each:
瞳Kong元素聚集在一个节点列表中,它们的旋转中心写为每个属性 :
var pupils = document.querySelectorAll(".pupil");
for (var i = 0; i < pupils.length; i++) {
var offset = pupils[i].getBoundingClientRect();
pupils[i]['centerX'] = offset.left + offset.width/2,
pupils[i]['centerY'] = offset.bottom;
}
The alternative technique shown in the previous article, of reading the element's transformOrigin
, could also be used here.
上一篇文章中显示的另一种技术,即读取元素的transformOrigin
,也可以在这里使用。
Three events will trigger goGoogly
, the function that moves the eyes:
三个事件将触发goGoogly
,该函数可移动眼睛:
window.addEventListener('mousemove', goGoogly);
window.addEventListener('touchstart', goGoogly);
window.addEventListener('touchmove', goGoogly);
Under normal circumstances (and in the demo above) the code for touch
events would be restricted to the area immediately around the face; using the entire window for those events would mean that the use could not scroll or otherwise interact with the page.
在正常情况下(和上面的演示中),用于touch
事件的代码将被限制在面部周围的区域; 将整个窗口用于这些事件将意味着用户无法滚动或与页面进行交互。
The function itself:
函数本身:
function goGoogly(e) {
var pointerEvent = e;
if (e.targetTouches && e.targetTouches[0]) {
e.preventDefault();
pointerEvent = e.targetTouches[0];
mouseX = pointerEvent.pageX + window.pageXOffset;
mouseY = pointerEvent.pageY + window.pageYOffset;
} else {
mouseX = e.clientX + window.pageXOffset,
mouseY = e.clientY + window.pageYOffset;
}
for (var i = 0; i < pupils.length; i++) {
pupils[i]['radians'] = Math.atan2(mouseX - pupils[i]['centerX'], mouseY - pupils[i]['centerY']),
pupils[i]['degree'] = (pupils[i]['radians'] * (180 / Math.PI) * -1);
pupils[i].style.transform = 'rotate('+ (pupils[i]['degree'] + 180) + 'deg)';
}
}
This code is similar to the previous example, with the following exceptions:
这段代码与前面的示例相似,但有以下例外:
the code loops through the
pupils
array to affect each element.码循环通过
pupils
阵列以影响每个元素。the calculation used for a single element in the previous example is now applied to
multiple elements
.现在,先前示例中用于单个元素的计算将应用于
multiple elements
。
As you can see, the code works to rotate the individual eyes to their own orientation, each pointing to the current position of the cursor.
如您所见,该代码可将每只眼睛旋转到自己的方向,每只眼睛都指向光标的当前位置。
进一步发展 (Taking Things Further)
![](https://i-blog.csdnimg.cn/blog_migrate/5d5d0df700fb09901f8214a9629f6241.png)
It's entirely possible to take this much further, as demonstrated in this wonderful demo by Adult Swim on CodePen, which uses xEyes to rotate the pupils into position.
这是完全可能的,正如成人游泳在CodePen上进行的精彩演示所展示的那样, 该演示使用xEyes将学生旋转到适当的位置。
翻译自: https://thenewcode.com/1127/Make-a-CSS-Smiley-Face-with-Dynamic-Googly-Eyes
使用css制作动态壁纸