Html
<template>
<canvas ref="canvas"></canvas>
</template>
Ts
<script lang="ts" setup>
import {ref,onMounted} from 'vue'
interface iBall{
x:number
y:number
dx:number
dy:number
radius:number
color:string
draw:()=>void
update:()=>void
}
const canvas = ref<HTMLCanvasElement>()
let ctx:CanvasRenderingContext2D
const colors = [
'red','orange','yellow','green','cyan','blue','purple','pink'
]
const ballArr:iBall[] = []
/**
* 初始化canvas画布
*/
const initCanvas = ()=>{
ctx = canvas.value?.getContext('2d') as CanvasRenderingContext2D
canvas.value!.width = window.innerWidth
canvas.value!.height = window.innerHeight
}
/**
* 创建一个渐变背景色
*/
const createRect = ()=>{
ctx.beginPath()
console.log(canvas.value!.width,canvas.value!.height)
// let linearGradient = ctx.createLinearGradient(0,0,canvas.value!.width,canvas.value!.height)
// linearGradient.addColorStop(0,'pink')
// linearGradient.addColorStop(1,'blue')
let rw = canvas.value!.width > canvas.value!.height ? canvas.value!.width/100 : canvas.value!.height/100
let rh = canvas.value!.width > canvas.value!.height ? canvas.value!.width : canvas.value!.height
let radiaGradient = ctx.createRadialGradient(canvas.value!.width/2,canvas.value!.height/2,rw,canvas.value!.width/2,canvas.value!.height/2,rh)
radiaGradient.addColorStop(0,'#583f92')
radiaGradient.addColorStop(1,'#140c27')
ctx.fillStyle = radiaGradient
ctx.fillRect(0,0,canvas.value!.width,canvas.value!.height)
ctx.closePath()
}
/**
* 小球 类
*/
class Ball {
x:number
y:number
dx:number
dy:number
radius:number
color:string
constructor(x:number,y:number,dx:number,dy:number,radius:number,color:string){
this.x = x
this.y = y
this.dx = dx
this.dy = dy
this.radius = radius
this.color = color
}
/* 绘制 */
draw(){
ctx!.beginPath()
ctx!.fillStyle = this.color
ctx!.arc(this.x,this.y,this.radius,0,2*Math.PI)
ctx!.fill()
ctx!.closePath()
}
/* 更新 */
update(){
//判断边界,回弹
if(this.x < this.radius || this.x > canvas.value!.width - this.radius){
this.dx = -this.dx
}
if(this.y < this.radius || this.y > canvas.value!.height - this.radius){
this.dy = -this.dy
}
//运动
this.x += this.dx
this.y += this.dy
this.draw()
}
}
/**
* 初始化得到一个小球数组
*/
const initBallArr = ()=>{
for(let i=0;i<150;i++){
let radius = Math.random() * 5 + 1
let x = Math.random() * (canvas.value!.width - 2*radius) + radius
let y = Math.random() * (canvas.value!.height - 2*radius) + radius
let dx = (Math.random() - 0.5) * 2
let dy = (Math.random() - 0.5) * 2
let color = colors[Math.floor(Math.random()*9)]
ballArr.push(new Ball(x,y,dx,dy,radius,color))
}
}
/**
* 动画
*/
const animate = ()=>{
requestAnimationFrame(animate)
ctx?.clearRect(0,0,canvas.value!.width,canvas.value!.height)
createRect()
ballArr.forEach(item=>{
item.update()
})
}
/**
* 初始化
*/
const init = ()=>{
initCanvas()
initBallArr()
animate()
}
onMounted(()=>{
init()
})
</script>