Paper.js: самый быстрый способ рисовать множество повторяющихся фигур в цикле

jsfiddle здесь: http://jsfiddle.net/yw0w18m3/2/

Я использую paper.js для создания фонового изображения, которое выглядит примерно так:

введите здесь описание изображения

По сути, я создаю пару тысяч треугольников в цикле и вращаю их на каждой второй итерации.

function Tri(x, y, rotate) {
    var tri = new Path([
        new Point((x - 42), (y - 48)),
        new Point((x - 42), y),
        new Point(x, (y - 24)), 
        new Point((x - 42), (y - 48)) 
    ]);

    tri.fillColor = {
        hue: Math.random() * 360,
        saturation: 0,
        brightness: ( (( Math.random() ) * .95) + .3 )
    };

    if(rotate) { tri.rotate(180); } 
}

for (var i = 0; i < 2000; i++) {
    rotate = false;

    if( i % 2 ) {
        rotate = true;
    }

    new Tri(x, y, rotate);

    x = x + 42;

    if( x > (winWidth + 42) ) {
        x = 0   ;
        y = y + 24;
    }
}

Кажется, что есть короткая 1-2-секундная пауза/заморозка во время рисования фигур. Есть ли более эффективный способ сначала нарисовать все фигуры (или поместить их в массив), а затем сразу добавить это на холст?

Я основывал свой код на примере здесь: http://paperjs.org/examples/candy-crash/ (нажмите "источник" в правом верхнем углу).

Буду признателен за любую оказанную помощь.

Спасибо!


person HandiworkNYC.com    schedule 29.01.2015    source источник


Ответы (2)


В итоге я бы создал два треугольника, один повернутый, поэтому их не нужно каждый раз строить из новых точек. Затем выберите правильный треугольник на основе переменной вращения и клонируйте его, вместо того, чтобы каждый раз создавать точки и треугольник с нуля. Наконец, просто измените положение клонированного треугольника.

Наконец, я бы исправил maxTri, чтобы он не делал больше, чем нужно. Скобка должна следовать за 48, а не за 24. Вы делаете на порядок больше треугольников, чем нужно.

Here's a link to the sketch.paperjs.org solution I created based on your code. Я считаю, что скетч проще в использовании, чем jsfiddle для бумажных примеров.

proto1 = new Path([
    new Point(0, -24),
    new Point(0, 24),
    new Point(42, 0)
    ]);
proto1.closed = true;

proto2 = proto1.clone();
proto2.rotate(180);


function putTriangle(pos, rotate) {
    var tri = (rotate ? proto2 : proto1).clone();
    tri.position = pos;
    tri.position = tri.position.subtract([21, 0])
    tri.fillColor = {
        hue: Math.random() * 360,
        saturation: 0,
        brightness: Math.random() * 0.5 + 0.5
    }
}
var tris = [],
    x = 42,
    y = 24,
    rotate,
    winWidth = paper.view.size.width,
    winHeight = paper.view.size.height,
    rows = (winHeight + 48) / 24,
    cols = (winWidth + 42) / 42,
    numTri = rows * cols,
    numTriOrig = (winWidth + 42) / 42 * (winHeight + 48 / 24);

//console.log(numTri, numTriOrig);

x = 0;
y = 0;

for (var row = 0; row < rows; row++) {
    rowrotate = row % 2;
    for (var col = 0; col <= cols; col++) {
        rotate = rowrotate ^ col % 2;
        putTriangle([x,y], rotate);
        x += 42;
    }
    x = 0;
    y = y + 24;
}
person bmacnaughton    schedule 30.01.2015
comment
Удивительно! Спасибо большое. - person HandiworkNYC.com; 31.01.2015

Две мысли:

Я вижу, вы используете поворот, чтобы поставить треугольники на место. Это дорогая операция. Вы можете заменить поворот менее геометрическим и более арифметическим расчетом ориентации треугольников.

Кроме того, я вижу, что цвет заливки меняется с каждым треугольником, а изменения состояния (например, заливка) стоят умеренно дорого. Вы можете сгруппировать все треугольники одинакового цвета и нарисовать их одной партией.

person markE    schedule 30.01.2015