javascript - Handling a rotated canvas image dragable relative to the canvas not the image
问题描述
I want to allow users to rotate an image in a canvas and then drag it to position it. This is working fine for angles of 0 degrees and 180 degrees but I am having trouble working out the trigonometry to make the image move relative to the canvas, rather than to it's original orientation.
Demo jsfiddle: http://jsfiddle.net/jamesinealing/3chy076x/ (now updated with a fix as described below)
Excerpt:
ctx.rotate(angle * Math.PI / 180);
// this is where a formula is needed to get the correct pan values based on the angle
panXTransformed = panX * Math.cos(angle * Math.PI / 180);
panYTransformed = panY * Math.cos(angle * Math.PI / 180);
ctx.drawImage(pic, panXTransformed, panYTransformed, pic.width, pic.height);
You will see here that if you click in the canvas and drag vertically up and down the image moves towards the 'top' arrow of the image, not following the mouse to the top of the canvas. Try it at other angles and it exhibits a range of behaviours!
I know I need to bring in some factor to manipulate both X and Y with such movement, but I can't for the life of me find anything that works!
解决方案
通过更多的调查、反复试验和运气,找到了它!已经更新了小提琴 - http://jsfiddle.net/jamesinealing/3chy076x/ - 但对于那些发现自己有同样问题的人来说,这是重要的代码!关键在于将其分解,以便任何水平或垂直鼠标移动实际上都会导致旋转图像上成比例的 x 和 y 偏移,该偏移根据角度而变化(因此 90 度角意味着 x 鼠标移动被平移100% 进入 y 图像移动等)
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.save();
ctx.translate((canvas.width - pic.width) / 2, (canvas.height - pic.height) / 2);
ctx.rotate(angle * Math.PI / 180);
// now set the correct pan values based on the angle
panXX = (panX*(Math.cos(angle * Math.PI / 180)));
panXY = (panY*(Math.sin(angle * Math.PI / 180)));
panYY = (panY*(Math.cos(angle * Math.PI / 180)));
panYX = (panX*(Math.sin(angle * Math.PI / 180)));
panXTransformed = panXX+panXY;
panYTransformed = panYY-panYX;
ctx.drawImage(pic, panXTransformed, panYTransformed, pic.width, pic.height);
ctx.fillStyle="#0000FF";
ctx.fillRect(0,0,5,5); // place marker at 0,0 for reference
ctx.fillStyle="#FF0000";
ctx.fillRect(panXTransformed, panYTransformed,5,5); // place marker at current tranform point
ctx.restore();
推荐阅读
- exception - 在 ABAP 中使用自定义消息引发异常
- sql-server - 使用 Sql 获取输出中的特定单词
- angular - 无法通过 javascricpt 分配 rowTemplate
- html - 如何在 html 中显示浏览器的默认主题背景?
- java - 使用@Query 从 SPRING BOOT 中的文件中获取查询
- php - 无法将值从 Node Js 传递给 php 并返回
- sql - 在 int 列问题 SQL Server 上前导 0
- java - SwingUtilities.invokeLater 什么都不做
- powershell - 使用 PowerShell Invoke-RestMethod 查询 MSGraph API 不会返回与 MSGraph Explorer 相同数量的详细信息
- tmux - tmux 附加和当前工作目录