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