Original Design:
Coding:
Built with:
license: cc-by-nc-sa-4.0 | |
height: 600 |
Original Design:
Coding:
Built with:
<html> | |
<head> | |
<meta charset="UTF-8"> | |
<title>Tokyo 2020 Pattern Generator</title> | |
<script language="javascript" type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.0/p5.min.js"></script> | |
<script language="javascript" type="text/javascript" src="sketch.js"></script> | |
<style> body {padding: 0; margin: 0;} </style> | |
</head> | |
<body> | |
</body> | |
</html> |
function setup() { | |
createCanvas(600, 600); | |
} | |
function draw() { | |
var size = width; | |
var division = 12; | |
var distance = dist(touchX, touchY, width * 0.5, height * 0.5); | |
if (distance < size * 0.5) { | |
division = int(map(distance, 0, size, 3, 12)) * 2; // [6 .. 24] | |
} | |
background(255); | |
drawTessellation(width * 0.5, height * 0.5, size, division); | |
} | |
function drawTessellation(x, y, size, div) { | |
var rounds = (div / 2) - 1; | |
var rotation = TWO_PI / div; | |
var rhombuses = []; | |
for (var i = 0; i < rounds; i++) { | |
rhombuses[i] = new Rhombus(div, i + 1); | |
} | |
var offsets = []; | |
for (var i = 0; i < rhombuses.length; i++) { | |
var offset = 0; | |
if (i == 1) { | |
offset = 1; | |
} else if (i > 1) { | |
offset += offsets[i-2]; | |
offset += rhombuses[i-2].vertices[2].x; | |
} | |
offsets[i] = offset; | |
} | |
var maxRadius = (offsets[rhombuses.length - 1] + rhombuses[rhombuses.length - 1].vertices[2].x); | |
var scaling = size / maxRadius * 0.5; | |
var wholeRotation = floor(frameCount / 120) * TWO_PI / div + map(easeInAndOut((frameCount % 120) / 120.0), 0, 1, 0, TWO_PI / div) | |
push(); | |
translate(x, y); | |
rotate(wholeRotation); | |
scale(scaling); | |
strokeWeight(1/scaling); | |
for (var i = 0; i < rhombuses.length; i++) { | |
//stroke(map(k, 0, rhombuses.length-1, 240, 180), 200, 200); | |
for (var j = 0; j < div; j++) { | |
push(); | |
if (j > div / 2 + i && j < div) { | |
translate(0, maxRadius); | |
} | |
rotate(rotation * (i * -0.5 +j)); | |
translate(offsets[i], 0); | |
if (j > div / 2 + i && j < div) { | |
rhombuses[i].draw(); | |
} else if (j > i && j < div / 2) { | |
} else { | |
rhombuses[i].draw(); | |
} | |
pop(); | |
} | |
} | |
pop(); | |
} | |
var Rhombus = function(div, index) { | |
var rotation = TWO_PI / div; | |
this.vertices = []; | |
this.vertices[0] = new p5.Vector(0, 0); | |
this.vertices[1] = new p5.Vector(cos(rotation * index * -0.5), sin(rotation * index * -0.5)); | |
this.vertices[2] = new p5.Vector(cos(rotation * index * 0.5) * 2, 0); | |
this.vertices[3] = new p5.Vector(cos(rotation * index * 0.5), sin(rotation * index * 0.5)); | |
} | |
Rhombus.prototype.draw = function() { | |
var easing = easeInAndOut((frameCount % 120) / 120.0); | |
var p = (easing + 0.5) % 1.0; // 0.5 -> 0.99 -> 0.0 -> 0.49 | |
var colorp = abs(easing - 0.5); | |
stroke(map(colorp, 0, 0.5, 255, 220)); | |
noFill(); | |
beginShape(); | |
for (var i = 0; i < this.vertices.length; i++) { | |
vertex(this.vertices[i].x, this.vertices[i].y); | |
} | |
endShape(CLOSE); | |
noStroke(); | |
fill(map(colorp, 0, 0.5, 160, 0), map(colorp, 0, 0.5, 160, 0), map(colorp, 0, 0.5, 160, 80)); | |
beginShape(); | |
for (var i = 0; i < this.vertices.length; i++) { | |
var x = lerp(this.vertices[i].x, this.vertices[(i+1)%this.vertices.length].x, p); | |
var y = lerp(this.vertices[i].y, this.vertices[(i+1)%this.vertices.length].y, p); | |
vertex(x, y); | |
} | |
endShape(CLOSE); | |
} | |
easeInAndOut = function(t) { | |
return 3 * t * t - 2 * t * t * t; | |
}; | |
// var frameEl = window.frameElement; | |
// if (frameEl) { | |
// frameEl.style.height = "600px"; | |
// } |