Javascript 如何说明在画布中缩放、平移和旋转鼠标单击

Javascript 如何说明在画布中缩放、平移和旋转鼠标单击,javascript,canvas,css-transforms,Javascript,Canvas,Css Transforms,我正在开发一个应用程序,它需要通过样式、宽度而不是缩放…进行缩放,转换translatex、y和旋转,例如旋转90度画布元素。然后我需要计算画布上正确的鼠标点击位置。也就是说,我需要这样做,以便在用户单击的位置实际显示行的结尾。现在,当我尝试合并翻译时,我的计算结果会有一点偏差,在下面的演示画布中单击两次可以看到这一点 部分让我困惑的是,我应该按哪个顺序进行非翻译、非旋转和非缩放以产生正确的结果 演示代码: var canvas=document.getElementByIdcanvas; v

我正在开发一个应用程序,它需要通过样式、宽度而不是缩放…进行缩放,转换translatex、y和旋转,例如旋转90度画布元素。然后我需要计算画布上正确的鼠标点击位置。也就是说,我需要这样做,以便在用户单击的位置实际显示行的结尾。现在,当我尝试合并翻译时,我的计算结果会有一点偏差,在下面的演示画布中单击两次可以看到这一点

部分让我困惑的是,我应该按哪个顺序进行非翻译、非旋转和非缩放以产生正确的结果

演示代码:

var canvas=document.getElementByIdcanvas; var scaleX=0.5; var scaleY=0.5; var-rot=1; var dispWidth=canvas.width*scaleX; var dispHeight=canvas.height*scaleY; var xlateX=Math.floordispHeight-dispWidth/2; var xlateY=Math.floordispWidth-dispHeight/2; 变量转换=平移+xlateX+px,+xlateY+px旋转+rot*90度; canvas.style.width=dispWidth+px; canvas.style.height=dispHeight+px; canvas.style.transform=转换; var context=canvas.getContext2d; var堆栈=[]; canvas.onclick=函数e{ var rect=canvas.getBoundingClientRect; console.log'rect',rect.left,rect.top; //在画布中定位,忽略滚动 var x=e.clientX-rect.left; var y=e.clientY-rect.top; 控制台。日志“原始”,x,y; //鳞片 x/=scaleX; y/=scaleY; 控制台。对数“缩放”,x,y; //翻译 x-=xlateX; y-=xlateY; console.log'translated',x,y; var-tmp; 开关%4{ 案例1: tmp=x; x=y; y=画布高度-tmp; 打破 案例2: y=画布高度-tmp; x=画布宽度-tmp; 打破 案例3: tmp=y; y=x; x=画布宽度-tmp; 打破 违约: 打破 } 控制台。日志“旋转”,x,y; stack.push{x:x,y:y}; 如果stack.length>1{ context.beginPath; context.moveTostack[0].x,堆栈[0].y; context.lineTostack[1].x,堆栈[1].y; 中风; 堆栈=[]; } }; 单击一次以开始一行。再次单击以完成它。
你为什么要用css呢?如果您更改canvas width/height属性并将转换应用于上下文矩阵,则会简单得多。@Kaido我上面提到的应用程序正在将用户绘制的内容覆盖到本机img元素上。当用户旋转img元素时,旋转和转换是通过CSS完成的,因此实际的canvas元素必须旋转以匹配。将canvas和img放在另一个容器中可能会更容易,而这个容器本身也被转换了,这样做行吗?但这需要对现有的应用程序进行更多的更改,而不是我当时认为的谨慎。我以后可能会尝试这种方法。在我看来,最简单的方法是在画布上绘制所有内容,并使用画布的方法进行转换。不管怎么说,修改css的脚本以改变上下文矩阵应该不是不可能的。使用转换矩阵来跟踪累积的缩放、平移和旋转。这是西蒙·萨里斯写的一篇好剧本。它是为了跟踪画布元素转换而编写的,但跟踪CSS转换也同样有效: