theme: smartblue
基础准备工
写一个div,让它跟随鼠标移动而移动
typescript 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)
html <body> <div id="point"></div> </body>
```less 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添加一个点击事件,并创建一个烟花
```typescript const onClick = (e: MouseEvent) => { const { clientX, clientY } = e
const mouse = new Vector2(clientX, clientY)
const div = createDiv(mouse)
document.body.appendChild(div)
} ```
createDiv
方法
typescript 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
方法用来获取随机颜色
typescript 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})`
计算烟花消失的位置
烟花向下做抛物线运动,起点为鼠标点击的位置,结束点要通过计算,算出相应的位置,首先写一个随机数,介于两个数值之间返回一个随机数
```typescript export function getRandomArbitrary(min: number, max: number): number { return Math.random() * (max - min) + min; }
```
结束坐标基于鼠标坐标,向外扩散
typescript const end = mouse.clone() .setX(mouse.x + getRandomArbitrary(-width, width)) .setY(mouse.y + getRandomArbitrary(-height, height))
动画
加入动画之前,先把点位创建出来,数量随机
typescript 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
方法
typescript /** * * @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性能提升不止一点点,感兴趣的同学可以研究研究
typescript (function animate() { requestAnimationFrame(animate); TWEEN && TWEEN.update() })()
window.requestAnimationFrame()
告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。该方法需要传入一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前执行
tween中easing
方法可以传入不同的运动效果,tween内置了许多运动模式
效果
历史文章
# three.js 打造游戏小场景(拾取武器、领取任务、刷怪)