Создание мозаики


Я играл вокруг с таблицами и случайных цветов, чтобы создать мозаику.

Как я считаю, это довольно медленно, скажите мне, как это может быть улучшено с точки зрения скорости.

function generate_mosaic(cols, rows) {
    var i, ncol, trans, colspan, style, html;
    html += "<table>";

    for (i = 0; i < rows; i += 1) {
        html += "<tr>";
        ncol = 0;
        while (ncol < cols) {
            trans = ncol / cols * 0.5 + i / rows * 0.5;
            colspan = Math.floor(Math.random() * 2) + 1;

            if (ncol === cols - 1) {
                colspan = 1;
            }

            ncol += colspan;

            style = "background-color: rgba(" + Math.floor(Math.random() * 255) + ", " + Math.floor(Math.random() * 255) + ", " + Math.floor(Math.random() * 255) + ", " + trans + ");";
            html += "<td colspan=" + colspan + " style='" + style + " line-height: 5px'>&nbsp;<\/td>";
        }
        html += "<\/tr>";
    }
    html += "<\/table>";
    return html;
}

document.write(generate_mosaic(250, 250));

Код также доступен в jsfiddle



969
3
задан 29 августа 2011 в 09:08 Источник Поделиться
Комментарии
4 ответа

Я предлагаю использовать документ.тела.innerHTML будет вместо документа.пишите()

document.body.innerHTML = generateMosaic();

также положить по математике.случайным образом в переменной, поэтому она не должна вернуться в Математика объект каждый раз:

var random = Math.random;
random() * 255;

Также Математика.Пол, видимо, довольно медленно, попробуйте >> 0 вместо

((random() * 255) >>0);

(пример использования Canvas в HTML5):

http://jsfiddle.net/yHxxT/1/

function generate_mosaic2(cols, rows, canvasElement) {
var colUnitSize = canvasElement.width / cols;
var rowUnitSize = canvasElement.height/ rows;
var nrows = rows;
var rows2 = rows * 2;
var cols2 = cols * 2;
var trans = 0;
var random = Math.random;
var floor = function (number){ return (number >> 0); };
var context = canvasElement.getContext("2d");
var colspan = 0;
context.fillStyle = "#000";
context.fillRect(0,0, 1000, 1250); //Black background
do
{
var ncols= cols;
do
{
trans = ncols / cols2 + nrows / rows2;

if(ncols === 1)
{
colspan = 1;
}
else
{
colspan = floor(random() * 2);
}
context.fillStyle = "rgba(" + floor(random() * 255) + ", " + floor(random() * 255) + ", " + floor(random() * 255) + ", " + trans + ")";
context.fillRect(ncols * colUnitSize , nrows * rowUnitSize , colspan * colUnitSize , rowUnitSize);
ncols -= colspan;
}while(ncols)
}while(--nrows)

}

http://jsperf.com/mosaic см. Этот тест jsperf бы предположить, что холст решения более чем в 2 раза быстрее за 250х250 или 150х150

4
ответ дан 30 августа 2011 в 01:08 Источник Поделиться

Так как вы ищете проблемы с производительностью, вы могли бы рассмотреть это:

в HTML += "";

Постоянно добавляя в строку часто за o(n), где N-длина строки. Используя массив и толкать()ную строку СНиПы на него, затем с помощью .присоединяйтесь() в конце часто может быть быстрее.

Разные движки JavaScript позволит оптимизировать два метода по-разному-тест, кросс-браузер, чтобы увидеть, если это достаточно быстро.

4
ответ дан 31 августа 2011 в 12:08 Источник Поделиться

Я с Шоном: конкатенация строк происходит медленно. Замените вашу функцию:

function generate_mosaic(cols, rows) { 
var i, ncol, trans, colspan, style;
var html = [], j=0;
html[j++] = "<div><table>";

for (i = 0; i < rows; i += 1) {
html[j++] = "<tr>";
ncol = 0;
while (ncol < cols) {
trans = ncol / cols * 0.5 + i / rows * 0.5;
colspan = Math.floor(Math.random() * 2) + 1;

if (ncol === cols - 1) {
colspan = 1;
}

ncol += colspan;

html[j++] = '<td colspan="';
html[j++] = colspan;
html[j++] = '" style="background-color: rgba(';
html[j++] = Math.floor(Math.random() * 255);
html[j++] = ',';
html[j++] = Math.floor(Math.random() * 255);
html[j++] = ',';
html[j++] = Math.floor(Math.random() * 255);
html[j++] = ',';
html[j++] = trans;
html[j++] = '); line-height: 5px">&nbsp;<\/td>';
}
html[j++] = '<\/tr>';
}
html[j++] = '<\/table></div>';
return html.join('');
}

вы должны найти его гораздо быстрее. Для получения более подробной информации смотрите мой ответ на подобный вопрос размещен здесь:

https://stackoverflow.com/questions/4864294/dynamic-creation-of-large-html-table-in-javascript-performance/4865247#4865247

Тестирование с IE9 показывает этот метод должен принимать только около половины времени для выполнения, чем решение "холст".

Тестирование с хром показывает случай более 125 x 125 медленнее, но дело 250х250 быстрее.

Тестирование с Firefox показывает обоих методов будет примерно такой же.

См.: http://jsperf.com/mosaic/2

Что касается
Нил

2
ответ дан 1 сентября 2011 в 08:09 Источник Поделиться

А вы попробуйте документа.тела.appendElement / документ.метод createElement("ТР") и т. д., а не изменять innerHTML будет.

Хотя, обратите внимание, что вы должны добавить все не видно (на самом деле даже не добавить его в DOM) элемент, в то время как в петле и после этого добавляет, что база-элемент фактической купола.

что-то вроде:

var myCanvas = document.createElement("div");
for(blabla)
{
var myTd = document.createElement("td");
myTd.style.backgroundColor = ...;
...
myCanvas.appendChild(myTd);
}
document.body.appendChild(myCanvas);

кстати, это поколение, которое медленно или всю страницу после поколения? Это ужасный способ, чтобы создать такие плотные и большие мозаики, использовать HTML5-Canvas или на стороне сервера, а не созданный образ.

1
ответ дан 3 сентября 2011 в 03:09 Источник Поделиться