使用事件监听器来创建更好的动画
如果你想超越标准的悬停、聚焦和点击动画,那你肯定看对了文章!这一切都是为了将用户输入转化为更好的动画。
事件监听器
JavaScript 中有很多事件监听器,有些你可能听说过,但大多数你可能永远都不需要或用不到。我最常用的是触摸/鼠标和滚动事件。我也在尝试理解这些devicemotion
事件,但进展不大,如果有人有什么阅读技巧,请告诉我!
在第一个例子中,我使用mouseover
事件来确定鼠标在屏幕上的位置(xy 坐标)。
示例 1 鼠标悬停时倾斜
以下是我如何在我的投资组合中运用此方法的示例:
HTML 非常简单:
<div class="skew">
<div class="skew__item">
<img src="https://pbs.twimg.com/media/BcvmxibIYAAH8a3.jpg" />
<!-- TIP: always use an image you really enjoy
looking at for codepens 😻 -->
</div>
</div>
JavaScript 变得更加复杂了:
const skewItemContainer = document.querySelector('.skew');
// Get the container element to add the mouseover
// event and css variable to
const skewItem = document.querySelector('.skew__item').getBoundingClientRect();
// getBoundingClientRect() returns an object with the
// coordinates and width, height etc of an element
const imageCenterX = skewItem.left + skewItem.width / 2;
const imageCenterY = skewItem.top + skewItem.height / 2;
// Calculating the center coordinates for the image
// Add the event to the container around the image
// (more room to mouseover == more better😎)
skewItemContainer.addEventListener("mousemove", function(e) {
// the event, e, is an object with a lot of
// information, I only use clientX and clientY
// for this animation
const clientX = e.clientX;
const clientY = e.clientY;
// Get x and y positions of the
const xCalc = (clientX - imageCenterX) * 0.000001;
// increasing 0.000001 will make the animation more pronounced
const yCalc = (clientY - imageCenterY) * 0.000001;
// Subtracting the X & Y coordinates by the image
// center ensures that the center of the image
// (where ever it may be positioned on the page) is 0, 0 🧐
skewItemContainer.style.setProperty("--x-translate", `${xCalc}`);
skewItemContainer.style.setProperty("--y-translate", `${yCalc}`);
// using setProperty to add css variables to the container element
});
好吧,我撒了个小谎,我其实没用skew()
变换函数,我用的是matrix3d()
,它能让你更好地控制。这个 matrix3d 变换非常复杂,我发现可以通过不断尝试不同的值来创建类似倾斜的效果。
.skew {
position: relative;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
// Centering the element with flexbox ❤️
background: black;
width: 100vw;
height: 100vh;
overflow: hidden;
--x-translate: 0;
--y-translate: 0;
// creating defaults for the css variables
&:hover {
.skew__item {
transform: matrix3d(1, 0, 0.00, var(--x-translate), 0.00, 1, 0.00, var(--y-translate), 0, 0, 1, 0, 0, 0, 0, 1);
// By adding the transform only on hover you
// make sure that when the user hovers out it
// will return to it's non transformed standard
// position, which saves you some code ;)
}
}
&__item {
width: 60vw;
max-width: 500px;
transition: 0.4s cubic-bezier(0.64, 0.57, 0.67, 1.53);
img {
width: 100%;
height: 100%;
object-fit: cover; // ❤️❤️❤️❤️ object-fit
}
&:hover {
transition: 0.4s ease-out;
// adding a different animation on hover than
// hover out makes animations more playful
}
}
}
示例 2 滚动时放大
以下是我如何在我的投资组合中运用此方法的示例:
我在codepen里用了三个视频,这完全没必要!在这里的代码示例中,我会演示如何只用一个视频来实现。
向我工作的公司(Matise)致以最诚挚的谢意,他们制作了这段视频并展示了视频中展示的设计。👏
<section class="scale-video">
<video class="video" autoplay muted loop playsinline src="https://cdn.matise.nl/content/uploads/2018/03/20092418/02_bbbSingleProduct.mp4"></video>
</section>
<section class="row">
<h1>Scroll!!</h1>
</section>
const videoContainer = document.querySelector('.scale-video');
const video = document.querySelector('.video');
// Create variables for the container and the video for easy access
window.addEventListener('scroll', function(e) {
let scrollY = window.scrollY / window.innerHeight * 5;
// Create a calculation to base the scale amount on
// Create min and max values for the scaling:
if (scrollY <= 0.3) {
scrollY = 0.3;
// We don't want the video to become smaller than (scale(0.3))
}
if (scrollY >= 1) {
scrollY = 1;
// We don't want the video to become bigger than (scale(1))
}
videoContainer.style.setProperty('--scale', `${ scrollY }`);
// Set css variable on the video container
});
:root {
// setting defaults can also be done on the root pseudo class
// https://tympanus.net/codrops/css_reference/root/
--scale: 0.3;
}
.scale-video {
position: relative;
display: flex;
justify-content: center;
align-items: center;
// Center the content with flexbox
width: 100vw;
box-sizing: border-box;
height: 300vh;
// The height here is quite outrageous, haha.
// It's to make sure that you have enough place
// to scroll to let the animation do its thing.
overflow: hidden;
background: black;
}
.video {
position: fixed;
top: 0;
transition: 1s ease-out;
width: 100vw;
z-index: 2;
overflow: hidden;
object-fit: cover;
transform: scale(var(--scale));
// Add the scale via css variable
}
就这些了,如果你做过类似的动画,请告诉我。我很想看看!
文章来源:https://dev.to/cydstumpel/using-event-listeners-to-create-better-animations-3c7