10 заметок с тегом

canvas

Генерируемый задний фон

Я как-то пропустил знаменитую (оказывается) программу для генерации фона, похожего на лабиринт из двух слешей. Несложная программа на Бейсике:

10 PRINT CHR$(205.5+RND(1));: GOTO 10

Выводит вот такой фон (скриншот с «Командора 64», поэтому цвета такие):

Фон из слешей (27.66КиБ)

Для тех, кто не понимает этот архаичный язык, перепишу на Пайтоне:

import random; while 1: print random.choice(u'╱╲'),

и ПХП:

for(;;) flush(print '/\\'[mt_rand(0, 1)+.5]);

На «Хабре» статья пробегала, где автор пытался сделать то же при помощи CSS, не справился и сделал генерацию на серверной стороне — на PHP. Он высказывал мысль использовать для этого JS, но то ли не справился, то ли отбросил её по каким-то иным причинам.

В общем, решил я попробовать сделать это на стороне клиента, на «канвасе», заодно посмотреть конструкции, которые позволяют ставить «канвас» в качестве задника, давно руки чесались.

Сначала результат (в левом верхнем углу фрагмент нормального размера):

Фон в виде лабиринта (31.46КиБ)

Теперь посмотрим код. Я убрал всё лишнее, подробности можно посмотреть в разделе «Храню»:

!function(c) {
    var ctx = document.getCSSCanvasContext ? 
        document.getCSSCanvasContext("2d", "maze", c.width, c.height):
        c.getContext("2d");

    ctx.font      = "10px monospace";
    ctx.fillStyle = '#36f';
    ctx.fillRect(0, 0, c.width, c.height);

    ctx.fillStyle = '#068';

    for (var y = 7, ly = c.height; y < ly; y += 8) {
        for (var x = -1, lx = c.width; x < lx; x+= 4) {
            ctx.fillText("/\\".charAt(Math.random() + .5), x, y);
        }
    }

    if (!document.mozSetImageElement && !document.getCSSCanvasContext) {
        document.getElementsByTagName('body')[0].style.backgroundImage='url(' + c.toDataURL("image/png") + ')';
    }

}(document.getElementById('maze'));

Внутрь функции у меня передаётся объект «канваса» (размером 99×96, подогнан под шрифт).

В первой строке проверяется наличие метода «getCSSCanvasContext», он работает только в браузерах, основанных на Вебките (Хром, Сафари) и позволяет напрямую использовать «канвас» для задника, нужно только в CSS указать идентификатор:

body { background: -webkit-canvas(maze); }

Если этот метод недоступен, то я рисую в скрытый тег «канваса», который есть у меня на странице. Вывожу те же самые символы, которые использовались в Бейсике.

Связь «канваса» и задника для браузеров на «Геко» (ФайрФокса и менее известных) в Джаваскрипте не видна, она полностью на стороне CSS:

body { background: -moz-element(#maze); }

Эти браузеры позволяют указать в качестве задника что угодно — хоть IFRAME, был бы у него идентификатор. Соответственно, «maze» — идентификатор моего «канваса». Делать больше ничего не нужно, любой элемент с этим «айди» размножится в качестве фона.

В последних строках я проверяют доступен ли метод для указания «-moz-element», нет ли метода для рисования «канвасом» прямо в задник, если нет, то перевожу картинку из «канваса» в dataURI и добавляю её в таком виде на фон тега BODY. Таким образом, этот код работает и для «Оперы» с «Эксплорером» (начиная с девятого).

Рабочая задача: карта + объекты

Ничего экстраординарного, просто задача по работе попалась.

Дана карта местности (картинка), на неё нанесено большое количество объектов, несколько тысяч. В каждый объект можно тыцнуть мышкой, карта большая, её надо позволять «таскать» мышкой.

Текущее решение тормозит, а надо сделать так, чтобы не тормозило.

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

В общем-то, похоже, подтвердилось. Я взял CANVAS 2000×2000 точек, накидал на него 4000 квадратов случайного цвета и в случайных координатах, CANVAS положил в DIV, растянутый 100% на 100% и скрыл у него скроллеры.

Муляж карты (38.97КиБ)

При клике происходит поиск объекта по списку (безо всякой оптимизации пока), если объект найден, то выводит информацию по цвету, если зажать кнопку мыши, срабатывает флаг «пользователь желает тащить», если пошевелить в этот момент мышью, координаты CANVAS будут меняться вслед за мышью.

Вроде не тормозит, хороший способ делать карты. Делюсь, вдруг пригодится кому.

CANVAS 1K Tank Game

Canvas Tank Game (0.58КиБ)

Решил попробовать уместить какую-нибудь игру с использованием тега CANVAS в 1КБ. После всех оптимизаций, который заняли у меня вдвое больше времени, чем написание игры, получилась несложная игрушка в 1020 1023 байта (то есть на четыре один байт меньше, чем килобайт).

Цель — подбить своим «танком» как можно больше вражеских ракет. Управление — курсорными клавишами, стрелять пробелом. Даётся три жизни, за каждые 20 сбитых ракет жизнь добавляется, если ракета долетит до вашей стороны или коснётся танка, жизнь теряется. Для рестарта игры просто перезагрузите страницу.

Должно работать везде, где поддерживается тег CANVAS, я тестировал в «Опере» 11, «Хроме» 10 и FF 3.6.13.

Have a fun!

Добавлено позднее: оказывается, я вполне уложился бы в правила конкурса JS1K (конкурс программ на JS, занимающих не более 1КБ), на который мне вчера ссылок накидали. У меня чистый JS (без сжатия в PNG) на восемь байт короче килобайта. А все эти пляски с кодом в PNG нужны для того, чтобы у меня весь код (включая HTML) поместился в килобайт.

Ещё позже: на заметку. Я вчера обращался к тегу CANVAS по идентификатору. Это очень длинный способ (не говоря уже о том, что тег должен иметь идентификатор, что ещё тратит место), вчера, когда мне показали JS1K, я там увидел способ короче: «document.body.children[0]», а сегодня я придумал способ ещё короче: «document.all[3]», это нестандартное свойство, но его поддерживают все браузеры.

Если использовать это свойство, то программа начинает занимать 1007 байт и у меня появляется ещё 17 байт. Может танк переделать? Мне пришлось упростить графику, из-за чего танк стал выглядеть странно.

И ещё позже: вернул прежний танк и сменил цвет «спецэффекта» при столкновении на красный, игра снова занимает 1020 байт. Если интересно, можно посмотреть как выглядит исходный код JavaScript моей игрушки. И ещё я внезапно придумал как ещё чуть-чуть сократить код.

И ещё: сократил чуть-чуть код, в частности, стрелять можно любой кнопкой, кроме курсорных. Освободилось несколько байт и я в левом верхнем углу нарисовал ракету, чтобы было понятно, что это количество сбитых ракет. Игра стала занимать 1023 байта.

Порисовал немного на теге CANVAS, ничего интересного

Фрактал (3.10КиБ)

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

<canvas width="500" height="240"></canvas>
<script type="text/javascript">
(function (c) {
    var img = c.createImageData(500, 240);

    var putPixel = function (x, y, c) {
        var index = (x + y * 500) << 2;

        for (var i = 0; i<4; i++) {
            img.data[index+i] = c[i];
        }
    };

    var x = 0, y = 0, color, leaf, idx,
    k = [
          [ 0.00, 0.00, 0.00, 0.16, 0.00, 0.00 ],
          [ 0.85, 0.04,-0.04, 0.85, 0.00, 1.60 ],    
          [ 0.05,-0.26, 0.23, 0.22, 0.00, 1.60 ],
          [-0.15, 0.30, 0.26, 0.24, 0.00, 0.44 ],
    ];

    for (var i = 0; i<200000; i++) {
        leaf = Math.random();

        if (leaf <= 0.010) leaf = 0; else
        if (leaf <= 0.860) leaf = 1; else
        if (leaf <= 0.930) leaf = 2; else    
        leaf = 3;

        x = x * k[leaf][0] + y * k[leaf][1] + k[leaf][4];    
        y = y * k[leaf][2] + y * k[leaf][3] + k[leaf][5];    

        putPixel(parseInt(y * 55), 120 - parseInt(x * 40), [10, 100, 20, 255]);
    }
    
    c.putImageData(img, 0, 0);
})(document.getElementsByTagName('canvas')[0].getContext('2d'));
</script>

Canvas в IE9 будет

Ну что, AMD действительно тогда проговорилась, никакой ошибки нет — в IE9 будет CANVAS. Только что появился Internet Explorer 9 Platform Preview 3 и там есть CANVAS.

Должен сказать, скорость очень хорошая. Реализовано пока не всё (это всё-таки даже не альфа), но для работы многих демок и игрушек хватает. Правда на синтетических тестах результаты противоречивые. Я сравнивал с последней сборкой «Оперы» 10.60, где-то IE9 впереди, где-то «Опера» сильно обгоняет.

Кажется, с применением полупрозрачности (и тени) производительность IE9PP3 пока резко падает.

Из других новостей: AUDIO, VIDEO, CANVAS с аппаратным ускорением, увеличена производительность и улучшена его поддержка JavaScript, поддержка WOFF (формат шрифтов), ACID3 — 83%, HTML5 test — 84/300 (предыдущий результат — 32).

Unicode со «школотой» по-прежнему рисует квадратиками.

2010   canvas   html5   ie   ie9   программирование

Canvas в IE9

Вроде как из блога AMD утекли сведения о том, что IE9 будет поддерживать Canvas:

The <canvas> element will be accelerated on the GPU via Direct2D and will enable hardware accelerated rendering contexts for application development, improving visual display, reducing CPU usage, and improving power usage. … AMD is working with multiple teams at Microsoft to ensure that technologies such as IE and Silverlight continue to move the PC platform forward.

Хотя в AMD чуть позднее поспешили откреститься от этого:

Got a little ahead of myself; Microsoft did not announce they were supporting <canvas>. However, they did say that all of Internet Explorer 9’s graphics, text, and rendering will be hardware accelerated. Given the embraced HTML5 across DOM, CSS3, SVG, and XHTML, it will be fun to watch this space closely as the IE9 Preview gets updated in the weeks to come.

Посмотрим.

2010   canvas   ie   ie9   программирование

Canvas в разных браузерах

Сегодня с утра, порадовавшись выходу Mozilla Firefox 3.5beta4, решил погонять её на JS-эмуляторе «Спектрума», о котором я упоминал. По скорости выходит где-то на уровне или впереди Safari4beta.

Canvas (3.77КиБ)

Плохо то, что Firefox, как оказывается, сильно размывает Canvas. Когда я играл на эмуляторе в одну из игр, мне казалось, что у меня что-то со зрением — до того размытая картинка. На скриншоте видно (слева направо): Opera 10 alpha 1456, Safari 3.2.2, Firefox 3.5beta4.

Получаем ещё один «стандарт», который ведёт себя во всех браузерах по-разному. Приехали.

Ogg и тег VIDEO, ActiveX Canvas для IE

Так-так, вот и FireFox 3.1, вслед за «Оперой» начинает поддерживать тег VIDEO и стандарт Ogg Theora для этого видео. Если так дело дальше пойдёт, то Ogg станет форматом для тега VIDEO де факто.

Из других интересных новостей — Vladimir Vukićević разработал ActiveX для IE, который повторяет функциональность этого тега пока только частично, но работа продолжается. Тот же автор обещает в будущем поддержку тегов video и audio, тоже, видимо, в формате ActiveX.

2008   canvas   firefox   html5   ie   программирование

Сжатие JavaScript с использованием PNG и Canvas

Jacob Seidelin в своём блоге «Nihilogic» опубликовал небезынтересную статью, где он рассказывает о своих экспериментах по сжатию кода JavaScript при помощи Canvas и PNG.

Идея простая, из разряда «как мне раньше не пришло это в голову». JavaScript переводится в последовательность байт, которая записывается как изображение. Изображение сохраняется в PNG-формате, в PNG используется довольно эффективное сжатие, что даже при расходах на заголовок даёт ощутимые результаты — известная библиотека Prototype (124 килобайта) стала занимать всего 30 килобайт в восьмибитном PNG-файле. Каждый пиксель в 24-битном PNG позволяет хранить три байта информации, в 8-битном формате — один.

Далее PNG-изображение загружается в тег CANVAS (нужный функционал поддерживается FireFox, WebKit/Safari и бета-версией «Оперы») и считывается попиксельно функцией getImageData, после чего полученный код выполняется (eval) и мы получаем исходный JavaScript.

Единственный недостаток метода — скорость. Извлечение скрипта в 255Кб может занять несколько секунд, что, впрочем, не всегда является проблемой.

HTML5 VIDEO: кто первый? А так же 3D CANVAS

Вышел браузер «Сафари» версии 3.1, в пресс-релизе написано, что «Сафари» — первый браузер, поддерживающий новые теги video и audio из HTML5:

Safari 3.1 is the first browser to support the new video and audio tags in HTML 5 and the first to support CSS Animations. Safari also supports CSS Web Fonts, giving designers limitless choices of fonts to create stunning new web sites

Что касается тега AUDIO — чистая правда, а с VIDEO — вышла накладка. Специальный билд «Оперы», поддерживающий этот тег, вышел 8-го ноября 2007-го года, тогда как Webkit (на движке которого сделан «Сафари») — 12-го ноября, на четыре дня позже.

Кстати, самое интересное, что появилось в том билде «Оперы», это не тег VIDEO, а 3D Canvas — до этого момента тег CANVAS позволял работать только с примитивами на плоскости (отрезками, прямоугольниками, кругами и так далее), знаменитая игра «Canvascape», сделанная с применением этого тега (требует для работы любой браузер, поддерживающий CANVAS), просчитывае 3D-графику самостоятельно, из-за чего игра на средних компьютерах заметно притормаживает.

Для 3D CANVAS задача вращения куба с текстурой, например — тривиальная. Примеров работы с этим новшеством пока немного, в оригинально статье упомянута Snake («змейка») в 3D, написанная Mathieu ’p01’ HENRI.