Context: multi-user application (node.js) - 1 artist, n clients
Canvas Size: 650x400 px (= 260,000 px)
In order for the canvas to be updated frequently (I think about 10 times per second), I need the data size to be as small as possible, especially when you think about download speed.
The toDataURL() method returning a base64 string is nice, but it contains a ton of data that I don't even need (23 bits per pixel). Its length is 8,088 (without previous MIME information) and assuming that JavaScript strings are 8-bit encoding, which will be 8.1 kilobytes of data, 10 times per second.
My next attempt was to use JS objects for various context actions, such as moveTo(x, y) or lineTo(x, y) , send them to the server and receive data in delta updates (through timestamps) by clients. However, this turned out to be even less efficient than the base64 string.
{ "timestamp": 0, "what": { "name": LINE_TO, "args": {"x": x, "y": y} } }
This does not work smoothly or accurately, because there are already about 300 lineTo commands when you quickly brush. Sometimes there is no part of the movement (a straight line, not a rounded one), sometimes events are not even recognized by the client side of the script, because it seems to be "overloaded" with a mass of events that have already been triggered.
So, I have to finish using the base64 string with my 8.1 KB. I donβt want to worry about this - but even if done asynchronously with delta updates, there will be big delays on the real server, not to mention the random overflow of bandwidth.
The only colors I use are # 000 and #FFF, so I was thinking about a 1-bit data structure with only delta updates. That would be enough, and I would not mind any βcolorβ precision losses (after all, it is black).
When most of the canvas is white, you might consider adding an extra Huffman length encoding to reduce the size even further. Like a canvas 50x2 px in size, and one black pixel in (26, 2) will return the following line: 75W1B74W (50 + 25 white pixels, then 1 black pixel, then another 24 white pixels)
It would even help if the canvas consisted of a 1-bit string like this:
00000000000000000000000000000000000000000000000000 00000000000000000000000001000000000000000000000000
This will help a lot.
My first question: how to write an algorithm to efficiently obtain this data?
Second: how can I pass pure canvas binary data to clients (via node server)? How do I even send a 1-bit data structure to the server? Should I convert my bits to a hexadecimal (or more) number and reanalyze?
Can this be used as a data structure?
Thanks in advance,
Harti