第一步是跟踪图像的绝对位置。为此,我在全局中添加了这个:
var ix=0, iy=0;
接下来,在mousemove
事件中,我们计算新位置和旧位置之间的差异:
var dx = x - startX;
var dy = y - startY;
然后我们需要找到缩放后的图像和画布之间的差异。由于画布不知道它被缩放(有点 - 我们使用的坐标一如既往地是 1:1),我们需要与画布的缩放大小进行比较。由于我们跟踪当前比例,我们只需将其乘以一个因子,减去图像尺寸并将所有内容除以 2 以使其居中:
var diffX = (canvas.width * currentScale - image.width) / 2;
var diffY = (canvas.height * currentScale - image.height) / 2;
现在我们可以检查我们的边界——如果在外面我们将 delta 值重置为 0,那么什么都不会被翻译:
if (ix + dx < -diffX ||
ix + dx + image.width > canvas.width * currentScale - diffX) dx = 0;
if (iy + dy < -diffY ||
iy + dy + image.height > canvas.height * currentScale - diffY) dy = 0;
最后,我们使用我们拥有的 delta 值更新翻译:
ix += dx; //image position
iy += dy;
element.translate(dx, dy);
因为如果外部边界没有任何变化,那么增量将为 0,在这种情况下,每个轴都是分开的。如上所述,我们使用坐标就像没有缩放和旋转一样,因为画布仅将我们拥有的内容投影到平移矩阵。因此我们不需要担心旋转。
结果演示在这里:
Modified fiddle
此外 - 当我们在移动图像以使鼠标光标在画布之外时遇到风险时,鼠标向上事件将永远不会在画布上注册。因此,我们改为听窗口,所以我们确定(除了在 iframe 中作为小提琴时)我们可以重置移动:
window.onmouseup = function (e) {
isDown = false;
}