├── images └── favicon.ico ├── projects ├── trees │ ├── index.css │ ├── image.png │ ├── index.html │ └── index.js ├── converge │ ├── image.png │ ├── index.css │ ├── index.html │ └── index.js ├── hehehe │ ├── rickroll.mp4 │ ├── index.css │ ├── index.html │ └── index.js └── tiny-mirror │ ├── image.jpg │ ├── index.css │ ├── index.html │ └── index.js ├── README.md └── index.html /images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wybiral/code-art/HEAD/images/favicon.ico -------------------------------------------------------------------------------- /projects/trees/index.css: -------------------------------------------------------------------------------- 1 | * { 2 | font-size: 0; 3 | margin: 0; 4 | padding: 0; 5 | } -------------------------------------------------------------------------------- /projects/trees/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wybiral/code-art/HEAD/projects/trees/image.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # code-art 2 | 3 | [https://wybiral.github.io/code-art/](https://wybiral.github.io/code-art/) 4 | -------------------------------------------------------------------------------- /projects/converge/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wybiral/code-art/HEAD/projects/converge/image.png -------------------------------------------------------------------------------- /projects/hehehe/rickroll.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wybiral/code-art/HEAD/projects/hehehe/rickroll.mp4 -------------------------------------------------------------------------------- /projects/tiny-mirror/image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wybiral/code-art/HEAD/projects/tiny-mirror/image.jpg -------------------------------------------------------------------------------- /projects/tiny-mirror/index.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | } 5 | 6 | body { 7 | padding-top: 20px; 8 | text-align: center; 9 | font-family: Arial; 10 | } -------------------------------------------------------------------------------- /projects/converge/index.css: -------------------------------------------------------------------------------- 1 | * { 2 | font-size: 0; 3 | margin: 0; 4 | padding: 0; 5 | } 6 | 7 | body { 8 | background-color: #666; 9 | text-align: center; 10 | font-family: Arial; 11 | } 12 | 13 | canvas { 14 | margin: 20px auto; 15 | box-shadow: 0px 0px 20px rgba(0, 0, 0, 0.5); 16 | } 17 | -------------------------------------------------------------------------------- /projects/hehehe/index.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | } 5 | 6 | body { 7 | padding-top: 20px; 8 | text-align: center; 9 | font-family: Arial; 10 | } 11 | 12 | body, html { 13 | width: 100%; 14 | height: 100%; 15 | } 16 | 17 | canvas, video { 18 | display: none; 19 | width: 32px; 20 | height: 32px; 21 | } -------------------------------------------------------------------------------- /projects/hehehe/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <-- hehehe 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |

Hint: Look at the favicon

13 |

(if nothing happens, click on this page)

14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /projects/trees/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Trees 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /projects/converge/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Converge 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /projects/tiny-mirror/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Tiny Mirror 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |

Hint: Look at the favicon

18 |

(doesn't really work on mobile)

19 |

20 | 21 | 22 | -------------------------------------------------------------------------------- /projects/hehehe/index.js: -------------------------------------------------------------------------------- 1 | window.onload = () => { 2 | // Create favicon link element 3 | const favicon = document.createElement('link'); 4 | favicon.rel = 'shortcut icon'; 5 | favicon.type = 'image/png'; 6 | favicon.href = '../../images/favicon.ico'; 7 | document.getElementsByTagName('head')[0].appendChild(favicon); 8 | // Create hidden canvas 9 | const w = 32; 10 | const h = 32; 11 | const canvas = document.getElementById('canvas'); 12 | canvas.width = w; 13 | canvas.height = h; 14 | // Grab canvas context 15 | const ctx = canvas.getContext('2d'); 16 | // Create hidden video element 17 | const video = document.getElementById('video'); 18 | video.width = w; 19 | video.height = h; 20 | // Loop forever 21 | const loop = () => { 22 | // Copy video to canvas 23 | ctx.drawImage(video, 0, 0, canvas.width, canvas.height); 24 | // Set canvas to favicon 25 | favicon.setAttribute('href', canvas.toDataURL()); 26 | // Loop 27 | setTimeout(loop, 50); 28 | }; 29 | loop(); 30 | document.body.onclick = () => video.play(); 31 | document.body.onfocus = () => video.play(); 32 | document.body.onmouseover = () => video.play(); 33 | }; 34 | 35 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Code Art 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 |

Davy

15 |

Wybiral

16 |

software_dev

17 |
18 |
19 |
20 |

Code Art

21 | 43 |
44 | 45 | 46 | -------------------------------------------------------------------------------- /projects/tiny-mirror/index.js: -------------------------------------------------------------------------------- 1 | // Handle FF 2 | navigator.getUserMedia = navigator.getUserMedia || navigator.mozGetUserMedia; 3 | 4 | window.onload = () => { 5 | // Create favicon link element 6 | const favicon = document.createElement('link'); 7 | favicon.rel = 'shortcut icon'; 8 | favicon.type = 'image/png'; 9 | favicon.href = '../../images/favicon.ico'; 10 | document.getElementsByTagName('head')[0].appendChild(favicon); 11 | // Create hidden canvas 12 | const w = 32; 13 | const h = 32; 14 | const canvas = document.createElement('canvas'); 15 | canvas.style = 'display: none'; 16 | canvas.width = w; 17 | canvas.height = h; 18 | document.body.appendChild(canvas); 19 | // Grab canvas context 20 | const ctx = canvas.getContext('2d'); 21 | // Create hidden video element 22 | const video = document.createElement('video'); 23 | video.style = 'display: none'; 24 | video.width = canvas.width; 25 | video.height = canvas.height; 26 | document.body.appendChild(video); 27 | // Assign user media to video and start loop 28 | navigator.mediaDevices.getUserMedia({video: true}).then(stream => { 29 | video.srcObject = stream; 30 | video.play(); 31 | loop(); 32 | }); 33 | // Flag for mirror image 34 | let mirror = false; 35 | // Loop forever 36 | const loop = () => { 37 | // save transform 38 | ctx.save(); 39 | // Mirror image based on checkbox 40 | if (mirror) { 41 | ctx.translate(canvas.width, 0); 42 | ctx.scale(-1, 1); 43 | } 44 | // Copy video to canvas 45 | ctx.drawImage(video, 0, 0, canvas.width, canvas.height); 46 | // restore transform 47 | ctx.restore(); 48 | // Set canvas to favicon 49 | favicon.setAttribute('href', canvas.toDataURL()); 50 | // Loop 51 | setTimeout(loop, 100); 52 | }; 53 | // Handle checkbox change event 54 | document.getElementById('mirror').addEventListener('change', e => { 55 | mirror = e.target.checked; 56 | }); 57 | }; 58 | 59 | -------------------------------------------------------------------------------- /projects/converge/index.js: -------------------------------------------------------------------------------- 1 | window.onload = function() { 2 | const width = 700; 3 | const height = 700; 4 | let canvas = document.createElement('canvas'); 5 | canvas.width = width; 6 | canvas.height = height; 7 | document.body.appendChild(canvas); 8 | let ctx = canvas.getContext('2d'); 9 | ctx.fillStyle = 'rgb(255,255,255)'; 10 | ctx.fillRect(0, 0, width, height); 11 | let bodies = []; 12 | for (let i = 0; i < 2000; i++) { 13 | bodies.push(create()); 14 | } 15 | start(ctx, bodies); 16 | }; 17 | 18 | function start(ctx, bodies) { 19 | function loop() { 20 | const avgDistance = integrate(bodies); 21 | if (avgDistance > 5) { 22 | requestAnimationFrame(loop); 23 | } 24 | for (var i = 0; i < bodies.length; i++) { 25 | var a = bodies[i]; 26 | ctx.strokeStyle = 'rgba(' + a.r + ', ' + a.g + ', ' + a.b + ', 0.1)'; 27 | ctx.beginPath(); 28 | ctx.moveTo(a.x0, a.y0); 29 | ctx.lineTo(a.x, a.y); 30 | ctx.stroke(); 31 | } 32 | } 33 | loop(); 34 | } 35 | 36 | function integrate(bodies) { 37 | const n = bodies.length; 38 | let totalDistance = 0.0; 39 | for (let i = 0; i < n; i++) { 40 | let a = bodies[i]; 41 | for (let j = i + 1; j < n; j++) { 42 | let b = bodies[j]; 43 | const dx = a.x - b.x; 44 | const dy = a.y - b.y; 45 | const d = Math.sqrt(dx * dx + dy * dy); 46 | const af = b.mass / d; 47 | const bf = a.mass / d; 48 | if (d > 0.01) { 49 | a.xv -= (dx / d) * af; 50 | a.yv -= (dy / d) * af; 51 | b.xv += (dx / d) * bf; 52 | b.yv += (dy / d) * bf; 53 | } 54 | totalDistance += d; 55 | } 56 | } 57 | for (let i = 0; i < n; i++) { 58 | let a = bodies[i]; 59 | a.x0 = a.x; 60 | a.y0 = a.y; 61 | a.x += a.xv; 62 | a.y += a.yv; 63 | a.xv *= 0.95; 64 | a.yv *= 0.95; 65 | } 66 | return totalDistance / (n * n); 67 | } 68 | 69 | function create() { 70 | const r = Math.random() * 50 + 300; 71 | const a = Math.random() * Math.PI * 2; 72 | const x = 350 + Math.cos(a) * r; 73 | const y = 350 + Math.sin(a) * r; 74 | return { 75 | x: x, 76 | y: y, 77 | xv: Math.random() * 0.2 - 0.1, 78 | yv: Math.random() * 0.2 - 0.1, 79 | mass: 0.01, 80 | r: 0 | (x / 700) * 255, 81 | g: 0 | (1 - ((x + y) / 1400)) * 255, 82 | b: 0 | (y / 700) * 255 83 | }; 84 | } -------------------------------------------------------------------------------- /projects/trees/index.js: -------------------------------------------------------------------------------- 1 | // That's right... I'm using globals... *gasp* 2 | let width; 3 | let height; 4 | let canvas; 5 | let ctx; 6 | 7 | window.onload = function() { 8 | width = window.innerWidth; 9 | height = window.innerHeight; 10 | canvas = document.createElement('canvas'); 11 | canvas.width = width; 12 | canvas.height = height; 13 | document.body.appendChild(canvas); 14 | ctx = canvas.getContext('2d'); 15 | ctx.fillStyle = 'rgb(255,255,200)'; 16 | ctx.fillRect(0, 0, width, height); 17 | setTimeout(() => mainLoop([create()]), 5000); 18 | }; 19 | 20 | function mainLoop(particles) { 21 | let nextParticles = []; 22 | 23 | requestAnimationFrame(function() { 24 | mainLoop(nextParticles); 25 | }); 26 | 27 | let spawnCutoff = width / 1000000; 28 | if (Math.random() < spawnCutoff) { 29 | nextParticles.push(create()); 30 | } 31 | 32 | ctx.fillStyle = 'rgba(0, 0, 0, 0.3)'; 33 | for (let i = 0, len = particles.length; i < len; i++) { 34 | renderParticle(particles[i]); 35 | updateParticle(particles[i], nextParticles); 36 | } 37 | 38 | // Nothing lasts forever. Not even these pixels. 39 | ctx.fillStyle = 'rgba(255, 255, 200, 0.05)'; 40 | let n = (width * height * 0.001) | 0; 41 | for (let i = 0; i < n; i++) { 42 | let x = Math.random() * width; 43 | let y = Math.random() * height; 44 | ctx.fillRect(x, y, 1, 1); 45 | } 46 | } 47 | 48 | function renderParticle(p) { 49 | let radius = p.radius; 50 | let n = 1 + (radius * radius * Math.PI * 0.5) | 0; 51 | for (let i = 0; i < n; i++) { 52 | let a = Math.random() * Math.PI * 2; 53 | let r = Math.sqrt(Math.random()) * radius; 54 | let x = p.x + Math.cos(a) * r; 55 | let y = p.y + Math.sin(a) * r; 56 | ctx.fillRect(x, y, 1, 1); 57 | } 58 | } 59 | 60 | function updateParticle(p, nextParticles) { 61 | let d = Math.random() * 1.25; 62 | p.x += Math.cos(p.angle) * d; 63 | p.y += Math.sin(p.angle) * d; 64 | p.angle += Math.random() * 0.02 - 0.01; 65 | p.radius *= 0.998; 66 | if (p.radius > 0.5) { 67 | // This means that the branch continues on 68 | nextParticles.push(p); 69 | let splitCutoff = Math.min(0.005, 1.0 / (p.radius * 10)); 70 | if (Math.random() < splitCutoff) { 71 | // And this means that it splits to become two branches 72 | nextParticles.push({ 73 | x: p.x, 74 | y: p.y, 75 | angle: p.angle + Math.random() - 0.5, 76 | radius: p.radius * 0.9 77 | }); 78 | p.angle += Math.random() - 0.5; 79 | p.radius *= 0.9; 80 | } 81 | } else { 82 | // Let's have a moment of silence for the loss of this great branch. 83 | // ... 84 | } 85 | } 86 | 87 | // A newborn branch. Isn't it cute? 88 | function create() { 89 | return { 90 | x: Math.random() * width, 91 | y: height + 5, 92 | angle: -Math.PI / 2, 93 | radius: Math.random() * 20 + 20, 94 | }; 95 | } 96 | --------------------------------------------------------------------------------