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

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

Больше всего понравилось название =('.')=
На втором месте !~Rat.notStyle.indexOf(key)
Сейчас набегут адепты читабельности и заминусят меня. Но, что поделать, я не друг тем людям, для которых смысл этой записи очевиден.
~(-1) === 0, а !0 === true. Без этих знаний можно только скриптики для сайтиков писать, а к толстому клиенту не лучше подходить.

Теперь по существу:
У описанной части есть только одно полезное свойство — графика описывается данными. Данные можно запомнить, а потом отрисовать полностью или частично, в одном canvase или в нескольких. Это открывает возможность разработке в парадигме MVC.
Код смотреть пока не досуг. С удовольствием почитаю следующую статью.
Была бы очень в тему поддержка добавления своих функций отрисовки, доступных по тому же алгоритму.
Да, про данные подумал не сразу. Но, в целом, можно и data-ориентированный код на чистом 2dcontext писать, разница есть, но не сильно заметная. Ну, мне так кажется, очень надеюсь, что я ошибаюсь.
В любом случае, именно на этих объектах будут строиться следующие части статьи.

Про добавление своих функций отрисовки чуть-чуть не понял, имеется в виду что-то подобное?:
var rect = rat.rect([10, 10, 200, 200], {
    fillStyle: 'red'
});

Скрытый текст
Rat.Rect = function(opt, style, context){
    Rat.init(this, arguments);
};
Rat.Rect.prototype = {
    draw: function(ctx){
        ctx = ctx || this.context.context;
        Rat.style(ctx, this.style);
        ctx.rect.apply(ctx, this.opt);
        if(this.style.fillStyle)
                ctx.fill();
        if(this.style.strokeStyle)
                ctx.stroke();
        ctx.restore();
    }
};

Rat.prototype.rect = function(opt, style){
    return new Rat.Rect(opt, style, this);
};
Это я сперва не понял идею.
data-ориентированность тут не до конца. Ну, не беда, можно допилить. Жаль, времени пока нет в коде копаться…
Предлагайте, если разберусь, напишу, мне это кажется интересным.
Код посмотрел. Некоторые идеи есть, но кодить пока некогда. А на естественном языке мне мысли о коде выражать труднее, чем на JS.
Будет окно в своих скриптах — предложу свой коммит для Rat.
А пока мне интересно, как Вы думаете реализовать события. Я сам очень мало работал с canvas и рассчитываю с помощью какого-то из Ваших фреймворков ликвидировать безграмотность.
Пройдёмся по опечаткам (дюже они страшные):
*я не друг тем людям, для которых смысл этой записи не очевиден.
*а к толстому клиенту не лучше не подходить

Вот что бывает, когда в конце рабочего дня комменты пишешь…
Ну и ещё недосуг слитно.

На первой опечатке ненадолго завис, но в итоге смысл понял, вторая просто незаметна.
Попробуйте нарисовать подряд большую картинку и потом треугольник, и будете приятно удивлены
Ну да, картинка же рисуется по событию onload, которое случается после основного потока… Поэтому она окажется нарисована позже (и выше, соответственно). Если вы об этом.
var path = rat.path([
  ['moveTo', 10, 10],
  ['lineTo', 100, 100],
  ['lineTo', 10, 100],
  ['closePath']
], {
  fillStyle: 'red',
  strokeStyle: 'green',
  lineWidth: 4
});

var img = new Image();
img.src = "image.jpg";
img.onload = function(){
  img = rat.image(img);
  path.draw(); // внимание сюда
}

Можно всю отрисовку сделать асинхронной. Рендерер ждёт, когда прогрузятся все картинки, а потом рисует элементы в порядке следования.
Или, ещё лучше, грузить картинку при создании элемента, а не при отрисовке. Рисовать же несколько раз можно, а грузить достаточно один раз.
Ну да: достаточно сделать массив элементов в Rat, и в функциях Rat.prototype.path, image, text, пушать элемент в массив. Можно даже и сам Rat от массива унаследовать. Дальше будет обработка событий, и я, возможно, приду к чему-нибудь подобному.

Такой подход я реализовал в, собственно, Graphics2D ( Github ), а Rat — чисто поиграть-поэкспериментировать, что уложится в 100 строк :).
В G2D всё то же самое реализуется таким кодом:
var path = ctx.path([
  // можно точно так же указывать функции ( ['lineTo', x, y] )
  [10, 10], // но по умолчанию -- 2 аргумента => lineTo
  [100, 100], // а в первом -- moveTo
  [10, 100],
  true // closePath
], 'red', 'green 4px');

var img = ctx.image('image.jpg', x, y);

Всё перерисовывается, обрабатывается и т.п.
Мы делали очередь, и ждали пока не будет доступны для отрисовки все ниже стоящие слои. Еще аналог 'z-index'a навешивали, для удобства использования.
Я бы сделал сервис загрузки картинок, который бы принимал {string}url и возвращал {Image}. Заодно исключив повторную загрузку с одного и того же url.
UPD: Я бы Rat к массиву не привязывал. Возможно, один и тот же массив придётся отрисовывать в разных canvas, а canvas уже привязан к экземпляру Rat.
Мне всегда нравился другой подход:
var context = document.get('canvas').getContext('2d') //псевдокод
    h_context = new function(){
        this.chain = function(method, args){
            context[method].apply(context, args); 
            return this;
        }
        return this;
   }
 h_context
    .chain('beginPath')
    .chain('fillRect', [0, 0, window.innerWidth, window.innerHeight]);
//ну или 
 h_context
    .chain('beginPath')
    .chain('arc', [/*some, arguments*/])
    .chain('fill')

Как-то оно нагляднее что-ли показывает процесс. Аргументы всё-равно достаточно редко нужны общие для всех рисунков. Хотя, эту обёртку я в основном писал что бы уменьшить количество строк при рисовании фигур, но выглядит достаточно удобно и более гибко.
PS форматирование хромает =(
Мне это больше всего напоминает EaselJS:
var circle = new createjs.Shape();
circle.graphics.beginFill("DeepSkyBlue").drawCircle(0, 0, 50);
circle.x = 100;
circle.y = 100;
stage.addChild(circle);

Может быть, это и удобно. Но… моё чувство эстетики (эстетичности? как правильно?) всеми руками протестует против чеининга свойств контекста:
// зачем делать так??
context.fillStyle('red').fillRect(10, 10, 200, 200);

// когда можно вот так?
context.fillRect(10, 10, 200, 200, 'red');

И при этом в каком-то виде возможна реализация ООП, и соблюдается «чистота» — свойства ранее отрисованных объектов не переползают на позднее рисуемые.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории