resize时html5canvas重绘

我有两个canvas元素,需要在按钮点击时resize。

和脚本:

  var sketch;var sketch_sl;var onPaint;var canvas=null;var ctx=null;var tmp_ctx=null; function drawCanvas(div) { canvas = document.querySelector(div + " #canvasGraph"); ctx = canvas.getContext('2d'); sketch = document.querySelector(div + " #canvasDiv"); sketch_sl = getComputedStyle(sketch); canvas.width = parseInt(sketch_style.getPropertyValue('width')); canvas.height = parseInt(sketch_style.getPropertyValue('height')); tmp_canvas = document.createElement('canvas'); tmp_ctx = tmp_canvas.getContext('2d'); tmp_canvas.id = 'tmp_canvas'; tmp_canvas.width = canvas.width; tmp_canvas.height = canvas.height; sketch.appendChild(tmp_canvas); 

重绘function:

 // here I must redraw my lines resized 2 times ( *cScale ) where cScale=2 or =1 function drawScales(ctx, canvas) ctx.strokeStyle = 'green'; ctx.fillStyle = 'green'; ctx.beginPath(); ctx.moveTo(5, 0); ctx.lineTo(0, canvas.height); scaleStep = 24*cScale; 

由于某种原因,它的工作非常糟糕,旧职位留下来。 有没有办法完全删除整个canvas并附加或完全重绘?

我试过canvas.width=canvas.width ,试过ctx.clearRect(0, 0, canvas.width, canvas.height);tmp_ctx.clearRect(0, 0, canvas.width, canvas.height); ,尝试$(".sDetails #canvasGraph")[0].reset();

逻辑上, drawCanvas(".sDetails");drawLines(ctx, canvas); 应该从头开始重绘,但不会。

调整canvas元素的widthheight并使用context.scale以新缩放的大小重绘原始图形。

  • 调整canvas元素的大小将自动清除canvas上的所有绘图。

  • resize还会自动将所有上下文属性重置为其默认值。

  • 使用context.scale很有用,因为canvas会自动重新缩放原始图形以适合新尺寸的canvas。

  • 重要说明:canvas不会自动重绘原始图纸……您必须重新发出原始图纸命令。

与2幅canvas相同尺寸的插图(其尺寸由范围控制控制)

在此处输入图像描述

左canvas的插图resize

在此处输入图像描述

右canvas的插图调整得更大

在此处输入图像描述

这是示例代码和演示。 此演示使用范围元素来控制resize,但您也可以在window.onresize大小调整+重绘

 var canvas1=document.getElementById("canvas1"); var ctx1=canvas1.getContext("2d"); var canvas2=document.getElementById("canvas2"); var ctx2=canvas2.getContext("2d"); var originalWidth=canvas1.width; var originalHeight=canvas1.height; var scale1=1; var scale2=1; $myslider1=$('#myslider1'); $myslider1.attr({min:50,max:200}).val(100); $myslider1.on('input change',function(){ var scale=parseInt($(this).val())/100; scale1=scale; redraw(ctx1,scale); }); $myslider2=$('#myslider2'); $myslider2.attr({min:50,max:200}).val(100); $myslider2.on('input change',function(){ var scale=parseInt($(this).val())/100; scale2=scale; redraw(ctx2,scale); }); draw(ctx1); draw(ctx2); function redraw(ctx,scale){ // Resizing the canvas will clear all drawings off the canvas // Resizing will also automatically clear the context // of all its current values and set default context values ctx.canvas.width=originalWidth*scale; ctx.canvas.height=originalHeight*scale; // context.scale will scale the original drawings to fit on // the newly resized canvas ctx.scale(scale,scale); draw(ctx); // always clean up! Reverse the scale ctx.scale(-scale,-scale); } function draw(ctx){ // note: context.scale causes canvas to do all the rescaling // math for us, so we can always just draw using the // original sizes and x,y coordinates ctx.beginPath(); ctx.moveTo(150,50); ctx.lineTo(250,150); ctx.lineTo(50,150); ctx.closePath(); ctx.stroke(); ctx.fillStyle='skyblue'; ctx.beginPath(); ctx.arc(150,50,20,0,Math.PI*2); ctx.closePath(); ctx.fill(); ctx.stroke(); ctx.beginPath(); ctx.arc(250,150,20,0,Math.PI*2); ctx.closePath(); ctx.fill(); ctx.stroke(); ctx.beginPath();; ctx.arc(50,150,20,0,Math.PI*2); ctx.fill(); ctx.stroke(); } $("#canvas1, #canvas2").mousemove(function(e){handleMouseMove(e);}); var $mouse=$('#mouse'); function handleMouseMove(e){ // tell the browser we're handling this event e.preventDefault(); e.stopPropagation(); var bb=e.target.getBoundingClientRect(); mouseX=parseInt(e.clientX-bb.left); mouseY=parseInt(e.clientY-bb.top); if(e.target.id=='canvas1'){ $mouse.text('Mouse1: '+mouseX/scale1+' / '+mouseY/scale1+' (scale:'+scale1+')'); }else{ $mouse.text('Mouse2: '+mouseX/scale2+' / '+mouseY/scale2+' (scale:'+scale2+')'); } } 
 body{ background-color: ivory; } canvas{border:1px solid red;} 
  
Resize left canvas

Resize right canvas

Mouse coordinates:

如果您需要与比例无关的位置,则可以使用标准化值([0,1]),并使用canvas的大小作为比例因子。 这样,您可以扩展和存储值,而无需过多关注实际目标大小。

您也可以按原样使用鼠标位置,并通过将它们划分为canvas大小进行标准化。

例如:

渲染时 ,(1,1)的点将始终像右下角一样绘制(1 * canvas.width, 1 * canvas.height)

存储点时,您将使用鼠标位置并将其划分在canvas尺寸上,例如,如果我单击尺寸为400×200的canvas的右下角,则点将为400/400 = 1,200 / 200 = 1。

请注意,宽度和高度将是独占的(即宽度为1等),但为了简单起见……

在此示例中,您可以从任何尺寸的canvas开始,绘制标准化的点,更改canvas的大小并使点相对于原始位置按比例重新绘制。

 var rng = document.querySelector("input"), c = document.querySelector("canvas"), ctx = c.getContext("2d"), points = []; // change canvas size and redraw all points rng.onchange = function() { c.width = +this.value; render(); }; // add a new normalized point to array c.onclick = function(e) { var r = this.getBoundingClientRect(), // to adjust mouse position x = e.clientX - r.left, y = e.clientY - r.top; points.push({ x: x / c.width, // normalize value to range [0, 1] y: y / c.height }); // store point render(); // redraw (for demo) }; function render() { ctx.clearRect(0, 0, c.width, c.height); // clear canvas ctx.beginPath(); // clear path for(var i = 0, p; p = points[i]; i++) { // draw points as fixed-size circles var x = px * c.width, // normalized to absolute values y = py * c.height; ctx.moveTo(x + 5, y); ctx.arc(x, y, 5, 0, 6.28); ctx.closePath(); } ctx.stroke(); } 
 canvas {background:#ddd} 
 

Click on canvas to add points, then resize


我决定使用比例变量来调整我的比例。 我调整canvascanvas.width *= 2; 然后我重绘我的秤。

var scaleStep;

并使用将其添加到代码中: ctx.lineTo(12*24*cScale+12, canvas.height-24); 需要进行缩放的地方。 最大化canvas时scaleStep为2,返回原始大小时为1。