目录
1. 背景
2. 分析
3. 代码实现
1. 背景
最近在项目中发现一个有意思的小需求,鼠标移入一个盒子里,然后盒子里的图就开始动起来,就像一个gif一样,然后鼠标移出,再按照原来的变化变回去,就像变形金刚一样,首先鼠标移入从车变成机器人,鼠标移出然后从机器人变回车。
2. 分析
实现这样一个需求的前提是,UI需要给你提供这样一张图,这个图是由多个连续的画面一起构成的一张图,如下这张我在网上随便找的图。其实这是一张图,只不过这张图由很多连贯的图一起组成的,当我们将各个独立的画面移动到可视窗口时,那么看起来就像是一个动态图一样。
然后我们来分析如何实现,首先我们要有一个div,然后设置这个div的background为这张图片,假设这个div宽150px,这张图宽1500px,那么浏览器呢就会默认显示这张图的前150px,也就是将这张图的最左端显示在div上。那么我们的可视窗口就是这150px,看到的就是这张图里的第一个小图。然后我们通过js的循环计时器setInterval来动态改变这个图的backgroundPositionX,如果UI提供的图是竖直的,那么就动态改变backGroundPositionY。
3. 代码实现
HTML&&CSS
<template>
<div class="container">
<div
class="imgContainer"
@mouseenter="handleMouseEnter"
@mouseleave="handleMouseLeave"
>
<div class="img" ref="imgRef"></div>
</div>
</div>
</template>
<style scoped>
.container {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.imgContainer {
width: 150px;
height: 300px;
}
.img {
width: 100%;
height: 100%;
background: red;
background: url("@/assets/lotsImg.png");
background-position: 0 0;
}
</style>
js部分:
在mouseEnter函数中,我们先设置循环定时器,然后在interValFun里设置具体逻辑,这里的"if(num< 12)"要根据UI提供的图片自己来设定,因为我找的这个图一共有12个小图所以是12,然后具体的"-${num * 136}px"这里具体要乘以多少也要根据图片的渲染大小来计算。如下图, 1636 / 12 约等于 136,所以我设置的136px。
在mouseLeave函数中,首先先清楚之前的定时器,然后获取当前图片的backGroundPositionX值,然后如果这个值小于等于0,就一直重复的更新backGroundPositionX值,如果大于了0,说明这个图的位置已经来到了最左端了,就可以不用再计算了,就清除这个定时器。
import { ref } from "vue";
const imgRef = ref(null);
const interval = ref(null);
function handleMouseEnter() {
interval.value = setInterval(interValFun, 80);
let num = 0;
function interValFun() {
num++;
if (num < 12) {
imgRef.value.style.backgroundPositionX = `-${num * 136}px`;
}
}
}
function handleMouseLeave() {
clearInterval(interval.value);
let currentPosition = parseFloat(imgRef.value.style.backgroundPositionX);
const interValConst = setInterval(interValFun, 80);
function interValFun() {
if (currentPosition <= 0) {
imgRef.value.style.backgroundPositionX = `${currentPosition}px`;
} else {
clearInterval(interValConst);
return;
}
currentPosition = currentPosition + 136;
}
}
最后实现的效果如图:
动态图例子