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.