I’ve got pretty strange example to work on… I need to fill a circle with 1×1 pixels, all with different colors in a browser.
What I tried, is something like this
function getRandomColor() { var letters = '0123456789ABCDEF'.split(''); var color = '#'; for (var i = 0; i < 6; i++ ) { color += letters[Math.round(Math.random() * 15)]; } return color; } function createRandomSqaure(destination) { var size = destination.height() * destination.width(); for (var i = 0; i < size; i += 1) { destination.append('<div class="pixel" style="background: ' + getRandomColor() + '"></div>'); } } createRandomSqaure($('.pic'));
The case is, it super slow (as you can imagine, loop goes 40k times for 200×200 image), I thought maybe a better way will be drawing It on canvas? And I need to draw a circle filled with this pixels in the end…
I don’t know how to do something like this in a more optimal way, I can use a nodejs server also, but I think generating something like this server side on heroku is a way too much.
I’m just curious what do you guys think, and what is the best way to do something like this?
Answer
You can use a simple approach like this:
- Draw all the pixels with random colors in a 200×200 grid on a canvas
- Change composite mode
- Draw circle on top
Live demo
Results in:
Example:
var canvas = document.getElementById('canvas'), // get canvas element ctx = canvas.getContext('2d'), // get context x, y = 0, // initialize dia = canvas.width, radius = dia * 0.5; ctx.translate(0.5, 0.5); // to make pixels sharper for(; y < dia; y++) { // walk x/y grid for(x = 0; x < dia; x++) { ctx.fillStyle = getRndColor(); // set random color ctx.fillRect(x, y, 1, 1); // draw a pixel } } // create circle // removes pixels outside next shape ctx.globalCompositeOperation = 'destination-in'; ctx.arc(radius, radius, radius, 0, 2*Math.PI); ctx.fill(); // reset ctx.globalCompositeOperation = 'source-over'; function getRndColor() { var r = 255*Math.random()|0, g = 255*Math.random()|0, b = 255*Math.random()|0; return 'rgb(' + r + ',' + g + ',' + b + ')'; }