Цитата:
[HTML run] |
Не стоит копировать с ответов часть ответственную за взаимодействие с DOM. 2е решение хоть и красивое но FullScreen по производительности не потянет 100X30 это 3000 операций с дум на кадр. А это очень много. При таких масштабах нужно обращаться к дум как можно меньше,а это означает что придется юзать либо innerHTML/innerText, либо Fragment. 2й пример пожалуй неудачный, а нападка на innerHtml в первом комменте чересчур предвзята.
1Й основан на innerText и он на фуллскрине выдает 30 кадров. Только slice для строки пришлось добавить. |
Всетаки не оставили меня мысли об этой сраной матрице. Выкрал еще чуток времени и сделал набросок под один innerHtml.
Все намного проще вышло чем мне показалось с первого раза. >Stage теперь не нужен так как нет больше столбиков анимируемых отдельно >Формирование строки для innerHTML и скроллинг массива происходит одновременно, за один и тот же перебор. Теперь с Fragment надо еще по попробывать, дабы скролить сложные HTML элементы :) <body style="height:100%;background:black;"> <div id="matrix" style="width:100%;height:100%; font-family:Courier New;color:green;"></div> </body> <script> function getRandomInt(min, max) { return Math.floor(Math.random() * (max-min) ) + min; } //Класс управлюящий поведением колонок function Column(minSize){ //сбрасывает столбик this.reset=function(){ this.frameCount=1; //счетчик пропущенных кадров this.speed=getRandomInt(1,5); //количество пропущенных кадров на один сработавший this.length=getRandomInt(minSize,minSize+15); //длинна падающего столбца } //уменьшает счетчик на единицу this.ReduceThecounter=function(){ if ( (this.frameCount--) <0) { //уменьшаем счетчик кадров, если длинна<0 то выполним фрагмент кода this.frameCount=this.speed; if ( ( this.length--) <0) this.reset(); //уменьшаем длинну столбца, если длинна<0 то сбрасываем столбец } } this.reset(); } //Матрица function Matrix(elem,sizeX,sizeY){ var columns=[], elem= typeof elem=="string"?document.getElementById(elem):elem, matrix=[]; //Инициализация колонок и первоначальное заполнение матрицы for (var x=0;x<sizeX;x++){ columns.push(new Column(sizeY+1) ); matrix.push([]); for (var y=0;y<sizeY;y++) { matrix[x][y]={sym:" "}; } } //метод обновления this.update=function(){ var y=sizeY, x=0, result=""; while(y--){ x=sizeX; while(x--){ if (y==0) columns[x].ReduceThecounter(); if(columns[x].frameCount==0){ if (y==0){ matrix[x][0].sym= (columns[x].length>sizeY)?String.fromCharCode( getRandomInt(97,122) ):" "; } else { matrix[x][y].sym=matrix[x][y-1].sym; } } result=matrix[x][y].sym+result; } result="<br/>"+result; } elem.innerHTML=result; } } var m=new Matrix('matrix',82,17); +function f(){ m.update(); setTimeout(f,1)//setTimeut для демки производительности оставил }(); </script> |
Дык а нафига вообще тут DOM использовать? Есть же уже куча готовых реализаций на canvas
http://tenthpla.net/matrix/ http://warwolf.org/404 |
Цитата:
А автору темы надо при помощи МАТРИЦЫ признаться в любви на НЕМЕЦКОМ ЯЗЫКЕ !!! Воистину любовь толкает на безрассудные поступки :D |
Не оч симпатично - буквы падают линейно и синхронно, а реале вертикальные строки двигались с чуть разной скоростью меняющейся туды сюды - похожей на дождь.
Проще заготовить рандомно заполненные буквами вертикальные div, уже вставленные в единый блок ( во всю ширину экрана и высотой - в полтора - два экрана) и этот блок двигать с постоянной скоростью, а вертикальные div в нём(они не прозрачные, а с черным фоном) - рандомно- тудем - сюдем(вверх-вниз) с мелкой скоростью. При близости окончания верхнего обреза текущего блока, сверху, с перекрытием, - накладывать дубликат текущего блока(который во всю ширину)(т.е это будет второй повтор анимации) В принципе, если скорость позволит, то пока идет первый заход, можно сгенерить и совершенно новый второй общий блок |
DEFF
Они не синхронно падают, у примера выше просто разброс в скорости небольшой от 1 до 5, и длительность колонок большая была и это все очень быстро в придачу. Можно поиграться с кастомизацией здесь http://learn.javascript.ru/play/0a6oXb Поиграться со скоростью (speed это количество пропущенных кадров на один сработавший) к примеру this.speed=getRandomInt(0,4)*3; 0 минимальная 4 максимальная 3 это множитель делающий разброс в скорости более выраженным поиграться с длинной колонок к примеру this.length=getRandomInt(minSize,minSize+15) minSize означает что длинна минимум равна высоте экрана minSize+15 означает что можно генерировать столбик до 15 символов Подмечу что minSize для столбика это количество пробелов разделяющих столбики, и естественно оно равно высоте экрана (иначе столбец исчезнет раньше чем скроется внизу за экраном). У меня чисто академический интерес связанный с быстрым падением большой кучи буковок с разной скоростью :) Красота лично мне мало интересна :) Заранее подготовленные столбики двигать не пробывал, их штук 130 будет. |
Я эксперементировал с typeScript и в порядке эксперемента переписал на нем код из примера выше. Публикую просто для сравнения, дабы мой скорбный труд не пропал совсем даром :)
Производительность ебстебственно одинаковая. var getRandomInt=(min:number, max:number)=> Math.floor(Math.random() * (max - min)) + min; //Класс управляющий поведением колонок class Column { frameCount:number;//счетчик пропущенных кадров (тип число) length:number; //Длина анимации (тип число) speed:number; //это значение устанавливается frameCount, если он ниже нуля (тип число) //конструктор. Прикольно что minSize сразу в this попадает :) constructor(private minSize:number) { this.reset(); } //сбрасывает столбик public reset() { this.frameCount = 1; this.speed = getRandomInt(1, 5); this.length = getRandomInt(this.minSize, this.minSize + 15); } //уменьшает счетчик на единицу public ReduceThecounter() { if ( ( this.frameCount-- ) < 0) { this.frameCount = this.speed; if ( (this.length--) < 0) this.reset(); } } } //Матрица class Matrix { private columns=[]; private matrix=[]; constructor(private elem, private sizeX:number, private sizeY:number){ this.elem=typeof elem == "string" ? document.getElementById(elem) : elem;//не стал мудрить, оставил в стиле JS for (var x = 0; x < sizeX; x++) { this.columns.push(new Column(sizeY + 1)); this.matrix.push([]); for (var y = 0; y < sizeY; y++) { this.matrix[x][y] = { sym: " " }; } } } //метод обновления public update () { var y = this.sizeY, x = 0, result = ""; while (y--) { x = this.sizeX; while (x--) { if (y == 0) this.columns[x].ReduceThecounter(); if (this.columns[x].frameCount == 0) { if (y == 0) { this.matrix[x][0].sym = (this.columns[x].length > this.sizeY) ? String.fromCharCode(getRandomInt(97, 122)) : " "; } else { this.matrix[x][y].sym = this.matrix[x][y - 1].sym; } } result = this.matrix[x][y].sym + result; } result = "<br/>" + result; } this.elem.innerHTML = result; } } var m = new Matrix('matrix', 82, 17); +(function f() { m.update(); setTimeout(f, 1); })(); //# sourceMappingURL=app.js.map |
Часовой пояс GMT +3, время: 21:16. |