Hi all,
I’m working on my personal website, my first forway into javascript and web development.
I wanted to create a flip dot style display which has since morphed into more of a CRT look.
You can take a look here if you like: https://343f-66-113-2-158.ngrok-free.app/main.html
However, I’ve recently, when sending it to a friend, we found it only seems to work with any performance on Safari, sometimes in fact failing entirely on Chrome and Firefox.
I’m wondering if anyone has any ideas on how I might change my design to migigate this or whether there is some way to give myself more resources on firefox and chrome.
A cursary look into fixing this seems to suggest I should use RequestAnimationFrame, however, this drawing of all elements smoothly at once, while efficent, destroyes the organic effect that the timeouts gave both on the individual dot level and when refreshing line by line.
My general design is outlined here:
I’m using HTML5 canvas; each dot is a class which redraws its section of the canvas with a 50-300 ms delay to emulate the per dot lag of a given hinge on a flip dot display. The display class again using setTimeOut(), schedules each line of the display, consisting of dots, to update at a slight offset so that you can see the display refresh from left to right. Then the rest of the program modifies the “next frame” array with text or images which I wish to be displayed.
Thank you!
In script.js, l.149ff:
drawImage(Image, topLeftX, topLeftY) { for (let row = 0; row < Image.length; row++) { for(let column = 0; column < Image[row].length; column++) { this.nextFrame[(topLeftX + column)*this.height + (topLeftY+row)] = Image[row][column]; } } }
The term
topLeftX + column * this.height
can be rewritten astopLeftX * this.height + column * this.height
. The first term of this is a constant and can be extracted into a variableconst verticalOffset = topLeftX * this.height
.Similarly,
topLeftY + row
doesn’t need to be recomputed in every iteration of the inner for loop. Move it out into the outer for loop.Also notice that the variable part,
column * this.height
is all the integer multiples ofthis.height
. Therefore, instead of a multiplication, you can simply addthis.height
to a running total. Sums should be faster than multiplications.With these three changes you get [Edit: I think I made mistakes during the replacements.]
drawImage(Image, topLeftX, topLeftY) { const TODO_NAME_THIS = topLeftX * this.height let TODO_NAME_THIS_ALSO = topLeftY for (let row = 0; row < Image.length; row++) { let TODO_NAME_THIS_TOO = 0 for(let column = 0; column < Image[row].length; column++) { this.nextFrame[TODO_NAME_THIS + TODO_NAME_THIS_TOO + TODO_NAMES_THIS_ALSO] = Image[row][column]; TODO_NAME_THIS_TOO += this.height } TODO_NAME_THIS_ALSO += row } }
Ah yes I see! That should offer some improvement given the number of times it’s called— also see I’m used to swift so I keep using let when I should probably use const— thanks I’ll give it a try and let you know what happens!