Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/lua/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 画布坐标溢出?_Javascript_Canvas - Fatal编程技术网

Javascript 画布坐标溢出?

Javascript 画布坐标溢出?,javascript,canvas,Javascript,Canvas,如何防止一些画布坐标溢出 示例案例: 以下javascript: var canvas = document.getElementById("canvas"); var context = canvas.getContext("2d"); canvas.width = 500; canvas.height = 500; context.strokeStyle = "#000"; context.beginPath(); /

如何防止一些画布坐标溢出

示例案例:

以下javascript:

 var canvas = document.getElementById("canvas");
 var context = canvas.getContext("2d");
 canvas.width = 500;
 canvas.height = 500;
 context.strokeStyle = "#000";
 context.beginPath();
 // line from (100, 100) to (100,999999999999.9)
 context.moveTo(100.0, 100.0);
 context.lineTo(100.0, 999999999999.9); 
 // line from (200, 200) to (200,9999999999999.9)
 context.moveTo(200.0, 100.0);
 context.lineTo(200.0, 9999999999999.9);
 context.stroke();
提供此画布输出

在这些示例中,两行的结尾Y坐标都为正值,但第二行的解释似乎类似于
-Inf
。似乎在内部,这些值被强制转换为一些
无符号int
,使得一些位值被认为是符号,但我没有找到关于它的明确文档

更新 我想要的是正确地画线,而不是阻止在画布图像外用坐标画线。
我知道有一种方法可以做一些线性代数(计算直线和边界之间的交点),但我想知道是否有更简单的方法。

假设我们有一个
canvas.height=500
canvas.width=500
,我们想防止坐标在
0到500
范围内。当使用
函数()调用上下文时,我们可以使用这些属性设置范围

var canvas=document.getElementById(“canvas”);
var context=canvas.getContext(“2d”);
画布宽度=500;
高度=500;
context.strokeStyle=“#000”;
letsDraw(100200800300)//返回警报错误
函数letsDraw(moveToX、moveToY、lineToX、lineToY){
如果((moveToX0)和&(moveToY0)){
context.beginPath();
moveTo(moveToX,moveToY);
如果((lineToX0)和&(lineToY0)){
lineTo(lineToX,lineToY);
stroke();
}否则{
警报(“范围超出画布”);
返回false;
}
}否则{
警报(“范围超出画布”);
返回false;
}
}
moveTo
lineTo
参数的数据类型为。您可以看到它是32位浮点数,大概是有符号的。这意味着根据规范,不应该有溢出,错误取决于浏览器的实现

我的测试证实了这一点,因为Firefox、Google Chrome或Opera都没有呈现任何内容,表明存在未定义的可疑行为。如果坐标无效,我希望出现错误。如果我使用较小的坐标(300),它们都会提供此结果(裁剪、框显):

然后,我执行了一些测试,可以呈现的最后一个数字是:

Math.pow(2,31)-Math.pow(2,6)-1 = 2147483583
因此,如果你真的想解决一个问题,而不是出于好奇而问,我建议以下两种解决方案之一:

  • 创建一个辅助函数来限制坐标。

      var max = 2147483583;
      var min = -2147483583;
      function safeCoordinate(number) {
        if(number>max)
          return max;
        if(number<min)
          return min;
        return number;
      }
    
  • 覆盖实际画布方法以解决问题

    如果您感到困难,实际上可以继续覆盖画布上下文方法。这是很多人都会建议你反对的,因为改变内置的东西经常会导致难以追踪的神秘错误。将此警告置之不理:

    (function(max, min, context_proto) {
              // Override move to
              var old_moveTo =context_proto.moveTo;
              context_proto.moveTo = function(x, y) {
                  return old_moveTo.call(this, safeCoordinate(x), safeCoordinate(y));   
              }
              var old_lineTo =context_proto.lineTo;
              context_proto.lineTo = function(x, y) {
                  return old_lineTo.call(this, safeCoordinate(x), safeCoordinate(y));   
              }
              // Override more methods if needed!
                ...
              // Our helper function
              function safeCoordinate(number) {
                if(number>max)
                  return max;
                if(number<min)
                  return min;
                return number;
              }  
    })(2147483583,-2147483583, CanvasRenderingContext2D.prototype);
    
    (函数(最大、最小、上下文){
    //覆盖移动到
    var old_moveTo=context_proto.moveTo;
    context_proto.moveTo=函数(x,y){
    返回旧的_moveTo.call(this,safeCoordinate(x),safeCoordinate(y));
    }
    var old_lineTo=context_proto.lineTo;
    context_proto.lineTo=函数(x,y){
    返回旧的_lineTo.call(this,safeCoordinate(x),safeCoordinate(y));
    }
    //如果需要,覆盖更多方法!
    ...
    //我们的助手函数
    功能安全坐标(编号){
    如果(数量>最大值)
    返回最大值;
    
    如果我想这不是我想要的画布元素范围。这不是我想要的。我认为我的错误是因为可以被误解。我想要画线,但是防止这些不想要的INF行为。我做了一个问题的更新。你可能想考虑你得到这些结果是否不是设计缺陷。我给你加了一个ANS。wer但您必须了解,检查有效坐标会降低性能。这似乎是一个很好的建议。谢谢。它应该按照标准工作,但这是一个实现问题。其他非浏览器画布引擎(android)也有同样的问题。
    context.lineTo(safeCoordinate(x), safeCoordinate(y)); 
    
    (function(max, min, context_proto) {
              // Override move to
              var old_moveTo =context_proto.moveTo;
              context_proto.moveTo = function(x, y) {
                  return old_moveTo.call(this, safeCoordinate(x), safeCoordinate(y));   
              }
              var old_lineTo =context_proto.lineTo;
              context_proto.lineTo = function(x, y) {
                  return old_lineTo.call(this, safeCoordinate(x), safeCoordinate(y));   
              }
              // Override more methods if needed!
                ...
              // Our helper function
              function safeCoordinate(number) {
                if(number>max)
                  return max;
                if(number<min)
                  return min;
                return number;
              }  
    })(2147483583,-2147483583, CanvasRenderingContext2D.prototype);