基础准备工
写一个div,让它跟随鼠标移动而移动
const point = document.querySelector('#point') as HTMLDivElement;
const mouseMove = (e: MouseEvent)=>{
const { clientX, clientY } = e
point.style.left = clientX - point.offsetWidth / 2 + 'px'
point.style.top = clientY - point.offsetHeight / 2 + 'px'
}
window.addEventListener('mousemove', mouseMove)
<body>
<div id="point"></div>
</body>
body {
background-image: url(../assets/image/indexBackgroundImage.jpeg);
background-repeat: no-repeat;
background-size: cover;
background-position: center;
#point {
width: 16px;
height: 16px;
border-radius: 100%;
border: 3px solid #fff;
position: fixed;
left: 10px;
top: 10px;
box-shadow: #fff 0px 0px 8px;
user-select: none;
}
}
大概就是这样的一个样式
添加点击效果
给window添加一个点击事件,并创建一个烟花
const onClick = (e: MouseEvent) => {
const { clientX, clientY } = e
const mouse = new Vector2(clientX, clientY)
const div = createDiv(mouse)
document.body.appendChild(div)
}
createDiv
方法
const createDiv = (v: Vector2) => {
const div: HTMLDivElement = document.createElement('div');
// 添加一个类名,在style.less中写上公共样式
div.classList.add('fieworks')
// 颜色随机
div.style.background = randomColor()
// 位置为鼠标所在位置
div.style.left = v.x + 'px'
div.style.top = v.y + 'px'
return div
}
randomColor
方法用来获取随机颜色
const r = Math.floor(Math.random() * 255);
const g = Math.floor(Math.random() * 255);
const b = Math.floor(Math.random() * 255);
return `rgb(${r},${g},${b})`
计算烟花消失的位置
烟花向下做抛物线运动,起点为鼠标点击的位置,结束点要通过计算,算出相应的位置,首先写一个随机数,介于两个数值之间返回一个随机数
export function getRandomArbitrary(min: number, max: number): number {
return Math.random() * (max - min) + min;
}
结束坐标基于鼠标坐标,向外扩散
const end = mouse.clone()
.setX(mouse.x + getRandomArbitrary(-width, width))
.setY(mouse.y + getRandomArbitrary(-height, height))
动画
加入动画之前,先把点位创建出来,数量随机
for (let i = 0; i < getRandomArbitrary(100, 1000); i++) {
const end = mouse.clone()
.setX(mouse.x + getRandomArbitrary(-width, width))
.setY(mouse.y + getRandomArbitrary(-height, height))
const div = createDiv(mouse)
document.body.appendChild(div)
changeFireworks(div, mouse, end,getRandomArbitrary(1, 2))
}
定义一个changeFireworks
方法,接受四个参数,移动的元素
,起点坐标
,终点坐标
,执行时间
,在方法内调用new TWEEN
方法
/**
*
* @param element 移动的元素
* @param s 起点坐标
* @param e 终点坐标
* @param time 执行时间
*/
const changeFireworks = (element: any, s: Vector2, e: Vector2, time = 1) => {
new TWEEN.Tween(s)
.to(e, time * 1000)
.start()
// .easing(TWEEN.Easing.Linear.None)
.easing(TWEEN.Easing.Back.InOut) // 运动动画方式
.onUpdate((v: any) => { // 更新时的回调
const { x, y } = v
element.style.left = x + 'px'
element.style.top = y + 'px'
})
.onComplete(() => { // 结束的回调
element.parentNode.removeChild(element)
})
}
更新动画
定义一个自调用函数,在该函数内调用TWEEN && TWEEN.update()
,并且时候循环动画requestAnimationFrame
来继续调用animate
方法,比传统的setInterval性能提升不止一点点,感兴趣的同学可以研究研究
(function animate() {
requestAnimationFrame(animate);
TWEEN && TWEEN.update()
})()
window.requestAnimationFrame()
告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。该方法需要传入一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前执行
tween中easing
方法可以传入不同的运动效果,tween内置了许多运动模式
效果
源码
历史文章
# three.js 打造游戏小场景(拾取武器、领取任务、刷怪)