Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 06.04.2015, 10:53
Аватар для khusamov
Соединяю Node.js и Ext JS
Отправить личное сообщение для khusamov Посмотреть профиль Найти все сообщения от khusamov
 
Регистрация: 25.06.2009
Сообщений: 1,033

2D Масштабирование и перемещение
Здравствуйте!

У меня задача сделать масштабирование при помощи колесика мыши на холсте SVG. Причем масштабирование делается через точку, которая в момент действия находится под курсором мыши. Ну, аналогично как это сделано в векторных редакторах.

Проблема в том, что работает это, но плохо. Сначала нормально, а потом точка масштабирования не совпадает с точкой курсора мыши.

Вот код:

// Единичная матрица
var matrixPrevious = Ext.create("Ext.draw.Matrix", 1, 0, 0, 1, 0, 0);

me.getEl().on("mousewheel", function(e) {

	// Здесь по событию от колесика мыши выбирается коэффициент масштабирования
	var scale = e.event.wheelDelta > 0 ? 1.2 : 0.8;
	
	// Создаю матрицу масштабирования
	var matrixScale = Ext.create("Ext.draw.Matrix", scale, 0, 0, scale, 0, 0);
	
	// Вычисляю координаты курсора мыши относительно холста SVG
	x = e.pageX - me.getX();
	y = e.pageY - me.getY();

	// Вычисляю смещение относительно мыши и необходимого положения масштабируемого изображения	
	var offsetX = x * (1 - scale);
	var offsetY = y * (1 - scale);
	
	// Создаю матрицу перемещения
	var matrixTranslate = Ext.create("Ext.draw.Matrix", 1, 0, 0, 1, offsetX, offsetY);
	
	// Беру предыдущую матрицу
	var matrixResult = matrixPrevious;

	// Все матрицы соединяю умножением
	matrixResult.multiply(matrixTranslate);
	matrixResult.multiply(matrixScale);

	// Применяю матрицу к элементу SVG-холста	
	me.getSurface().matrix(matrixResult);
	
	// Сохраняю матрицу как предыдущую, чтобы в следующей итерации ее использовать
	// для относительных трансформаций
	matrixPrevious = matrixResult;
	
});


У меня есть подозрения, что масштабирования я сделал относительное, а вот перемещение похоже не совсем относительное. Но как это исправить пока не знаю.

Последний раз редактировалось khusamov, 06.04.2015 в 13:48.
Ответить с цитированием
  #2 (permalink)  
Старый 06.04.2015, 12:45
Аватар для Safort
Профессор
Отправить личное сообщение для Safort Посмотреть профиль Найти все сообщения от Safort
 
Регистрация: 23.12.2013
Сообщений: 1,856

Может лучше использовать snap.svg для этой цели?
http://jsfiddle.net/AGq9X/5/
http://snapsvg.io/docs/#Matrix.scale
Ответить с цитированием
  #3 (permalink)  
Старый 06.04.2015, 12:47
Аватар для khusamov
Соединяю Node.js и Ext JS
Отправить личное сообщение для khusamov Посмотреть профиль Найти все сообщения от khusamov
 
Регистрация: 25.06.2009
Сообщений: 1,033

Но это ведь не отменяет создание матрицы?
Ответить с цитированием
  #4 (permalink)  
Старый 06.04.2015, 13:11
Аватар для trikadin
Модератор
Отправить личное сообщение для trikadin Посмотреть профиль Найти все сообщения от trikadin
 
Регистрация: 27.04.2010
Сообщений: 3,417

Что-то непонятно, что здесь происходит.

// Вычисляю координаты курсора мыши относительно холста SVG
/*
Вот здесь получаются реальные (экранные) пиксели. А дальше я не вижу, 
чтобы ты их переводил в свои сабпиксели (то есть, ты не учитываешь уже
существующее масштабирование)

*/
    x = e.pageX - me.getX();
    y = e.pageY - me.getY();

/*
Вот где-то здесь тебе надо бы x и у умножить на текущий scale
*/
 
    // Вычисляю смещение относительно мыши и необходимого положения масштабируемого изображения
    var offsetX = x - x * scale;
    var offsetY = y - y * scale;
__________________
Читайте:
Ты любопытный) Всё-таки, ничему в этом мире не помешает хорошая доля юмора)
Как спросить, чтобы вам ответили
Часто Задаваемые Вопросы (FAQ)
Ответить с цитированием
  #5 (permalink)  
Старый 06.04.2015, 13:18
Аватар для khusamov
Соединяю Node.js и Ext JS
Отправить личное сообщение для khusamov Посмотреть профиль Найти все сообщения от khusamov
 
Регистрация: 25.06.2009
Сообщений: 1,033

А как их переводить? У меня когда изначально масштаб 1:1 стоит, то пиксель изображения равен пикселу экрана. А вот когда накладывается transform, то уже они меняются.

Вот куда текущий scale приложить так и не понял.
Ответить с цитированием
  #6 (permalink)  
Старый 06.04.2015, 13:23
Аватар для khusamov
Соединяю Node.js и Ext JS
Отправить личное сообщение для khusamov Посмотреть профиль Найти все сообщения от khusamov
 
Регистрация: 25.06.2009
Сообщений: 1,033

Я взял формулу отсюда http://xiper.net/learn/svg/svg-essen...a-center-point

но там расписано как смасштабировать один раз. А что делать, когда надо потом (колесико мыши крутится же дальше) еще раз смасштабировать?

Я думал что нужно просто умножать новую матрицу на существующую.
Ответить с цитированием
  #7 (permalink)  
Старый 06.04.2015, 13:44
Аватар для trikadin
Модератор
Отправить личное сообщение для trikadin Посмотреть профиль Найти все сообщения от trikadin
 
Регистрация: 27.04.2010
Сообщений: 3,417

khusamov, если вы в точности придерживаетесь того, что там описываете, то для масштабирования при прокрутке вам нужно завести отдельную переменную для scale, в которой хранится текущее значение масштабирования. При прокрутке колесика вы:
1) прибавляете к текущему значению scale deltaWheel (scale += deltaWheel)
2) масштабируете оригинальное изображение с текущим (только что записанным) значением scale
__________________
Читайте:
Ты любопытный) Всё-таки, ничему в этом мире не помешает хорошая доля юмора)
Как спросить, чтобы вам ответили
Часто Задаваемые Вопросы (FAQ)
Ответить с цитированием
  #8 (permalink)  
Старый 06.04.2015, 13:46
Аватар для khusamov
Соединяю Node.js и Ext JS
Отправить личное сообщение для khusamov Посмотреть профиль Найти все сообщения от khusamov
 
Регистрация: 25.06.2009
Сообщений: 1,033

У меня для этой цели заведена специальная матрица. Она сначала пустая (нули для смещений, и 1-ки для масштаба). А потом приращения масштаба туда записываются.

var matrixPrevious = Ext.create("Ext.draw.Matrix", 1, 0, 0, 1, 0, 0);

Последний раз редактировалось khusamov, 06.04.2015 в 13:48.
Ответить с цитированием
  #9 (permalink)  
Старый 06.04.2015, 13:49
Аватар для trikadin
Модератор
Отправить личное сообщение для trikadin Посмотреть профиль Найти все сообщения от trikadin
 
Регистрация: 27.04.2010
Сообщений: 3,417

khusamov, дайте пример? Где-нить здесь.
http://jsfiddle.net/
__________________
Читайте:
Ты любопытный) Всё-таки, ничему в этом мире не помешает хорошая доля юмора)
Как спросить, чтобы вам ответили
Часто Задаваемые Вопросы (FAQ)
Ответить с цитированием
  #10 (permalink)  
Старый 06.04.2015, 13:51
Аватар для khusamov
Соединяю Node.js и Ext JS
Отправить личное сообщение для khusamov Посмотреть профиль Найти все сообщения от khusamov
 
Регистрация: 25.06.2009
Сообщений: 1,033

Я готовлю пример. Там у меня куча моих классов. Надо как-то их все разместить.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как отключить масштабирование перетаскиваемых элементов? danik.js Firefox/Mozilla 2 18.11.2013 17:09
Перемещение объектов, последовательность событий prizrak39 Events/DOM/Window 3 19.11.2012 13:42
Масштабирование изображений по курсору Eugent ExtJS 1 22.03.2012 14:55
Перемещение, вращение, масштабирование div'a den_zm Dojo toolkit 1 13.10.2011 18:41
Grid - roweditor плавное перемещение Jevgeny ExtJS 2 26.10.2010 14:43