簡介
實現功能,在畫布上繪制矩形,移動矩形。
在線演示
繪制矩形
實現代碼
<!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.devicePixelRatiocvs.height=h*window.devicePixelRatiocvs.style.width=w+'px'cvs.style.height=h+'px'}//存儲圖形數組const shapes = []//矩形類class Rectangle{constructor(color,startX,startY){//矩形顏色this.color = color//矩形起始坐標this.startX = startXthis.startY = startY//矩形結束坐標this.endX = startXthis.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.colorctx.fill()ctx.strokeStyle='#fff'ctx.lineGap='square'ctx.lineWidth=3*window.devicePixelRatioctx.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.offsetXconst mouseY=e.offsetYwindow.onmousemove=(e)=>{const disX=e.clientX-bouding.left-mouseXconst disY=e.clientY-bouding.top-mouseYshape.startX=startX+disXshape.startY=startY+disYshape.endX=endX+disXshape.endY=endY+disY}}else{//新增繪制矩形shapes.push(rect)window.onmousemove=(e)=>{rect.endX=e.clientX-bouding.leftrect.endY=e.clientY-bouding.top}}window.onmouseup=()=>{window.onmousemove=nullwindow.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>
?
?