Skip to content

Instantly share code, notes, and snippets.

@dominictarr
Created May 23, 2020 07:18
Show Gist options
  • Select an option

  • Save dominictarr/a15a1236f9e1cc21f727abc393655099 to your computer and use it in GitHub Desktop.

Select an option

Save dominictarr/a15a1236f9e1cc21f727abc393655099 to your computer and use it in GitHub Desktop.

A comparison of how much code it takes to write random pixel data to the screen via canvas, or via x11. there is a similar protocol to x11 on mac. I don't know how windows or mobile works. I think this is enough to confirm that it wouldn't be too hard to provide the same low level access on any platform.

<canvas width=800 height=600></canvas>
<script>
var id
var mem = new Uint8ClampedArray(1024*1024 * 4)
function resize () {
canvas.width = window.innerWidth
canvas.height = window.innerHeight
id = new ImageData(mem.slice(0, canvas.width*canvas.height*4), canvas.width, canvas.height)
}
var canvas = document.querySelector("canvas")
var ctx = canvas.getContext('2d')
document.body.style = 'margin:0px'
id = ctx.getImageData(0, 0, canvas.width, canvas.height)
resize()
function initial () {
var data = id.data
var len = data.length
for(var i = 0; i < len; i++)
data[i] = ~~(Math.random()*256)
}
initial()
window.requestAnimationFrame(function noise () {
if(canvas.width !== window.innerWidth || canvas.height !== window.innerHeight) {
resize()
initial()
}
var data = id.data
var len = data.length
for(var i = 0; i < len; i++)
data[i] = (data[i] + ~~(Math.random()*32) - 15) % 256
ctx.putImageData(id, 0, 0)
window.requestAnimationFrame(noise)
}, 100)
</script>
var x11 = require('x11');
var Exposure = x11.eventMask.Exposure;
x11.createClient(function(err, display)
{
var X = display.client;
X.require('render', function(err, Render) {
var root = display.screen[0].root;
main(root, X, Render);
});
});
var w = 800, h = 600
var logo = {
width: w, height: h, data: Buffer.alloc(w*h*4)
}
function main(root, X, Render) {
var win, picWin, pic, gc;
win = X.AllocID();
X.CreateWindow(
win, root,
0, 0, logo.width, logo.height,
0, 0, 0, 0,
{ eventMask: Exposure }
);
X.MapWindow(win);
gc = X.AllocID();
X.CreateGC(gc, win);
var logoPixmap = X.AllocID();
X.CreatePixmap(logoPixmap, win, 24, logo.width, logo.height);
// TODO: add proper png pixel conversion here
var winPicture
var logoPicture
var ts = Date.now()
X.PutImage(2, logoPixmap, gc, logo.width, logo.height, 0, 0, 0, 24, logo.data);
logoPicture = X.AllocID();
Render.CreatePicture(logoPicture, logoPixmap, Render.rgb24);
winPicture = X.AllocID();
Render.CreatePicture(winPicture, win, Render.rgb24);
function animate () {
//not sure why fps is so low. we are sending quite a bit of data to the screen each time
//but probably just havn't found the best way to do it.
console.error('fps', 1000 / (Date.now() - ts))
ts = Date.now()
for(var i = 0; i < logo.data.length; i++)
logo.data[i] = ~~(Math.random()*256)
var start = Date.now()
X.PutImage(2, logoPixmap, gc, logo.width, logo.height, 0, 0, 0, 24, logo.data);
var start = Date.now()
Render.Composite(3, logoPicture, 0, winPicture, 0, 0, 0, 0, 0, 0, logo.width, logo.height);
setTimeout(animate, 10)
}
animate()
X.on('event', function(ev) {
if (ev.name == 'Expose')
Render.Composite(3, logoPicture, 0, winPicture, 0, 0, 0, 0, 0, 0, logo.width, logo.height);
});
}
@untriedbox
Copy link

Low-level pixel access is possible everywhere, but ease and complexity vary. Browser canvas is far simpler; native APIs like X11 give more control but require more code.
Deltarune

@tinyfishing2a
Copy link

tinyfishing2a commented Dec 25, 2025

Tiny fishing is a terrific game that I simply adore for its fun nature. Everyone should play this game to relax and unwind when they are anxious or exhausted.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment