A tileable background generator using truchet tiles with alternated coloring
A Pen by Ben Matthews on CodePen.
<div id="controls"></div> |
let grid, cells, tiles; | |
let mx = 0; | |
let my = 0; | |
let cellSize = 20; | |
let paths = [ | |
[[0,0], [.5, 0], [0, .5]], | |
[[.5, 0],[1, 0],[1, .5], [.5, 1], [0, 1], [0, .5]], | |
[[1, 1], [1, .5], [.5, 1]], | |
] | |
class Cell{ | |
constructor(x, y, left){ | |
this.x = x; | |
this.y = y; | |
this.left = left; | |
this.col = 1; | |
} | |
render(){ | |
let [x, y] = [this.x, this.y]; | |
let idx = this.left ? 0 : 2; | |
let t = tiles[idx + 1 - this.col]; | |
image(t, x, y, 1, 1); | |
} | |
} | |
//TODO meta tiles | |
class Tile{ | |
constructor(x, y, size){ | |
this.x = x; | |
this.y = y; | |
this.g = createGraphics(this.size,this.size); | |
} | |
} | |
function setup (){ | |
pixelDensity(1); | |
createCanvas(); | |
colorMode(HSB, 1, 1, 1); | |
windowResized(); | |
} | |
let createGrid = () => { | |
grid = []; | |
cells = []; | |
tiles = []; | |
[gw, gh] = [floor(width/cellSize), floor(height/cellSize)]; | |
[gw, gh] = [max(floor(gw/2)*2, 2), max(floor(gh/2)*2, 2)];//tileable | |
for (let i = 0; i < gw; i++){ | |
grid.push([]); | |
for (let j = 0; j < gh; j++){ | |
let cell = new Cell(i, j, random() < .5); | |
grid[i].push(cell); | |
cells.push(cell); | |
} | |
} | |
} | |
let updateColors = () => { | |
for (let i = 0; i < gw; i++){ | |
for (let j = 0; j < gh; j++){ | |
let c = grid[i][j]; | |
if (i == 0){ | |
if (j != 0){ | |
let c2 = grid[i][j-1]; | |
if (c.left ^ c2.left) c.col = c2.col; | |
else c.col = 1-c2.col; | |
} | |
} else { | |
let c2 = grid[i-1][j]; | |
if (c.left ^ c2.left) c.col = c2.col; | |
else c.col = 1-c2.col; | |
} | |
} | |
} | |
} | |
let createTiles = () => { | |
tiles.map(t => t.remove()); | |
tiles = []; | |
//noise | |
let n = createGraphics(cellSize, cellSize) | |
for (let i = 0; i < cellSize; i++){ | |
for (let j = 0; j < cellSize; j++){ | |
n.stroke(0, 20 + random()*50); | |
n.point(i, j); | |
} | |
} | |
//tiles | |
for (let i = 0; i < 4; i++){ | |
let g = createGraphics(cellSize, cellSize); | |
g.colorMode(HSB, 1, 1, 1); | |
let col = i%2; | |
let left = floor(i/2); | |
g.noStroke(); | |
g.scale(cellSize); | |
if (left == 0){ | |
g.translate(1, 0); | |
g.scale(-1, 1); | |
} | |
for (let i = 0; i < 3; i++){ | |
g.fill(.6, col, 1); | |
if (i%2 == 1) g.fill(.6, 1 - col, 1); | |
let path = paths[i]; | |
g.beginShape(); | |
path.map(p => vertex(p[0], p[1])); | |
g.endShape(CLOSE); | |
} | |
g.strokeWeight(3/cellSize); | |
g.stroke(0); | |
g.line(.5, 0, 0, .5); | |
g.line(1, .5, .5, 1); | |
g.image(n, 0, 0, 1, 1); | |
tiles.push(g); | |
} | |
} | |
function init(){ | |
createGrid(); | |
createTiles(); | |
updateColors(); | |
} | |
function draw(){ | |
background(0); | |
scale(width/gw, height/gh); | |
cells.map(c => c.render()); | |
} | |
function mouseMoved(){ | |
let [px, py] = [mx, my]; | |
mx = floor(mouseX/(width/gw)); | |
my = floor(mouseY/(height/gh)); | |
if (px != mx || py != my){ | |
let c = grid[mx][my]; | |
c.left ^= true; | |
updateColors(); | |
} | |
} | |
function mousePressed(){init()} | |
function windowResized(){ | |
resizeCanvas(windowWidth, windowHeight) | |
init(); | |
} |
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.10.2/p5.min.js"></script> |
* { margin:0; padding:0; } | |
html, body { width:100%; height:100%; overflow: hidden; background:black;} | |
canvas { display:block; } | |
#controls { | |
z-index: 2; | |
margin: 20px; | |
position: absolute; | |
top: 0; left: 0; | |
color: white; | |
} |
A tileable background generator using truchet tiles with alternated coloring
A Pen by Ben Matthews on CodePen.