一、效果图
先上效果图
二、前言
通过实现图片跟随鼠标的移动而旋转,使用JS实现3D模型的旋转效果。
**原理:**就是通过鼠标事件和鼠标定位,鼠标位置的不断改变,通过计算属性来不断地切换图片。
三、代码实现
1、编写一个容器包裹着图片,并给容器添加鼠标监听事件
<div @mousemove="onMouseMove" id="animationContainer" ref="container">
<img :src="currentImageSrc" id="animatedImage" />
<div class="imgName">{{ currentImageSrc }}</div>
</div>
2、让容器全屏,并添加定位,让图片居中。
绝对定位,让图片在容器中居中对齐样式
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
#animationContainer {
width: 100vw;
height: 100vh;
background-color: #75aabb;
position: relative;
overflow: hidden;
cursor: pointer;
}
#animatedImage {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.imgName{
position: absolute;
top: 75%;
left: 50%;
transform: translate(-50%, -50%);
}
3、引入vue的ref和computed和定义参数
import { ref, computed } from 'vue'
const totalFrames = 360 //图片总数
const imagePrefix = '1_0' //图片的前缀名,完整的名称为1_0001.jpg 1_0025.jpg 1_0164.jpg
const imageExtension = '.jpg' //图片后缀名
const animationSpeed = 100 // 调整这个值以控制动画速度
const maxAngle = 30 // 最大角度(可根据需求调整)
const currentFrame = ref(1)
const mouseX = ref(0)
const containerWidth = ref(0)
let animationInterval
let container = ref()
let frameToShow = ref(1)
4、添加鼠标的监听事件
getBoundingClientRect() 方法返回元素的大小及其相对于视口的位置。
event.clientX 以浏览器窗口左上顶角为原点,定位 x 轴坐标。
// 监听鼠标位置变化
const onMouseMove = (event) => {
const containerRect = container.value.getBoundingClientRect()
mouseX.value = event.clientX - containerRect.left
containerWidth.value = containerRect.width
}
5、通过计算属性,来显示要显示的图片
const mousePercentage = mouseX.value / containerWidth.value 计算出当前的x坐标占整个容器的份数。
**// 计算角度并显示对应的图片
const currentImageSrc = computed(() => {
const mousePercentage = mouseX.value / containerWidth.value
const angle = maxAngle * (2 * mousePercentage - 1)
frameToShow.value = Math.floor(((angle / maxAngle + 1) * totalFrames) / 2) + 1
let str = frameToShow.value.toString()
if (str.length == 1) {
frameToShow.value = `00${frameToShow.value}`
} else if (str.length == 2) {
frameToShow.value = `0${frameToShow.value}`
}
if (!frameToShow.value) {
frameToShow.value = 1
let url = `${imagePrefix}00${frameToShow.value}${imageExtension}`
return new URL(`/src/components/canvas/${url}`, import.meta.url).href
} else {
let url = `${imagePrefix}${frameToShow.value}${imageExtension}`
return new URL(`/src/components/canvas/${url}`, import.meta.url).href
}
})
**
四、完整代码
<template>
<div @mousemove="onMouseMove" id="animationContainer" ref="container">
<img :src="currentImageSrc" id="animatedImage" />
<div class="imgName">{{ currentImageSrc }}</div>
</div>
</template>
<script setup>
import { ref, computed } from 'vue'
const totalFrames = 360 //图片总数
const imagePrefix = '1_0' //图片的前缀名,完整的名称为1_0001.jpg 1_0025.jpg 1_0164.jpg
const imageExtension = '.jpg' //图片后缀名
const animationSpeed = 100 // 调整这个值以控制动画速度
const maxAngle = 30 // 最大角度(可根据需求调整)
const currentFrame = ref(1)
const mouseX = ref(0)
const containerWidth = ref(0)
let animationInterval
let container = ref()
let frameToShow = ref(1)
// 监听鼠标位置变化
const onMouseMove = (event) => {
const containerRect = container.value.getBoundingClientRect()
mouseX.value = event.clientX - containerRect.left
containerWidth.value = containerRect.width
}
// 计算角度并显示对应的图片
// 通过容器的大小和鼠标的x坐标来实现图片的监听
const currentImageSrc = computed(() => {
const mousePercentage = mouseX.value / containerWidth.value
const angle = maxAngle * (2 * mousePercentage - 1)
frameToShow.value = Math.floor(((angle / maxAngle + 1) * totalFrames) / 2) + 1
let str = frameToShow.value.toString()
if (str.length == 1) {
frameToShow.value = `00${frameToShow.value}`
} else if (str.length == 2) {
frameToShow.value = `0${frameToShow.value}`
}
if (!frameToShow.value) {
frameToShow.value = 1
let url = `${imagePrefix}00${frameToShow.value}${imageExtension}`
return new URL(`/src/components/canvas/${url}`, import.meta.url).href
} else {
console.log(frameToShow.value)
let url = `${imagePrefix}${frameToShow.value}${imageExtension}`
return new URL(`/src/components/canvas/${url}`, import.meta.url).href
}
})
</script>
<style>
#animationContainer {
width: 100vw;
height: 100vh;
background-color: #75aabb;
position: relative;
overflow: hidden;
cursor: pointer;
}
#animatedImage {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.imgName{
position: absolute;
top: 75%;
left: 50%;
transform: translate(-50%, -50%);
}
</style>