调整大小后,画布点绘图不会缩放

时间:2017-03-01 18:26:12

标签: javascript jquery html css canvas

使用绘制在其上的javascript点动态调整画布大小后,不再与它们放置的位置对齐,并且弧线也应该从它们的渲染方式拉伸。

下面的runnable示例演示了这个问题,因为单击光标的点应该变成一个错误位置的大的miss-shapen椭圆。



var TargetWidth = 400;

var canvases = $(".hotspot-canvas")

for (i = 0; i < canvases.length; i++) { 
    canvas = $(canvases[i]);

    var src = canvas.attr("data-img");

    initilizePlotPointCanvas(canvas, src);
  
}

function initilizePlotPointCanvas(canvas, src)
{
  var my_image = new Image();
  my_image.onload = function(){
    
    var w1 = this.width;
    var w2 = TargetWidth
  
    var r = w1 / w2;
  
    var h1 = this.height;
    var h2 = this.height / r;
  
    canvas.width(TargetWidth).height(h2).css("background-image", "url("+src+")");
    setTimeout(function(){
      
      var jcanvas = canvas[0];
    
    var ctx = jcanvas.getContext('2d'),
    w = jcanvas.width,
    h = jcanvas.height;
    ctx.translate(-0.1, -0.1);
    jcanvas.onmousedown = function(e) {
      var rect = jcanvas.getBoundingClientRect();
      x3 = e.clientX - rect.left;
      y3 = e.clientY - rect.top;
  
      ctx.clearRect(0, 0, w, h)
      ctx.beginPath();
      ctx.arc(x3, y3, 5, 0, 2 * Math.PI, false);
      ctx.fillStyle = 'red';
      ctx.fill();
      ctx.stroke();
    }
      
    }, 500)
    
  }
  my_image.src = src;
}
&#13;
.hotspot-canvas {
    -webkit-user-select: none;
    -moz-user-select: none;
    user-select: none;
    cursor: crosshair;
    border: 1px solid black;
    background-repeat: no-repeat;
    background-position: center center;
    background-clip: border-box;
    background-origin: padding-box;
    -moz-background-size: cover;
    background-size: cover;
}
&#13;
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>

<canvas 
  data-id="554924"
  data-img="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQXXarydhE3CZRSMgXCProd1w0_oSwIOPd7zJN5EQmLtQtPDD21" 
  class="hotspot-canvas"
   data-responses="0" data-notes="0" data-actions="0" data-email="123" data-responder="true" data-response-id="" orig_type="14" data-tag="6bbf8f97-758f-47ca-8b8c-24a1cd3ddd55" data-formtemplatequestiontype="s" data-valueifparentna="" data-exportkey=""></canvas>
&#13;
&#13;
&#13;

2 个答案:

答案 0 :(得分:2)

显示大小和画布分辨率

显示大小和画布分辨率是两个不同的实体。

设置画布样式的宽度和高度时,可以设置显示大小

canvas.style.width = "100px";
canvas.style.height = "100px";

设置画布宽度和高度时,请设置分辨率。

canvas.width = 100;
canvas.height = 100;

您已设置了显示尺寸,但忽略了将分辨率与显示尺寸相匹配。

您可以通过设置分辨率以匹配显示尺寸来修复它

var bounds = jcanvas.getBoundingClientRect();
jcanvas.width = bounds.width;
jcanvas.height = bounds.height; 

&#13;
&#13;
var TargetWidth = 400;

var canvases = $(".hotspot-canvas")

for (i = 0; i < canvases.length; i++) { 
    canvas = $(canvases[i]);

    var src = canvas.attr("data-img");

    initilizePlotPointCanvas(canvas, src);
  
}

function initilizePlotPointCanvas(canvas, src)
{
  var my_image = new Image();
  my_image.onload = function(){
    
    var w1 = this.width;
    var w2 = TargetWidth
  
    var r = w1 / w2;
  
    var h1 = this.height;
    var h2 = this.height / r;
  
    canvas.width(TargetWidth).height(h2).css("background-image", "url("+src+")");

    setTimeout(function(){
      
      var jcanvas = canvas[0];
     var bounds = jcanvas.getBoundingClientRect();
    jcanvas.width = bounds.width;
    jcanvas.height = bounds.height;        
    var ctx = jcanvas.getContext('2d'),
    w = jcanvas.width,
    h = jcanvas.height;
    ctx.translate(-0.1, -0.1);
    jcanvas.onmousedown = function(e) {
      var rect = jcanvas.getBoundingClientRect();
      x3 = e.clientX - rect.left;
      y3 = e.clientY - rect.top;
  
      ctx.clearRect(0, 0, w, h)
      ctx.beginPath();
      ctx.arc(x3, y3, 5, 0, 2 * Math.PI, false);
      ctx.fillStyle = 'red';
      ctx.fill();
      ctx.stroke();
    }
      
    }, 500)
    
  }
  my_image.src = src;
}
&#13;
.hotspot-canvas {
    -webkit-user-select: none;
    -moz-user-select: none;
    user-select: none;
    cursor: crosshair;
    border: 1px solid black;
    background-repeat: no-repeat;
    background-position: center center;
    background-clip: border-box;
    background-origin: padding-box;
    -moz-background-size: cover;
    background-size: cover;
}
&#13;
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>

<canvas 
  data-id="554924"
  data-img="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQXXarydhE3CZRSMgXCProd1w0_oSwIOPd7zJN5EQmLtQtPDD21" 
  class="hotspot-canvas"
   data-responses="0" data-notes="0" data-actions="0" data-email="123" data-responder="true" data-response-id="" orig_type="14" data-tag="6bbf8f97-758f-47ca-8b8c-24a1cd3ddd55" data-formtemplatequestiontype="s" data-valueifparentna="" data-exportkey=""></canvas>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

就像我在评论中提到的那样,我最近遇到了同样的问题,所以我想分享我的解决方案。基本上发生的事情是你的canvas元素的尺寸是缩放的,它的原点是由于CSS而翻译的,但是画布的内部分辨率仍然是相同的。此外,画布的边框和填充也会影响DOMRect返回的getBoundingClientRect属性。

您需要获取某些clientXclientY的{​​{1}}和MouseEvent值,画布的内部分辨率以及所显示画布的尺寸和偏移量元素,包括边框和填充,并使用它们来计算与画布的内部坐标系相关的xy坐标。此代码需要JQuery和ES6支持,但如果您担心浏览器兼容性,可以使用Babel或其他东西进行编译。

TouchEvent