Last active
September 10, 2018 14:20
-
-
Save tompng/10423da61b8d32a39c12759b2195e77c to your computer and use it in GitHub Desktop.
人という字は、人と人が支え合ってできています (フラクタル) https://twitter.com/tompng/status/1038799318398853121
This file contains 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
<script> | |
const scaleRatio = 0.75 | |
function humanFromCanvas(base, alpha){ | |
const output = document.createElement('canvas') | |
const size = 1024 | |
output.width = output.height = size | |
const ctx = output.getContext('2d') | |
ctx.globalAlpha = alpha || 1 | |
ctx.translate(size/2, size/2) | |
ctx.scale(scaleRatio, scaleRatio) | |
ctx.translate(-size/2, -size/2) | |
ctx.scale(size, size) | |
ctx.save() | |
ctx.translate(-0.13,0.31) | |
ctx.rotate(-Math.PI/5) | |
ctx.translate(0.5,0.7) | |
ctx.scale(-0.8,0.65) | |
ctx.scale(1/scaleRatio, 1/scaleRatio) | |
ctx.drawImage(base, -0.5, -0.5, 1, 1) | |
ctx.restore() | |
ctx.save() | |
ctx.translate(0.18,-0.05) | |
ctx.rotate(Math.PI/6) | |
ctx.scale(0.8,0.8) | |
ctx.translate(0.5, 0.5) | |
ctx.scale(1/scaleRatio, 1/scaleRatio) | |
ctx.drawImage(base, -0.5, -0.5, 1, 1) | |
ctx.restore() | |
return output | |
} | |
function scaleMessage(canvas, msg, color){ | |
const output = document.createElement('canvas') | |
const w = output.width = canvas.width | |
const h = output.height = canvas.height | |
const ctx = output.getContext('2d') | |
function trans() { | |
ctx.translate(w / 2, h / 2) | |
ctx.scale(scaleRatio, scaleRatio) | |
ctx.translate(-w / 2, -h / 2) | |
} | |
ctx.save() | |
const hoffset = h / 16 | |
const woffset = w / 16 | |
trans() | |
ctx.fillStyle=color || '#ccc'; | |
ctx.globalAlpha=0.6; | |
ctx.fillRect(-4-woffset,-4-hoffset,w+4*2+woffset*2,h+4*2+hoffset*2) | |
ctx.globalAlpha=1 | |
ctx.restore() | |
ctx.drawImage(canvas, 0, 0, w, h) | |
ctx.save() | |
trans() | |
ctx.lineWidth = 2 | |
ctx.fillStyle = 'black' | |
ctx.strokeRect(-4-woffset,-4-hoffset,w+4*2+woffset*2,h+4*2+hoffset*2) | |
ctx.font = '200px sans-serif' | |
ctx.fillText(msg, -woffset, 200-hoffset) | |
ctx.restore() | |
return output | |
} | |
function scaleBase(canvas){ | |
const output = document.createElement('canvas') | |
const w = output.width = canvas.width | |
const h = output.height = canvas.height | |
const ctx = output.getContext('2d') | |
ctx.translate(w / 2, h / 2) | |
ctx.scale(scaleRatio, scaleRatio) | |
ctx.translate(-w / 2, -h / 2) | |
ctx.drawImage(canvas, 0, 0, w, h) | |
return output | |
} | |
function createBase() { | |
const canvas = document.createElement('canvas') | |
const size = 1024 | |
canvas.width = canvas.height = size | |
const ctx = canvas.getContext('2d') | |
ctx.beginPath() | |
const r = size | |
const w = size / 10 | |
const th = Math.asin(size/2/r) | |
const cos = Math.cos(th) | |
ctx.arc(size/2 - (r - w / 2) * cos, size/2, r - w / 2, -th, th) | |
ctx.lineWidth = w | |
ctx.stroke() | |
return canvas | |
} | |
function cropImage(canvas) { | |
const output = document.createElement('canvas') | |
const w = output.width = canvas.width | |
const h = output.height = canvas.height * 1 | |
const ctx = output.getContext('2d') | |
ctx.fillStyle='white' | |
ctx.fillRect(0,0,w,h) | |
ctx.drawImage(canvas, -(canvas.width-w)/2, -(canvas.height-h)/2) | |
return output | |
} | |
function createTile(images) { | |
const output = document.createElement('canvas') | |
const n = Math.ceil(Math.sqrt(images.length)) | |
const w = Math.max(...images.map(c=>c.width)) | |
const h = Math.max(...images.map(c=>c.height)) | |
const nw = n | |
const nh = Math.ceil(images.length / n) | |
const scale = 1 / n | |
output.width = w * nw * scale | |
output.height = h * nh * scale | |
const ctx = output.getContext('2d') | |
ctx.fillStyle = 'white' | |
ctx.fillRect(0, 0, output.width, output.height) | |
ctx.scale(scale, scale) | |
for (let y = 0; y < nh; y++) { | |
for (let x = 0; x < nw; x++) { | |
const img = images[y * nw + x] | |
if (img) ctx.drawImage(img, x * w, y * h) | |
} | |
} | |
return output | |
} | |
onload = () => { | |
show(createIt(1, true)) | |
show(createIt(2, true)) | |
show(createTile([ | |
createIt(3, false), | |
createIt(4, false), | |
createIt(8, false), | |
createIt(16, false) | |
])) | |
show(createIt(32, false)) | |
} | |
function createIt(n, flg){ | |
let canvas = scaleBase(createBase()) | |
for(i=1;i<n;i++)canvas = humanFromCanvas(canvas, 0.95) | |
if (flg)canvas = scaleMessage(canvas, 'ひと') | |
canvas = humanFromCanvas(canvas) | |
canvas = scaleMessage(canvas, '', 'white') | |
// canvas = cropImage(canvas) | |
const ctx = canvas.getContext('2d') | |
ctx.textAlign = 'right' | |
ctx.font = '96px courier' | |
ctx.fillStyle = 'black' | |
ctx.fillText('Human n=' + n, canvas.width - 84, canvas.height-16) | |
return canvas | |
} | |
function show(canvas) { | |
canvas.style.border='1px solid red' | |
canvas.style.width='50%' | |
document.body.appendChild(canvas) | |
} | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment