【问题标题】:HTML5 Canvas distortionHTML5 画布扭曲
【发布时间】:2016-06-25 21:07:34
【问题描述】:

我正在尝试在将异步加载的动态大小的视频上包含一个画布元素。在画布上,用户将能够拖动矩形选择框并调整其大小。

在我的 JS 文件中,我有一个监听器正在监视窗口并通过 canvas 元素的 .width 和 .height 属性调整画布的大小,使其与视频的确切宽度和高度一致。

对于 JS 矩形选择代码,我正在按照 StackOverflow 问题的第一个答案中的小提琴:drawing a rectangle with mouse click and drag - javascript,但是,由于某种原因,当用户在页面上向下滚动时画布上的绘图完全扭曲,矩形开始被绘制得离鼠标很远。但是,当用户位于页面顶部时,矩形将绘制在正确的位置。为什么会这样?

以下是我正在使用的一些 JS 代码:

  
// Happens on mousedown event
  downCanvas: function(e) {
    $('.label-grid-canvas').css('cursor','crosshair');
    this.isDrawing = true
    this.startX = parseInt(e.clientX - this.offsetX);
    this.startY = parseInt(e.clientY - this.offsetY);
  },
  
// Happens on mouseup event
  upCanvas: function(e) {
    this.isDrawing = false;
    $('.label-grid-canvas').css('cursor','default');
  },
  // Happens on mousemove event
  moveCanvas: function(e) {
    if (this.isDrawing) {
      var mouseX = parseInt(e.clientX - this.offsetX);
      var mouseY = parseInt(e.clientY - this.offsetY);

      this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
      this.ctx.beginPath();
      this.ctx.rect(this.startX, this.startY, mouseX - this.startX, mouseY - this.startY);
      this.ctx.stroke();
    }
  },

  resizeCanvas: function() {
    this.canvas.width = $('#video-canvas')[0].offsetWidth;
    this.canvas.height = $('#video-canvas')[0].offsetHeight;

    this.canvasOffset = $('.label-grid-canvas').offset();
    this.offsetX = this.canvasOffset.left;
    this.offsetY = this.canvasOffset.top;

    this.redraw();
  },

  redraw: function() {
    this.ctx.strokeStyle = 'blue';
    this.ctx.lineWidth = '2';
    this.ctx.strokeRect(0, 0, $('#video-canvas')[0].offsetWidth,
        $('#video-canvas')[0].offsetHeight);
  },

// Happens after page-load
  initialize: function(options) {
    this.canvas = document.getElementById('label-grid-canvas');
    this.isDrawing = false;
    this.ctx = this.canvas.getContext('2d');
    this.startX;
    this.startY;
    this.canvasOffset = $('.label-grid-canvas').offset();
    this.offsetX = this.canvasOffset.left;
    this.offsetY = this.canvasOffset.top;
    $(window).on('resize', _.bind(this.resizeCanvas, this));
 ....
}

请忽略效率低下的问题,我只是在清理之前先尝试一起破解一个工作的东西。

【问题讨论】:

  • 这是 Stackoverflow 上的常见问题。不要使用 CSS 调整 html5 画布的大小。相反,调整画布元素本身的大小:canvasElement.width=800; canvasElement.height=500;。您可以使用context.drawImage 的扩展形式将较小的视频图像放大到较大的画布上。这样您就不会失真,也不会误报鼠标坐标。
  • @markE 感谢您的建议。所以现在我让我的 JS 做的是观察窗口以调整大小,然后使用您的方法直接更新画布的尺寸。现在矩形更准确了一点,但它仍然肯定是关闭的。有什么建议吗?
  • 您的用户是否允许滚动,您对此负责吗?顺便说一句,您的问题与this one 几乎相同。你们都在做同一个项目吗?无论如何,请查看其他问答,其中包含可调整大小/可滚动设计的演示。
  • 是的,不,我没有考虑到这一点,我刚刚意识到滚动位置是我的问题,现在这就是我需要解决的问题。这很有趣,但不,那个人不是我。
  • 我添加了一个答案,显示如何在计算鼠标位置时考虑调整大小和滚动。

标签: javascript jquery html canvas


【解决方案1】:

这里的骨架显示了在计算鼠标位置时如何考虑调整大小和滚动。

var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
function reOffset(){
  var BB=canvas.getBoundingClientRect();
  offsetX=BB.left;
  offsetY=BB.top;        
}
var offsetX,offsetY;
reOffset();
window.onscroll=function(e){ reOffset(); }
window.onresize=function(e){ reOffset(); }

var isDown=false;
var startX,startY,mouseX,mouseY;

var $mouse=$('#mouse');
$("#canvas").mousemove(function(e){handleMouseMove(e);});

function handleMouseMove(e){
  // tell the browser we're handling this event
  e.preventDefault();
  e.stopPropagation();
  // calc the current mouse position
  mouseX=parseInt(e.clientX-offsetX);
  mouseY=parseInt(e.clientY-offsetY);
  // report the mouse position
  $mouse.text('Mouse position: '+mouseX+' / '+mouseY);
}
body{ background-color: ivory; }
#canvas{border:1px solid red; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<h4 id=mouse>Move the mouse around the canvas.</h4>
<canvas id="canvas" width=300 height=300></canvas>

【讨论】:

  • 刚刚实现了reOffset功能,解决了我所有的问题,非常感谢!
猜你喜欢
  • 2016-02-07
  • 2023-03-17
  • 1970-01-01
  • 2022-01-07
  • 2012-08-31
  • 2020-03-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多