前段时间自己写过一个查看不同颜色得分的小游戏,随着点击次数的增多,元素会越来越多,所以后来决定用cavans实现一下,效果如下:
1. 首先创建一个canvas
<div id="grend">
得分:
<span id="count">0</span>
</div>
<canvas id="canvas" width="400" height="400"></canvas>
2. 创建一个类并设置初始值,
class CanvasDraw {
constructor() {
this.lineCount = 2 //每行的个数
this.colorNumber = 0xFFFFFF + 1
this.index = 0
this.canvas = document.getElementById('canvas')
this.count = document.getElementById('count')
this.width = (this.canvas.offsetWidth - (this.lineCount - 1) * 3) / this.lineCount //每个的宽度,每个块之间有3px的间隔
}
//点击错误之后清除并重新开始
clear() {
this.canvas.getContext('2d').clearRect(0, 0, 400, 400)
}
//点击成功之后个数增加,并计算对应的宽度与当前得分
next() {
this.lineCount++
this.width = (this.canvas.offsetWidth - (this.lineCount - 1) * 3) / this.lineCount
this.count.innerHTML = +this.count.innerHTML + 10
this.draw()
}
}
3. 创建一个绘制的函数
随机生成一个不同的块,并设置差距在0x0f0f0f的颜色,并绘制到canvas上
draw() {
const context = canvas.getContext('2d')
const count = this.lineCount ** 2,
randomIndex = Math.random() * count | 0,
randomColor = this.colorNumber * Math.random() | 0,
specialColor = randomColor - 0x0f0f0f > 0? randomColor - 0x0f0f0: randomColor + 0x0f0f0f
this.index = randomIndex
for(let i = 0; i < count; i++) {
context.fillStyle = '#' + (i === randomIndex? specialColor.toString(16).padStart(6, 0): randomColor.toString(16).padStart(6, 0))
context.fillRect((this.width + 3) * (i % this.lineCount), (this.width + 3) * ((i / this.lineCount) | 0), this.width, this.width)
}
}
4. 点击canvas的逻辑
判断点击时的位置是不是特殊的块的位置,正确的时候下一步,不正确的话重新开始
click(e) {
return new Promise((resolve, reject) => {
const { offsetX, offsetY } = e
const row = this.index / this.lineCount | 0, colomn = this.index % this.lineCount
if(offsetX >= colomn * (this.width + 3)
&& offsetX <= (colomn + 1) * (this.width + 3) - 3
&& offsetY >= row * (this.width + 3)
&& offsetY <= (row + 1) * (this.width + 3) - 3) {
resolve()
}else {
reject()
}
})
}
最终代码与实现效果
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="content-security-policy" content="策略">
<meta http-equiv="content-security-policy-report-only" content="策略">
<title>Document</title>
</head>
<style>
body {
height: 100%;
}
#container {
position: absolute;
width: 400px;
height: 400px;
border: 1px solid pink;
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-50%);
}
#grend {
text-align: center;
}
</style>
<body>
<div id="grend">
得分:
<span id="count">0</span>
</div>
<div id="container">
<canvas id="canvas" width="400" height="400"></canvas>
</div>
</body>
<script>
const container = document.getElementById('container')
class CanvasDraw {
constructor() {
this.lineCount = 2
this.colorNumber = 0xFFFFFF + 1
this.index = 0
this.canvas = document.getElementById('canvas')
this.count = document.getElementById('count')
this.width = (this.canvas.offsetWidth - (this.lineCount - 1) * 3) / this.lineCount
}
init() {
this.lineCount = 2
this.width = (this.canvas.offsetWidth - (this.lineCount - 1) * 3) / this.lineCount
this.count.innerHTML = 0
this.draw()
}
draw() {
const context = canvas.getContext('2d')
const count = this.lineCount ** 2,
randomIndex = Math.random() * count | 0,
randomColor = this.colorNumber * Math.random() | 0,
specialColor = randomColor - 0x0f0f0f > 0? randomColor - 0x0f0f0: randomColor + 0x0f0f0f
this.index = randomIndex
for(let i = 0; i < count; i++) {
context.fillStyle = '#' + (i === randomIndex? specialColor.toString(16).padStart(6, 0): randomColor.toString(16).padStart(6, 0))
context.fillRect((this.width + 3) * (i % this.lineCount), (this.width + 3) * ((i / this.lineCount) | 0), this.width, this.width)
}
}
clear() {
canvas.getContext('2d').clearRect(0, 0, 400, 400)
}
next() {
this.lineCount++
this.width = (this.canvas.offsetWidth - (this.lineCount - 1) * 3) / this.lineCount
this.count.innerHTML = +this.count.innerHTML + 10
this.draw()
}
click(e) {
return new Promise((resolve, reject) => {
const { offsetX, offsetY } = e
const row = this.index / this.lineCount | 0, colomn = this.index % this.lineCount
if(offsetX >= colomn * (this.width + 3)
&& offsetX <= (colomn + 1) * (this.width + 3) - 3
&& offsetY >= row * (this.width + 3)
&& offsetY <= (row + 1) * (this.width + 3) - 3) {
resolve()
}else {
alert('点击错误,即将重新开始')
reject()
}
})
}
}
const canvasDraw = new CanvasDraw()
canvasDraw.init()
container.addEventListener('click', (e) => {
canvasDraw.click(e).then(() => {
canvasDraw.clear()
canvasDraw.next()
}).catch(e => {
canvasDraw.clear()
canvasDraw.init()
})
})
</script>
</html>
完结撒花