canvasClass.js
const colorPicker = document.querySelector('input')
const cvs = document.querySelector('canvas')
const ctx = cvs.getContext('2d')
function init() {
let w = 500,
h = 300
cvs.width = w * devicePixelRatio
cvs.height = h * devicePixelRatio
cvs.style.width = w + 'px'
cvs.style.height = h + 'px'
cvs.style.backgroundColor = '#ccc'
}
init()
const shapes = []
class Rectangle {
constructor(color, startX, startY) {
this.startX = startX
this.startY = startY
this.endX = startX
this.endY = startY
this.color = color
}
get minX() {
return Math.min(this.startX, this.endX)
}
get maxX() {
return Math.max(this.startX, this.endX)
}
get minY() {
return Math.min(this.startY, this.endY)
}
get maxY() {
return Math.max(this.startY, this.endY)
}
draw() {
ctx.beginPath()
ctx.moveTo(this.minX * devicePixelRatio, this.minY * devicePixelRatio)
ctx.lineTo(this.maxX * devicePixelRatio, this.minY * devicePixelRatio)
ctx.lineTo(this.maxX * devicePixelRatio, this.maxY * devicePixelRatio)
ctx.lineTo(this.minX * devicePixelRatio, this.maxY * devicePixelRatio)
ctx.lineTo(this.minX * devicePixelRatio, this.minY * devicePixelRatio)
ctx.fillStyle = this.color
ctx.fill()
ctx.strokeStryle = '#fff'
ctx.lineCap = 'square'
ctx.lineWidth = 3 * devicePixelRatio
ctx.stroke()
}
isInside(x, y) {
return x >= this.minX && x <= this.maxX && y >= this.minY && y <= this.maxY
}
}
const rest = new Rectangle('#f00', 0, 0)
rest.endX = 300
rest.endY = 300
rest.draw()
cvs.onmousedown = (e) => {
const rect = cvs.getBoundingClientRect()
const clickX = e.clientX - rect.left
const clickY = e.clientY - rect.top
const shape = getShape(clickX, clickY)
if (shape) {
const { startX, startY, endX, endY } = shape
window.onmousemove = (e) => {
const disX = e.clientX - rect.left - clickX
const disY = e.clientY - rect.top - clickY
shape.startX = startX + disX
shape.endX = endX + disX
shape.startY = startY + disY
shape.endY = endY + disY
}
} else {
// 新建
const shape = new Rectangle(colorPicker.value, clickX, clickY)
shapes.push(shape)
window.onmousemove = (e) => {
shape.endX = e.clientX - rect.left
shape.endY = e.clientY - rect.top
}
}
window.onmouseup = (e) => {
window.onmousemove = null
window.onmouseup = null
}
}
function getShape(x, y) {
for (let i = shapes.length - 1; i >= 0; i--) {
const s = shapes[i]
if (s.isInside(x, y)) {
return s
}
}
return null
}
function draw() {
requestAnimationFrame(draw)
ctx.clearRect(0, 0, cvs.width, cvs.height)
for (const s of shapes) {
s.draw()
}
}
draw()
index.html
<!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">
<title>Document</title>
</head>
<body>
<input type="color"></input>
<canvas></canvas>
<script src="./canvasClass.js"> </script>
</body>
</html>