Как стать автором
Обновить

Комментарии 96

— Я не хочу ничего читать, давай результат!
За это спасибо!
НЛО прилетело и опубликовало эту надпись здесь
Там случайные названия от Марсианских до Перловых. А вот легко на хтмл5 сделать так, чтобы планеты всегда смотрели на солнце одной стороной, как Луна на Землю?
Уже сделал.

ctx.save();
ctx.translate(x, y); // Точка, в которой должен был бы находиться верхний левый угол картинки
ctx.rotate(Math.atan2(wy - y, wx - x) + Math.PI / 2); // wy, wx точка, относительно которой поворачиваем картинку
ctx.drawImage(img, -width / 2, -height / 2); // Рисуем точку в положении минус половина ширины / высоты
ctx.restore();
А можете пояснить, почему нужно рисовать «в положении минус половина ширины/высоты»? На MDN не смог найти, как работают отрицательные значения координат.
Картинка вращается вокруг своего центра, соответственно и расчет поворота идёт относительно центральной точки (x + width / 2, y + height / 2). Функция drawImage рисует изображение относительно её левого верхнего угла вправо вниз. Чтобы уравнять это несоответствие сдвигаем картинку влево и вверх на половину ширины и высоты.

Отрицательные значения координат просто сдвинут изображение в невидимую область и всё. Если бы я не применял трансформацию, то на рисовалась бы правая нижняя четверть картинки.
Спасибо! С вращением планеты напутал — перепутал радиусы орбиты и самой планеты (тайла). Пора спать :)
Небольшая ошибка в вычислении угла — радиус вектор от центра солнца надо проводить к центру планеты, а не к верхнему левому углу. На больших радиусах планетарных орбит это не заметно, на малых — видно.
Извиняюсь, совсем забыл что в функцию значение со смещением передаю.
А если в реальном масштабе расстояния хотя бы сделать?
НЛО прилетело и опубликовало эту надпись здесь
я бы сказал на совместных мониторах невозможно.
Еще и размеры планет и солнца прилично различаются :)
— Изобразим Землю в виде шарика около 1 мм диаметром (размер булавочной головки или песчинки)
— Луна была бы в виде крупинки в 1/4 мм диаметром и находилась бы на расстоянии 30 мм
— Солнце было бы величиной с мяч (10 см) и будет находится на расстоянии 10 м от Земли
— В 16 м от мяча-Солнца кружится Марс – крупинка в 1/2 мм поперечником.
— Каждые 15 лет обе крупинки, Земля и Марс, сближаются на кратчайшее расстояние в 4 м
— Юпитер будет представлен шариком величиной с орех (10 мм) в 52 м от Солнца
— Наиболее удаленный из спутников Юпитера, пришлось бы поместить в 2 м от него
— Таким образом система Юпитера имеет диаметр 4 м (при этом диаметр орбиты Юпитера 104 метра — размер футбольного поля), а система Земля – Луна диаметр 6 см
— Сатурн пришлось бы поместить в 100 м от Солнца в виде орешка 8 мм диаметром
— Кольца Сатурна шириной 4 мм и толщиной 1/2 мм будут находиться в 1 мм от поверхности планеты
— Уран — это горошина диаметром 3 мм, в нашей модели он отброшен на 196 м от Солнца
— В 300 м от центрального шара медлительно совершает свой путь Нептун
— Вспомним что в нашей модели Солнце изображается шаром 10 см в диаметре, а вот вся планетная система в диаметре составит 800 м!
P.S. В нашей системе Проксима Центавра (самая близкая звезда) оказалась бы на расстоянии 2700 км
(С) «Занимательная астрономия» Я. И. Перельман
Эта задача не симуляция солнечной системы. Это анимация для игры, для стратегии. Вас же не смущает, что в играх серии Civilization юниты размером с гору, а в Victoria вообще с небольшое государство. Так же и тут — это просто схема.
Зачем? Это техническая статья. Речь идет об оптимизации скорости работы графических эффектов, и о том как легко/тяжело их реализовать на HTML5. Реалистичность эффектов не имеет никакого значения. Откуда всегда такие вопросы? Что у вас в головах?
Вот и интересно, канвас масштаб такой потянет.
Канвас — это битмапка в памяти, по 4 байта на пиксель. Потянет столько, сколько влезет в оперативку и своп. Канвасы порядка 10000×10000 я создавал. Ещё вроде как в некоторых браузерах возникают проблемы, если одна из координат превышает 32000. По факту же не стоит создавать канвас размером больше, чем монитор — пожалейте память клиента. Прокрутку можно эмулировать хоть на бесконечном холсте.
Прокрутку можно эмулировать хоть на бесконечном холсте.

Вот я таки не придумал, как сделать быструю прокрутку без видео-ускорения. Единственный способ, который работает вменяемо везде — отрисовать в большой холст всё, а показывать только часть, остальное скрывать при помощи DOM. Вот пример, холст 7к*4к, двигается как гуглокарты, работает шустро и без проблем, около 100 мб памяти на его хранение, но карта реально большущая получается:
libcanvas.github.com/games/dune/
play-dune.com/
Попробуй посмотреть, как реализована карта здесь.
Может натолкнуть на размышления.
Нуууу… Маленький экран, проц загружён постоянно, обновления редкие, скроллинг делается резким сдвигом, а не плавно. Вполне возможно, что просто перерисовывается вся рабочая область. Как-то хотелось бы что-то пошустрее…
нужно сделать fullscreen-патч ^_^
А это твоё творение?
Нет. Жаль, но нет. Я пока-что не на столько крут.
Скажу что это очень хороший способ. Уже проверил. Но у него есть один недостаток, нужно очень быстро отрисовать новый контент при достижении грани холста и создать механизм обратного прыжка, обычно его проблематично синхронизировать с рисовкой.

Если мы рисуем по принципу «кадров» т.е. имеем fps, то нужно создать достаточный запас канвы, чтоб пользователь не увидел границы канваса при перетаскивании.

Если мы риусем по событиям, у нас уже полностью пропадает понятие кадров, то нужно обеспечить скорость полной перерисовки холста за 20-30мс, т.к. на это время подвисает браузер и при драге карты все зависает.
Чтобы не задавать таких вопросов — подучите астрономию (хотя-бы школьный курс).
А зачем звезде орбита?
В авроре таки подлагивает, но не так плохо как могло бы.
Текст в информации штырит жутко же.
Проблема с прокруткой существовавшая у предыдущего реализатора решена Вами кардинально, я вижу :)

А в остальном, good job, посмотрим, что скажет RussianSpy.
Это просто круг для выделения (у планет, помимо орбит тоже есть этот круг). Меня тоже поначалу смутило.
Только поначалу? А потом, ничего, втянулись? :D
Ну так у звёзд тоже есть орбиты, просто они более глобальные :)
Что за проблема с прокруткой?
В прошлом примере ломалось выделение орбит и планеток, если сжать окно и прокрутить вниз. В последствии было исправлено, да.
В Chrome 23.0.1271.97 m, Win 8 x64, планета не останавливается по клику.
А так — отлично!)
+1, условия те же.
Уже останавливаются :)
НЛО прилетело и опубликовало эту надпись здесь
Исправил.
НЛО прилетело и опубликовало эту надпись здесь
В мобильном Safari подергивается, видно что телефон напрягается. В версии с LibCanvas такого нет.
Не могу проверить, но полагаю что LibCanvas несколько оптимизирован для мобильных устройств.
Не могу проверить, но полагаю что LibCanvas несколько оптимизирован для мобильных устройств.

Ну во-первых та разница в два процента между LibCanvas и вашим приложением — скорее в рамках погрешности.

Ничего особого для мобильных устройств не делалось. Основной секрет в отвратительной строчке
ctx.clearRect(0, 0, canvas.width, canvas.height);   // Очистить всё


Она, конечно, позволяет не париться и рисовать всё «втупую» без кучи слоёв и всего остального, но только пока у вас нормальный браузер и компьютер.

На мобильных же устройствах и устройствах без аппаратного ускорения (в моём Линуксе аппаратное ускорение для Холста не работает) такой подход съедает львиную долю всей производительности:

Ваш:

LibCanvas-based


Именно потому на мобильных устройствах моя версия лучше работает)

Но всё-равно спасибо за ваш код)
Зато я памяти меньше кушаю!
С мобильными устройствами конечно проблема :(
Ну естественно) Мой вариант при старте загружает AtomJS и LibCanvas — там создаётся куча классов и дополнительных материалов, которые как раз и занимают эти 8 метров. Не думаю, что это очень критично в реальном приложении))

А подход описанный в статье работает только на узком спектре мощных устройств. Мне в своё время пришлось LibCanvas перепилить, чтобы от него отказаться)
У меня же должны быть преимущества, раз тут такая проблема с телефонами :)
Но вообще буду объективным — приложение отлично написанное исключительно под задачу будет однозначно производительнее приложения, написанном на универсальном фреймворке)
Подскажите, а как у вас решена эта проблема? Можете об этом рассказать (или уже есть где почитать)? Как я понимаю, это код в районе clearPrevious и сохранения формы при drawElements?
Как я понимаю, это код в районе clearPrevious и сохранения формы при drawElements?

По сути — да, правильно понимаете)

Код отрисовки кадра:

// функция слоя, которая вызывается каждый кадр
draw: function () {
	var
		ctx = this.dom.canvas.ctx,
		resources = this.app.resources;

	// добавляем в список отрисовки элементы, которые
	// пересекаются с теми которые отправлены на отрисовку
	if (this.settings.get('intersection') === 'auto') {
		this.addIntersections();
	}

	// На случай, если активирован режим "перерисовывать всё"
	// необходимо в первую очередь стереть удалённые элементы
	if (this.shouldRedrawAll) {
		atom.array.invoke(this.clear, 'clearPrevious', ctx, resources);
	}

	// Потом стираем старые позиции из списка отрисовки
	// При режиме "перерисовывать всё" этот список указывает на все элементы
	atom.array.invoke(this.redraw, 'clearPrevious', ctx, resources);

	// После этого отрисовываем текущие элементы
	this.drawElements(this.redraw, ctx, resources);

	// Чистим списки отрисовки
	if (this.shouldRedrawAll) {
		this.clear.length = 0;
	} else {
		this.redraw.length = 0;
	}
},

// перерисовка единственного элемента
drawElement: function (elem, ctx, resources) {
	// если так получилось, что элемент уже не часть слоя - не перерисовываем
	if (elem.layer == this) {
		// redrawRequested необходимо в целях оптимизации
		// снимаем флаг неоходимости отрисовка
		elem.redrawRequested = false;
		// отрисовываем элемент только если он видим
		if (elem.isVisible()) {
			// потом вызываем метод отрисовки элемента
			elem.renderToWrapper( ctx, resources );
			// сохраняем текущую обводщую фигуру
			// она будет использоваться в clearPrevious
			// и в addIntersections в следующем кадре
			elem.saveCurrentBoundingShape();
		}
	}
},	


Ну это как бы основная идея, там ещё небольшое количество мелочей.
А как быть, если надо восстановить фон, который был? Например, была отрисована некоторая фигура, затем в процессе анимации над ней была нарисована другая, на следующий кадр эта часть канваса просто очистится и первая фигура будет утрачена?
Именно за это и отвечает addIntersections ;)

upd: Можно посмотреть этот пример:
libcanvas.github.com/base/button.html

Двигайте одну кнопку поверх других и всё будет отрисовываться корректно)
Как я понял, она при каждой перерисовке элемента проходится по всем элементам и высчитывает пересечения? Это действительно настолько быстро?
Пока не жаловался. На большом количестве объектов это, конечно, не очень, но для этого у меня есть режим ручного управления перерисовкой) На обычных же приложениях это даёт нормальную скорость)
Вычислить пересечения всегда быстрее полной перерисовки.
Кроме крайнего случая, когда выгоднее перерисовывать всё)
Возможно, ещё имеет смысл сохранять то, что под объектом в скрытый и не перерисовывать объект снизу, а просто на его место отрисовывать предыдущий фон, но это тоже сомнительное решение — я не уверен, что будет желаемый результат, а потестить пока не доходили руки.
Делать конвейер сохраненных состояний, как-то так.
Объясните, что вы имеете ввиду)
Общая идея — в сложных объектах (где возможно много фонов) — в результат рисования формировать ступенчатую пачку отдельных canvas'ов, у каждого их которых будет свое состояние. Допустим, на уровень «орбиты» выплевывать [{c: planet, res:null, changed: false}, {c: planet, res: null, changed: true}, {c: back, res: null, changed: false}]. И если где-то на пути от back вверх по конвейеру мы встречаем changed:true — собираем новый результат в res следующего объекта и перерисовываем его.
Да, без реализации пока сложновато понять))
У вас, как мне кажется, примерно такая идея и звучала в топике. TheShock кинули в личку какой-то пример со скрытым канвасом, но на публику, реально ли увеличение призводительности с помощью этого или лучше делать как-то иначе, инфа не пошла :)
У меня всё никак не дойдут руки его потестить, тот пример(
Сорри, концепт на первых стадиях, и я до сих пор сам с трудом понимаю, чего же я хочу ^_^ Но, по идее, должно сработать.

В общем, как я и обещал — «далi будe»
Товарищи, нам пора делать отдельный хаб, я считаю. Или профсоревнование ^_^
НЛО прилетело и опубликовало эту надпись здесь
Всё хорошо, но этого нет в ТЗ. Тут уже… Кажется, с мая прошлого года над этой задачей люди копаются, а вы еще навороты предлагаете.
Тогда нужно сразу делать нормальную солнечную систему, с нормальными орбитами, скоростями, расстояниями. Если сессию переживу — займусь :)
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
На самом деле, орбиты планет в Солнечной системе хоть и эллиптические, но очень близки к круговым, а в масштабах экрана монитора они и будут круговыми. То есть, чтобы эллиптичность стала заметна, орбиту придётся сильно искажать: сильнее, чем в реальности. Такие вот дела.
НЛО прилетело и опубликовало эту надпись здесь
Ну да, Меркурий. А остальные планеты имеют близкие к круговым орбиты. Плутон так же имеет сильно вытянутую эллиптическую орбиту, но из состава планет он был официально исключён.
НЛО прилетело и опубликовало эту надпись здесь
Странный баг, оно само не прошло? Должно было в следующем кадре перерисовать.
Обводка планет как раз по центру, а вот сами планеты на своём текстурном изображении не очень ровно расположены.
Сделайте орбиты пересекающимися и эллептическими, скорость движения пусть немного увеличивается, планеты останавливаются только пока ты их держишь и столкновение планет пусть приводят к game end. В итоге готовая игра тайм-киллер. Дальше идею развивать можно сколько-угодно…
При чем тут идея? Есть ТЗ, на которые авторы статей опираются. Конкретно в данном случае даже это ТЗ реализовано не полностью. :)
Я лишь поделился идеей ;).
1. процессор ест чуть больше, чем вариант на libcanvas, но в моем случае не получается выбрать идеально совпадающий масштаб.
2. флеш версия жрет процессор меньше, чем все JS/CSS варианты и чем моя поделка на Silverlight
3. если бы каждый вариант создавался в отдельном топике, их было бы уже около десятка. может кто-то возьмется сделать в своем блоге что-то вроде конкурса, оценить на разных платформах и пр.?
У вас есть флеш версия? Сделайте статью на эту тему, защитите честь флеша :)
я не флешер, у меня есть версия на Silverlight. Ссылку см. выше или в предыдущем топике
но в моем случае не получается выбрать идеально совпадающий масштаб.

Объясните? Они ведь одинакового размера.

флеш версия жрет процессор меньше

какая из?
Объясните? Они ведь одинакового размера.

у меня разрешение 2560x1440, шрифты и размеры немного увеличены, потому все версии выглядят по-разному, если не масштабировать через Cmd+/Cmd-. Причем, в некоторых случаях изображение в центре экрана, в некоторых в рамке, в некоторых слева без рамки.
Вот два скриншота, сделанные один за другим, размеры подобраны одинаковые:
runserver.net/temp/libcanvas.png
runserver.net/temp/new.png

Вообще, в примере топикстартера меня смущает рандом иконок планет, названий, отсебятина в виде вращения спрайта вокруг своей оси. Все-таки, производительность надо замерять на идентичных примерах. Никто не сомневается в вашем умении сделать что-угодно, с любыми вариациями и карточными играми, но задача ведь сделать 1в1 как в эталонном примере. Резюмирую: раз залезли в нашу песочницу мерятся, так соблюдайте правила и не пользуйтесь виагрой :)
Увидел в коде интересный хак this.angle = ~~(Math.random() * 360); объяснение нашлось тут на стеке
я тоже вот сейчас сделал, хотел выложить, но опоздал.
ждал в этот момент апокалипсиса :)
Парад планет :)
На маленьком экране если планетка убежала за границу к ней не проскролишься, лекарство есть?
Извиняюсь, я скрол для боди выключил. Сейчас всё ок.
Дорогой Санта, я просил только одну Солнечную систему...
Шутки — шутками, но у ad hock решений, на мой взгляд, существует один общий большой недостаток — они призваны решить частную проблему частным способом. Возможно, они делают это оптимально для каждого конкретного случая. Но сам по себе такой подход мне кажется отнюдь не оптимальным.
Для примера: было создано по крайней мере несколько решений данного ТЗ:

Я придерживаюсь мнения, что ценны только те решения, которые сделаны на обобщенных инструментах для web-анимации, например таких, как LibCanvas или Three.js. Любые частные решения дают лишь сиюминутный профит, но почти не закладывают базиса для дальнейшего совершенствования и разработок. Для демонстрации возможностей API Canvas-а их может и хватает, но не более того. Мне кажется, что наиболее полезным приложением усилий были бы разработка и поддержка свободного движка для высокопроизводительных Web приложений, построенного исключительно на Canvas 2D API (а в дальнейшем и на 3D, если он все-таки будет). Чтобы показать пример, я решил начать с себя и в ближайшее время постараюсь представить библиотеку на 2D API, позволяющую решать не только такие простейшие вещи, как солнечная система, но и что-то посложнее, например, эффекты псевдообъемности, наложение текстур на поверхности и т.п.
НЛО прилетело и опубликовало эту надпись здесь
Я это и сказал в комментарии. Но, боюсь это все, на что они годятся. В стратегическом плане они не дают ничего.
НЛО прилетело и опубликовало эту надпись здесь
Ну, вот смотрите: у вас есть продукты, вода, соль и все что нужно для счастья, но чтобы позавтракать нужно выковать вилку, нож и ложку, сделать станок для изготовления сковородок и кастрюль, собрать печку и т.д. Когда вы уже закончили со всем этим и приступили к готовке, уже время ужина и ваши соседи, плотно поев, отправляются ко сну.
Фреймворк он потому так и называется, что не дает вам рыбу, но дает удочку, или бульдозер или кирпичный завод.
НЛО прилетело и опубликовало эту надпись здесь
Хорошо, если из свинца, а не из уникального суперсплава бумаги с картоном.
Мне кажется, что наиболее полезным приложением усилий были бы разработка и поддержка свободного движка для высокопроизводительных Web приложений, построенного исключительно на Canvas 2D API

Эээмс, LibCanvas?)
А с комментарием в целом согласен)
Во всем должна быть конкуренция ;)
Что ж вы все так конкурентов любите создавать? Их десятки уже) Направили бы эту энергию на улучшение существующих проверенных решений)
Да я не претендую на фреймворк. И даже не против плавно влиться в Ваше творение. Пока я стараюсь добиться определенных наработок, чтобы было о чем вообще говорить. Думаю, что если у меня получится задуманное, то и предметный разговор о том, делать из этого что-то свое, или интегрировать и развивать в LC, будет более уместен. Может Вы еще сами не захотите, как знать ).
Интересно) Жду, пишите)
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории