Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   canvas.transform на лету (https://javascript.ru/forum/dom-window/22598-canvas-transform-na-letu.html)

nixy 26.10.2011 01:28

canvas.transform на лету
 
Здравствуйте.

Подскажите существует ли возможность вначале нарисовать на canvas что-либо, и уже после этого оперировать трансформациями с этой канвой, чтобы изображение менялось?
Или всё равно придётся постоянно перерисовывать с новой трансформацией изображение на канве?

Если другими словами, то вот здесь имеется достаточное количество примеров с трансформациями.
В них трансформации всегда задаются до отрисовки "фигур":
...
ctx.translate(x,y);
drawSpirograph(ctx,x1,y1);
...
ctx.translate(100,0);
ctx.scale(0.75,0.75);
drawSpirograph(ctx,22,6,5);
...
и т.д.

Однако если поменять местами строки вот как-то так:
drawSpirograph(ctx,22,6,5);
ctx.translate(100,0);
то тут само собой трансформация уже не подцепится, и фигура нарисуется в оригинале.

dmitriymar 26.10.2011 09:30

Цитата:

Сообщение от nixy
Или всё равно придётся постоянно перерисовывать с новой трансформацией изображение на канве?

перерисовывать

nixy 26.10.2011 09:58

Тогда получается, что метод буферизации, о котором говориться например здесь в пункте 21 или вот здесь, в случае использования "пост-трансформации" полностью теряет смысл?
А в выше написанных ссылках канву из буфера можно достать лишь в её оригинале, как она была инициализирована изначально?

dmitriymar 26.10.2011 10:26

Цитата:

Сообщение от nixy
Тогда получается, что метод буферизации, о котором говориться например здесь в пункте 21 или вот здесь, в случае использования "пост-трансформации" полностью теряет смысл?

смысл в том что они сохранят изображение с канвы в объекте, делают трансформацию и вставляют изображение-так выходит чуть быстрее.но для этого вторая канва не нужна
Цитата:

Сообщение от nixy
А в выше написанных ссылках канву из буфера можно достать лишь в её оригинале, как она была инициализирована изначально?

любое изображение после трансформации вставляется в оригинале,трансформируетс сам холст

nixy 26.10.2011 12:29

Цитата:

они сохраняют изображение с канвы в объекте... но для этого вторая канва не нужна
но ведь этот объект и есть вторая канва-буфер (или же её контекст), разве нет?

Цитата:

сохранят изображение с канвы в объекте, делают трансформацию и вставляют
если я правильно понимаю, то для этих трёх действий необходимо следующее:

- создать объект, куда сохранять оригинал
buffer = document.createElement('canvas').getContext('2d')

- сохранить в buffer изображение-оригинал
buffer.всяческое_рисование()

- сделать его трансформацию примерно вот так:
sub_buffer.setTransform(..матрица..)
sub_buffer.drawImage(buffer.canvas,0,0)
(sub_buffer необходим для сохранения в нём трансформированного основного буфера buffer)

- вставить трансформированную "под-канву" на основную канву странички
context.imageDraw(sub_buffer.canvas,0,0)

В принципе это всё работает, но исходя из бытовой логики, где:
Цитата:

трансформируется сам холст
как бы этот холст странсформировать, с уже находящемся на нём контентом. Т.к. где-то в глубине кроется предчувствие, что возможно выкинуть из кода строки
sub_buffer.setTransform(..матрица..)
sub_buffer.drawImage(buffer.canvas,0,0)
как и сам промежуточный sub_buffer, и вместо этого вписать
buffer.setTransform(..матрица..)
buffer.ReDraw() // которого, к сожалению не существует =(
context.imageDraw(buffer.canvas,0,0).

Я описал упрощенный пример для одного буфера. Но если предположить, что на страничке уже не один буфер, а целый массив, в нём лежит штук 100 картинок, и для каждой картинки на каждый маусМув присваивается своя трансформация, и потом это всё отрисовывается на основной канве, то я подумал не будет ли лишним избавиться от хотя бы одного промежуточного drawImage.

А в примерах нет именно трансформации буфера, поэтому там такой элегантный код, и нету этого промежуточного sub_buffer.

dmitriymar 26.10.2011 12:50

Цитата:

Сообщение от nixy
как бы этот холст странсформировать, с уже находящемся на нём контентом. Т.к. где-то в глубине кроется предчувствие, что возможно выкинуть из кода строки

никак.
Цитата:

Сообщение от nixy
А в примерах нет именно трансформации буфера, поэтому там такой элегантный код, и нету этого промежуточного sub_buffer

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

dmitriymar 26.10.2011 12:54

Цитата:

Сообщение от nixy
- сохранить в buffer изображение-оригинал
buffer.всяческое_рисование()

- сделать его трансформацию примерно вот так:
sub_buffer.setTransform(..матрица..)
sub_buffer.drawImage(buffer.canvas,0,0)

трансформации Всегда производятся до рисования объекта нуждающегося в трансформации
и вариант с буфером (трансформировать участок и вставить на остальное ) при переносе изображений с прозрачным фоном-необходимо его ещё обрабатывать пред вставкой(времени гораздо больше чем трансформировать основную и вставить изображение).так что выигрыш сомнителен,а точнее "выигрыш" со знаком минус

да и последовательность у вас не правильная-последовательность тогоже без библиотек
канва2.transform(....)transform-образно
канва2.drawImage(....)
канва2.getImage(....)
канва1.putImage(....)

drawImage-не работает с объектом изображения забранным из канвы эт раз.-значит производятся преобразования-это время по любому
два-использование сторонних не способствует увеличению быстродействия поскольку они в большинстве своём пишутся на все случаи жизни

nixy 26.10.2011 15:44

dmitriymar, спасибо за ответы.

Итог таков:

1. если замостить всю канву размером эдак 1500на1000px мелкими картинками (200на150px) и на каждый маусМув трансформировать и перерисовывать все картинки (100-150 штук), то в целом на Core2Duo работает вполне прилично, можно юзать.

2. визуально разница между:
sub_buffer.setTransform(...)
sub_buffer.drawImage(buffer.canvas,0,0)
context.drawImage(sub_buffer.canvas,0,0)
и
канва2.transform(....)
канва2.drawImage(....)
канва2.getImage(....)
канва1.putImage(....)
...
лучше в пользу get/put, вопреки пункту 26, однако пока проверить удалось только в Опере, т.к. всё остальное категорически не хочет принимать get/putImageData, пишет ошибку "security error code 1000 NS_ERROR_DOM_SECURITY_ERR". Про эту ошибку уже были подобные вопросы, но у меня пока не получается запустить под FF, может кто подскажет что еще можно сделать с картинкой, чтобы методы get/put заработали (картинка лежит в той же папке, что и *.html файл).

3. если делать всё тоже самое как в пункте 1, только без трансформаций и вставлять из буфера оригинал, то картинка "летает", визуальных тормозов вообще не видно. Но и тут метод get/put летает лучше drawImage.

dmitriymar 26.10.2011 19:04

Цитата:

Сообщение от nixy
"security error code 1000 NS_ERROR_DOM_SECURITY_ERR".

getImage работает только если изображение загружено с того же сайта что и страница(проверку нужно делать используя сервер).если даже локально лежат в одной папке(но не локальном сервере)-будет эта ошибка

nixy 26.10.2011 22:04

dmitriymar, можете посоветовать какие-нть ресурсы, где можно почитать про слоёную канву, или примеры реализации.


Часовой пояс GMT +3, время: 11:07.