Skip to content

Instantly share code, notes, and snippets.

@tompng
Last active September 10, 2018 14:20
Show Gist options
  • Save tompng/10423da61b8d32a39c12759b2195e77c to your computer and use it in GitHub Desktop.
Save tompng/10423da61b8d32a39c12759b2195e77c to your computer and use it in GitHub Desktop.
人という字は、人と人が支え合ってできています (フラクタル) https://twitter.com/tompng/status/1038799318398853121
<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