Javascript 鼠标坐标don';缩放和平移画布后不匹配

Javascript 鼠标坐标don';缩放和平移画布后不匹配,javascript,html,animation,canvas,html5-canvas,Javascript,Html,Animation,Canvas,Html5 Canvas,我对javascript和canvas非常陌生,我有一个程序,可以检测椭圆路径上的动画元素。它后来会形成一棵树。。但这是我链接到JSFIDLE的基本结构。 它在没有缩放或平移的情况下运行良好,但只要我尝试缩放或平移,鼠标坐标就会失控。 我试着听从马克的建议 但我肯定是做错了什么,我还不清楚画布和转换矩阵到底发生了什么。我花了大约3天的时间试图改变我能想到的所有组合,但我似乎不明白:s 已解决: 下面是我的代码,用于缩放和鼠标平移,以及在椭圆上设置动画和检测元素: canvas=document

我对javascript和canvas非常陌生,我有一个程序,可以检测椭圆路径上的动画元素。它后来会形成一棵树。。但这是我链接到JSFIDLE的基本结构。 它在没有缩放或平移的情况下运行良好,但只要我尝试缩放或平移,鼠标坐标就会失控。 我试着听从马克的建议 但我肯定是做错了什么,我还不清楚画布和转换矩阵到底发生了什么。我花了大约3天的时间试图改变我能想到的所有组合,但我似乎不明白:s

已解决: 下面是我的代码,用于缩放和鼠标平移,以及在椭圆上设置动画和检测元素:

canvas=document.getElementById(“canvasOne”); context=canvas.getContext(“2d”); var status=document.getElementById('status'); 变量$canvas=$(“#canvasOne”); var canvasOffset=$canvas.offset(); var offsetX=canvasOffset.left; var offsetY=canvasOffset.top; var scrollX=$canvas.scrollLeft(); var scrollY=$canvas.scrollTop(); var cw=扫描宽度; var ch=底盘高度; var scaleFactor=1.00; var-panX=0; var panY=0; var-mainX=250; //设置中点位置X值 var-mainY=100; //设置中点位置Y值 var-mainR=125; //主椭圆半径R var no=5; //要显示的节点数 var div_角=360/无; 变量圆={ centerX:mainX, 森蒂:缅因州+100, 半径:缅因州, 角度:.9 }; 变量球={ x:0,, y:0, 速度:.1 }; var a=1.8; //椭圆宽度 var b=0.5; //椭圆高度 //尺度和泛变量 变量translatePos={ x:1, y:1 }; var startDragOffset={}; var mouseDown=false; 变量元素=[{}]; //生动活泼 var animateInterval=setInterval(绘图屏幕,1); //动画 函数drawScreen(){ clearRect(0,0,cw,ch); //背景框 context.beginPath(); context.fillStyle='#EEEEEE'; context.fillRect(0,0,canvas.width,theCanvas.height); strokeRect(1,1,canvas.width-2,canvas.height-2); closePath(); context.save(); 上下文翻译(panX,panY); scale(scaleFactor,scaleFactor); 球速=球速+0.001;
对于(var i=1;i,在这些情况下,使用转换矩阵是有用的,甚至是必要的:

  • 如果您正在深入嵌套转换
  • 如果要使用不同的变换修改不同的图形
  • 如果需要临时变换坐标
  • 如果您正在执行涉及倾斜的变换
  • 如果正在进行涉及旋转的变换
但是对于平移和缩放整个画布的简单情况,有一种更简单的方法

首先,设置变量以保存当前缩放和平移量:

var scaleFactor=1.00;
var panX=0;
var panY=0;
然后使用这些平移和缩放变量绘制所有图形。

  • 清理画布
  • 保存未转换的画布状态
  • 使用
    panX
    变量进行翻译
  • 使用
    scaleFactor
    变量进行缩放
  • 绘制所有元素,就像它们在未变形的空间中一样
  • 将上下文恢复到其未转换状态
示例代码:

function drawTranslated(){

    ctx.clearRect(0,0,cw,ch);

    ctx.save();
    ctx.translate(panX,panY);
    ctx.scale(scaleFactor,scaleFactor);

    ctx.beginPath();
    ctx.arc(circleX,circleY,15,0,Math.PI*2);
    ctx.closePath();
    ctx.fillStyle=randomColor();
    ctx.fill();

    ctx.restore();

}
现在,关于鼠标坐标:

var scaleFactor=1.00;
var panX=0;
var panY=0;
浏览器始终以未转换的坐标返回鼠标位置。您的绘图是在转换的空间中完成的。如果您想知道鼠标在转换的空间中的位置,可以将未转换的鼠标坐标转换为转换的坐标,如下所示:

var mouseXTransformed = (mouseX-panX) / scaleFactor;
var mouseYTransformed = (mouseY-panY) / scaleFactor;
以下是示例代码和演示:


正文{背景色:象牙;}
#画布{边框:1px纯红;}
$(函数(){
var canvas=document.getElementById(“canvas”);
var ctx=canvas.getContext(“2d”);
var$canvas=$(“#canvas”);
var canvasOffset=$canvas.offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;
var scrollX=$canvas.scrollLeft();
var scrollY=$canvas.scrollTop();
var cw=画布宽度;
var ch=画布高度;
var scaleFactor=1.00;
var-panX=0;
var panY=0;
var-circleX=150;
var-circleY=150;
变量$screen=$(“#screen”);
var$transformed=$(“#transformed”);
var$trx=$(“trx”);
drawTranslated();
$(“#canvas”).mousemove(函数(e){handleMouseMove(e);});
$(“#scaledown”)。单击(函数(){scaleFactor/=1.1;drawTranslated();});
$(“#scaleup”)。单击(函数(){scaleFactor*=1.1;drawTranslated();});
$(“#panleft”)。单击(函数(){panX-=10;drawTranslated();});
$(“#panright”)。单击(函数(){panX+=10;drawTranslated();});
函数drawTranslated(){
ctx.clearRect(0,0,cw,ch);
ctx.save();
翻译公司(panX,panY);
ctx.scale(scaleFactor,scaleFactor);
ctx.beginPath();
ctx.arc(circleX,circleY,15,0,数学PI*2);
ctx.closePath();
ctx.fillStyle=randomColor();
ctx.fill();
ctx.restore();
$trx.text(“平移:+panX+”,缩放:+scaleFacto
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
    body{ background-color: ivory; }
    #canvas{border:1px solid red;}
</style>
<script>
$(function(){

    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");
    var $canvas=$("#canvas");
    var canvasOffset=$canvas.offset();
    var offsetX=canvasOffset.left;
    var offsetY=canvasOffset.top;
    var scrollX=$canvas.scrollLeft();
    var scrollY=$canvas.scrollTop();
    var cw=canvas.width;
    var ch=canvas.height;

    var scaleFactor=1.00;
    var panX=0;
    var panY=0;

    var circleX=150;
    var circleY=150;

    var $screen=$("#screen");
    var $transformed=$("#transformed");
    var $trx=$("#trx");

    drawTranslated();

    $("#canvas").mousemove(function(e){handleMouseMove(e);});
    $("#scaledown").click(function(){ scaleFactor/=1.1; drawTranslated(); });
    $("#scaleup").click(function(){ scaleFactor*=1.1; drawTranslated(); });
    $("#panleft").click(function(){ panX-=10; drawTranslated(); });
    $("#panright").click(function(){ panX+=10; drawTranslated(); });


    function drawTranslated(){
        ctx.clearRect(0,0,cw,ch);

        ctx.save();
        ctx.translate(panX,panY);
        ctx.scale(scaleFactor,scaleFactor);

        ctx.beginPath();
        ctx.arc(circleX,circleY,15,0,Math.PI*2);
        ctx.closePath();
        ctx.fillStyle=randomColor();
        ctx.fill();

        ctx.restore();

        $trx.text("Pan: "+panX+", Scale: "+scaleFactor);
    }

    function handleMouseMove(e){
        e.preventDefault();
        e.stopPropagation();

        var mouseX=parseInt(e.clientX-offsetX);
        var mouseY=parseInt(e.clientY-offsetY);

        var mouseXT=parseInt((mouseX-panX)/scaleFactor);
        var mouseYT=parseInt((mouseY-panY)/scaleFactor);

        $screen.text("Screen Coordinates: "+mouseX+"/"+mouseY);

        $transformed.text("Transformed Coordinates: "+mouseXT+"/"+mouseYT);
    }

    function randomColor(){ 
        return('#'+Math.floor(Math.random()*16777215).toString(16));
    }

}); // end $(function(){});
</script>
</head>
<body>
    <h3>Transformed coordinates are mouseXY in transformed space.<br>The circles center is always at translated [150,150]</h3>
    <h4 id=screen>Screen Coordinates:</h4>
    <h4 id=transformed>Transformed Coordinates:</h4>
    <h4 id=trx>Pan & Scale</h4>
    <button id=scaledown>Scale Down</button>
    <button id=scaleup>Scale Up</button>
    <button id=panleft>Pan Left</button>
    <button id=panright>Pan Right</button><br>
    <canvas id="canvas" width=350 height=400></canvas>
</body>
</html>