Первый шаг - отслеживать абсолютное положение изображения. Для этого я добавил это в глобальном:
var ix=0, iy=0;
Далее на mousemove
случае мы вычисляем разницу между новым положением и старым:
var dx = x - startX;
var dy = y - startY;
И тогда нам нужно найти с diffence между увеличенным изображением и холстом. Поскольку холст не знает, что он увеличен (вид - используемые нами координаты находятся в 1: 1, как всегда), нам нужно сравнить с масштабированным размером холста. Поскольку мы отслеживаем текущий масштаб мы просто умножать с теми, как фактор, вычитает размер изображения и разделить все на 2, чтобы расположить его в центре:
var diffX = (canvas.width * currentScale - image.width)/2;
var diffY = (canvas.height * currentScale - image.height)/2;
Теперь мы можем проверить наши границы - если снаружи мы сбрасываем значение дельты 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;
И, наконец, мы обновляем переводим со значениями дельты мы имеем:
ix += dx; //image position
iy += dy;
element.translate(dx, dy);
в дельте будет 0, если за пределы Его ndaries ничего не меняется в этом случае отдельно для каждой оси. Как упоминалось выше, мы используем координаты, как если бы ничто не масштабировалось и не вращалось как холст только проект что мы имеем для матрицы перевода. Поэтому нам не нужно беспокоиться о ротации.
Результирующая демо здесь:
Modified fiddle
Кроме того - как мы столкнулись с риском при перемещении изображения вокруг, чтобы курсор мыши за пределами холста, мышь вверх событие никогда не будет зарегистрируйтесь на холсте. Поэтому мы прислушиваемся к окну, поэтому мы уверены (за исключением случаев, когда в iframe как на скрипке), что мы можем сбросить перемещение:
window.onmouseup = function (e) {
isDown = false;
}