Збільшити полотно до курсору миші


78

Я програмую проект HTML5 <canvas>, який передбачає збільшення та зменшення зображень за допомогою колеса прокрутки. Я хочу наблизити курсор, як це робить google maps, але я повністю заблукав, як розрахувати рухи.

Що у мене є: зображення x та y (верхній лівий кут); ширина та висота зображення; курсор x та y щодо центру полотна.


15
ви повинні прийняти цю відповідь або переглянути своє запитання
ghayes

Відповіді:


236

Коротше кажучи, ви хочете, щоб translate()контекст полотна здійснювався за вашим зміщенням, scale()його збільшували або зменшували, а потім translate()повертали назад, протилежно від зміщення миші. Зверніть увагу, що вам потрібно перетворити позицію курсора з простору екрана в перетворений контекст полотна.

ctx.translate(pt.x,pt.y);
ctx.scale(factor,factor);
ctx.translate(-pt.x,-pt.y);

Демонстрація: http://phrogz.net/tmp/canvas_zoom_to_cursor.html

Я розмістив на своєму веб-сайті повний робочий приклад, який ви можете вивчити, підтримуючи перетягування, клацніть, щоб збільшити, клацніть клавішу Shift, щоб прокрутити вгору / вниз.

Єдина (поточна) проблема полягає в тому, що Safari масштабується занадто швидко в порівнянні з Chrome або Firefox.


2
Приємні зусилля на прикладі. Дякую!
Mikael Eliasson

4
Ого, @phrogz, ти пішов і вище, і далі!
snapfractalpop

1
Привіт @Phrogz це чудово! Мені просто цікаво, чи можна обмежити перетягування так, щоб не можна було перетягувати зображення за межі. Якщо більше немає зображення для перетягування, перетягування має просто зупинитися там, а не дозволяти перетягувати невизначено довго. Я вдарився, але, здається, я не можу правильно зрозуміти математику :-(
Крістоф,

2
@Christoph це легко. отримати шкалу - масштаб можна взяти з: var scale = ctx.getTransform (). a; потім прийміть поточне ліве верхнє положення зображення: var curX = ctx.getTransform (). e; var curY = ctx.getTransform (). f; оцінити зміну положення: var deltaX = pt.x - dragStart.x; var deltaY = pt.y - dragStart.y; тоді є оригінальний розмір зображення, давайте візьмемо, наприклад, ширину (коли масштаб = 1): imageW і є ширина полотна: canvasW, тоді умова повинна бути хибною, щоб дозволити перетягування: curX + deltaX + imageW * масштаб <canvasW і ще один ( curX + deltaX> 0 || curY + deltaY> 0)
максимум

1
Чи важко це реалізувати на мобільних пристроях за допомогою жестів? Мовляв, дозволити 2 пальцем стиснути, щоб збільшити лише зображення, але не весь веб-сайт?
Thomas Stock


11

Нещодавно мені потрібно було архівувати ті самі результати, що вже робив Phrogz, але замість того, щоб використовувати context.scale(), я розрахував розмір кожного об’єкта на основі співвідношення.

Це те, що я придумав. Логіка за цим дуже проста. Перед масштабуванням я обчислюю точкову відстань від краю у відсотках, а пізніше налаштовую область перегляду в потрібне місце.

Мені знадобився досить довгий час, щоб це придумати, сподіваюся, це економить хтось.


6

Я взяв відповідь @ Phrogz за основу і створив невелику бібліотеку, яка дозволяє полотно перетягувати, масштабувати та обертати. Ось приклад.

var canvas = document.getElementById('canvas')
//assuming that @param draw is a function where you do your main drawing.
var control = new CanvasManipulation(canvas, draw)
control.init()
control.layout()
//now you can drag, zoom and rotate in canvas

Ви можете знайти більш докладні приклади і документацію по проекту сторінки

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.