每日一题:canvas绘制矩形/拖动绘制的矩形

代码不再赘述,直接复制到文件直接运行即可

逻辑很简单,在画布上进行绘制,对js基础有一定要求。

html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="./style.css">
</head>

<body>
<input type="color">
<canvas>
</canvas>
<script src="index.js"></script>

</body>
</html>

css

body{
    display: flex;
    align-items: center;
    justify-content: center;
    flex-direction: column;
}
canvas {
    margin: 50px;
    background-color: #b1b3b8;
}

javascript

console.log(devicePixelRatio)
// 原始尺寸 = 样式尺寸 * 缩放倍率
const cvs = document.querySelector('canvas') // 画布

const colorPicker = document.querySelector('input') // 颜色选择器

const ctx = cvs.getContext('2d')// 2d绘图环境

function init() {
    const w = 500 // 画布宽度
    const h = 300 // 画布高度
    cvs.width = w * devicePixelRatio
    cvs.height = h * devicePixelRatio
    cvs.style.width = w + 'px'
    cvs.style.height = h + 'px'
}

init()
const shapes = []

class Rectangle {
    constructor(color, startX, startY) {
        this.color = color
        this.startX = startX
        this.startY = startY
        this.endX = startX
        this.endY = startY
    }

    get minX() {
        return Math.min(this.startX, this.endX)
    }

    get minY() {
        return Math.min(this.startY, this.endY)
    }

    get maxX() {
        return Math.max(this.startX, this.endX)
    }

    get maxY() {
        return Math.max(this.startY, this.endY)
    }

    draw(ctx) {
        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.strokeStyle = '#fff'
        ctx.lineCap = 'square'
        ctx.lineWidth =  2* devicePixelRatio
        ctx.stroke()
    }

}


cvs.onmousedown= e => {
    console.log(e.offsetX, e.offsetY)
    const bounding = cvs.getBoundingClientRect()
    const rect = new Rectangle(colorPicker.value, e.offsetX, e.offsetY)
    const shape = getShape(e.offsetX, e.offsetY)
    if(shape){
        const { startX, startY,endX,endY} = shape
        const mouseX = e.offsetX
        const mouseY = e.offsetY
        window.onmousemove = e => {
            const distX = e.clientX - bounding.left - mouseX
            const distY = e.clientY - bounding.top - mouseY
            shape.startX = startX + distX
            shape.startY = startY + distY
            shape.endX = endX + distX
            shape.endY = endY + distY
        }

        console.log('拖动')
    }else {
        shapes.push(rect)
        window.onmousemove = e => {
            rect.endX = e.clientX - bounding.left
            rect.endY = e.clientY - bounding.top

        }
    }


    window.onmouseup = () => {
        window.onmousemove = null
        window.onmouseup = null
    }
}
function draw() {
    requestAnimationFrame(draw)
    ctx.clearRect(0, 0, cvs.width, cvs.height) // 清空画布
    shapes.forEach(item => {
        item.draw(ctx)
    }
    )
}
draw()
function getShape(x,y) {
    return shapes.find(item => {
        return item.minX <= x && item.maxX >= x && item.minY <= y && item.maxY >= y
    })
}

posted @ 2023-10-25 16:36  菜鸟小何  阅读(95)  评论(0编辑  收藏  举报