Last active
June 16, 2020 05:43
-
-
Save Meshiest/b9e0b11a742ef340671ac14d69148648 to your computer and use it in GitHub Desktop.
Trianglify all images on any webpage
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Put this in a bookmark: | |
javascript:var s=document.createElement('script');s.src='https://gistcdn.githack.com/Meshiest/b9e0b11a742ef340671ac14d69148648/raw/trianglify.js';document.body.appendChild(s); | |
*/ | |
function trianglify(image) { | |
const triangles = 40; | |
const scaleAmt = 0.2; | |
const slow = 0; | |
if (image.width === 0 || image.height === 0 || !image.complete) | |
return; | |
if (image.getAttribute('zapped') && image.getAttribute('zapped') === image.src) | |
return; | |
const loadImage = url => new Promise((resolve, reject) => { | |
const fake = new Image(); | |
fake.src = url; | |
fake.onload = () => resolve(fake); | |
fake.onerror = reject; | |
}); | |
const secureImage = url => url.indexOf('data') === 0 ? loadImage(url) : fetch('https://cors-anywhere.herokuapp.com/' + url, {}) | |
.then(r => r.blob()) | |
.then(blob => URL.createObjectURL(blob)) | |
.then(url => loadImage(url)); | |
const genTriangle = (w, h) => { | |
const size = Math.min(w, h); | |
const randMag = () => Math.random() * size/4 + size/8; | |
const arcA = Math.random() * Math.PI; | |
const arcB = arcA + (Math.random() * Math.PI / 4 - Math.PI / 8) + Math.PI * 2 / 3; | |
const arcC = arcB + (Math.random() * Math.PI / 4 - Math.PI / 8) + Math.PI * 2 / 3; | |
const polarToCartesian = (ang, mag, [x, y]) => [ | |
Math.floor(Math.cos(ang) * mag + x), | |
Math.floor(Math.sin(ang) * mag + y), | |
]; | |
const center = [ | |
(Math.random() * 0.8 + 0.1) * w, | |
(Math.random() * 0.8 + 0.1) * h, | |
]; | |
return { | |
points: [arcA, arcB, arcC].map(rad => polarToCartesian(rad, randMag(), center)), | |
center, | |
}; | |
}; | |
const run = (image, dest) => { | |
const canvas = document.createElement('canvas'); | |
const ctx = canvas.getContext('2d'); | |
canvas.style.width = (canvas.width = ctx.canvas.width = image.width) + 'px'; | |
canvas.style.height = (canvas.height = ctx.canvas.height = image.height) + 'px'; | |
ctx.drawImage(image, 0, 0); | |
for(let i = 0; i < triangles; i++) { | |
const ctx = canvas.getContext('2d'); | |
ctx.save(); | |
ctx.beginPath(); | |
const {points: [start, ...points], center} = genTriangle(ctx.canvas.width, ctx.canvas.height); | |
ctx.moveTo(...start); | |
points.forEach(p => ctx.lineTo(...p)); | |
const scale = Math.random() * scaleAmt + 1; | |
ctx.translate((center[0]-center[0]*scale), (center[1]-center[1]*scale)); | |
ctx.scale(scale, scale); | |
ctx.clip(); | |
ctx.drawImage(canvas, 0, 0); | |
ctx.restore(); | |
} | |
console.log('Zapped', dest.src); | |
try { | |
dest.src = canvas.toDataURL(); | |
dest.setAttribute('zapped', dest.src); | |
} catch (e) { | |
console.error(e); | |
} | |
} | |
secureImage(image.src) | |
.then(fake => run(fake, image)); | |
} | |
setInterval(() => Array.from(document.querySelectorAll('img')).forEach(trianglify), 1000); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment