分享画布绘制矩形

简介

实现功能,在画布上绘制矩形,移动矩形。

在线演示

绘制矩形

实现代码

<!DOCTYPE html>

<html>

<head>
<title>绘制矩形</title>
</head>

<body>

<div style="margin: 10px">
     <input type="color" />
</div>

<div style="background: #ccc;margin: 10px">
     <canvas></canvas>
</div>

<script>

//获取调色板

const colorPicker=document.querySelector('input')

//获取画布

const cvs=document.querySelector('canvas')

//获取画布上下文

const ctx=cvs.getContext('2d')


init()

//初始化画布

function init(){

    const w = window.innerWidth-50,h=window.innerHeight-80
    //dpr保证高清屏绘制的清晰度
    cvs.width=w*window.devicePixelRatio

    cvs.height=h*window.devicePixelRatio

    cvs.style.width=w+'px'

    cvs.style.height=h+'px'

}

//存储图形数组

const shapes = []

//矩形类

class Rectangle{

    constructor(color,startX,startY){

        //矩形颜色

        this.color = color

        //矩形起始坐标

        this.startX = startX

        this.startY = startY

        //矩形结束坐标

        this.endX = startX

        this.endY = startY

    }

    //get为访问器属性

    //矩形左上角坐标

    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.beginPath()

        //移动到左上角

        ctx.moveTo(this.minX*window.devicePixelRatio,this.minY*window.devicePixelRatio)
        
        //绘制直线到左上角
        
        ctx.lineTo(this.minX*window.devicePixelRatio,this.minY*window.devicePixelRatio)

        //绘制直线到右上角

        ctx.lineTo(this.maxX*window.devicePixelRatio,this.minY*window.devicePixelRatio)

        //绘制直线到右下角

        ctx.lineTo(this.maxX*window.devicePixelRatio,this.maxY*window.devicePixelRatio)

        //绘制直线到左下角

        ctx.lineTo(this.minX*window.devicePixelRatio,this.maxY*window.devicePixelRatio)

        //绘制直线到左上角

        ctx.lineTo(this.minX*window.devicePixelRatio,this.minY*window.devicePixelRatio)

        ctx.save()
        //设置填充颜色

        ctx.fillStyle=this.color

        ctx.fill()

        ctx.strokeStyle='#fff'

        ctx.lineGap='square'

        ctx.lineWidth=3*window.devicePixelRatio

        ctx.stroke()
        ctx.restore()

    }

}

cvs.onmousedown = (e)=>{
    //画布左上角坐标

    const bouding = 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 disX=e.clientX-bouding.left-mouseX

            const disY=e.clientY-bouding.top-mouseY

            shape.startX=startX+disX

            shape.startY=startY+disY

            shape.endX=endX+disX

            shape.endY=endY+disY

        }

    }else{

        //新增绘制矩形

        shapes.push(rect)

        window.onmousemove=(e)=>{

            rect.endX=e.clientX-bouding.left

            rect.endY=e.clientY-bouding.top

        }

    }

    window.onmouseup=()=>{

        window.onmousemove=null

        window.onmouseup=null

    }

}

function getShape(x,y){
    //画布的绘制顺序倒着来循环,
    for(let i=shapes.length-1;i>=0;i--){
        if(x>=shapes[i].minX&&x<=shapes[i].maxX&&y>=shapes[i].minY&&y<=shapes[i].maxY){
           return shapes[i]
        }

    }
}


function draw(){
    //每一帧注册绘制方法

    requestAnimationFrame(draw)
    //清空画布

    ctx.clearRect(0,0,cvs.width,cvs.height)

    for(const shape of shapes){

         shape.draw()

    }

}

draw()

function emptyCanvas(){
    shapes = []
}
function undo(){
    shapes.pop()
}

</script>

</body>

</html>

  • 7
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

:MNongSciFans

抛铜币以舒赞同,解兜囊以现支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值