Skip to content

Instantly share code, notes, and snippets.

@dribnet
Last active October 18, 2017 13:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 28 You must be signed in to fork a gist
  • Save dribnet/b963e498ccfce6a14de7827c1df6e665 to your computer and use it in GitHub Desktop.
Save dribnet/b963e498ccfce6a14de7827c1df6e665 to your computer and use it in GitHub Desktop.
17.2.MDDN342 PS4
license: mit
height: 720

PS4 MDDN 342 2017

In my example I am starting with the classic 10print commodore screen. My idea is to expose additional levels of maze as a person zooms in closer. In my case, the additional maze elements will appear behind the original layer. The smaller mazes will also have more structure and less contrast than the largest layers.

This README should be updated as the code changes. Replace this placeholder text and use this README as a design journal to record your process. Be sure to use complete sentences, and you can reference your sketch which will appear above. The explanation should be short but complete, roughly 100 words.

Also update both images keeping their original sizes: preview.png (960x500) and thumbnail.png (230x120).

/*
* This is the funciton to implement to make your own abstract design.
*
* arguments:
* p5: the p5.js object - all draw commands should be prefixed with this object
* x1, x2, y1, y2: draw the pattern contained in the rectangle x1,y1 to x2, y2
* z: use this as the noise z offset (can be shifted)
* zoom: current zoom level (starts at 0), useful to decide how much detail to draw
*
* The destination drawing should be in the square 0, 0, 255, 255.
*/
function drawGrid(p5, x1, x2, y1, y2, z, zoom) {
// debug - show border
p5.noFill();
p5.stroke(255, 0, 0)
p5.rect(0, 0, 255, 255);
}
/*
* This is the funciton to implement to make your own abstract design.
*
* arguments:
* p5: the p5.js object - all draw commands should be prefixed with this object
* x1, x2, y1, y2: draw the pattern contained in the rectangle x1,y1 to x2, y2
* z: use this as the noise z offset (can be shifted)
* zoom: current zoom level (starts at 0), useful to decide how much detail to draw
*
* The destination drawing should be in the square 0, 0, 255, 255.
*/
function drawGrid1(p5, x1, x2, y1, y2, z, zoom) {
// debug - show border
var noiseScale=0.1;
// local to global
var center_x = p5.map(128, 0, 256, x1, x2)
var center_y = p5.map(128, 0, 256, y1, y2)
var noiseX = p5.noise(center_x * noiseScale,
center_y * noiseScale, z);
var noiseY = p5.noise(center_x * noiseScale,
center_y * noiseScale, z+50);
var offsetX = p5.map(noiseX, 0, 1, -64, 64);
var offsetY = p5.map(noiseY, 0, 1, -64, 64);
var local_center_x = p5.map(center_x + offsetX, x1, x2, 0, 256);
var local_center_y = p5.map(center_y + offsetY, y1, y2, 0, 256);
p5.fill(0, 0, 128);
p5.ellipse(local_center_x, local_center_y, 64);
// debug - show border
p5.noFill();
p5.stroke(255, 0, 0)
p5.rect(0, 0, 255, 255);
}
function getOffsetPoint(p5, canvasX, canvasY, x1, x2, y1, y2, z, noiseScale) {
var center_x = p5.map(canvasX, 0, 256, x1, x2)
console.log("Example: ", center_x, canvasX, x1, x2)
var center_y = p5.map(canvasY, 0, 256, y1, y2)
var noiseX = p5.noise(center_x * noiseScale,
center_y * noiseScale, z);
var noiseY = p5.noise(center_x * noiseScale,
center_y * noiseScale, z+50);
var offsetX = p5.map(noiseX, 0, 1, -96, 96);
var offsetY = p5.map(noiseY, 0, 1, -96, 96);
var local_center_x = p5.map(center_x + offsetX, x1, x2, 0, 256);
var local_center_y = p5.map(center_y + offsetY, y1, y2, 0, 256);
return [local_center_x, local_center_y]
}
function drawGrid(p5, x1, x2, y1, y2, z, zoom) {
// debug - show border
var noiseScale=0.1;
var p = getOffsetPoint(p5, 127, 127, x1, x2, y1, y2, z, 0.1);
// local to global
p5.fill(0, 0, 128);
p5.noStroke();
p5.ellipse(p[0], p[1], 64);
p5.stroke(0, 0, 128);
p5.strokeWeight(10);
for(var i=-1; i<2; i++) {
for(var j=-1; j<2; j++) {
if((i==0 || j==0) && (i!=j)) {
var neighbor_x = 127 + 256 * i;
var neighbor_y = 127 + 256 * j;
var p2 = getOffsetPoint(p5, neighbor_x, neighbor_y, x1, x2, y1, y2, z, 0.1);
p5.line(p[0], p[1], p2[0], p2[1]);
}
}
}
// debug - show border
// p5.noFill();
// p5.stroke(255, 0, 0, 30)
// p5.rect(0, 0, 255, 255);
}
function drawGrid(p5, x1, x2, y1, y2, z, zoom) {
var noiseScale=0.02;
p5.noiseDetail(8,0.5);
p5.noStroke();
for(var i=0; i<16; i++) {
var n_x = p5.map(i, 0, 16, x1, x2);
for(var j=0; j<16; j++) {
var n_y = p5.map(j, 0, 16, y1, y2);
var noiseVal = p5.noise(n_x * noiseScale,
n_y * noiseScale, z);
p5.fill(noiseVal*255);
p5.rect(i*16, j*16, 16, 16);
}
}
// debug - show border
// p5.noFill();
// p5.stroke(255, 0, 0)
// p5.rect(0, 0, 255, 255);
}
<head>
<style> body {padding: 0; margin: 0;} </style>
</head>
<body style="background-color:white">
<img src="sketch.png" width="960" height="720"/>
</body>
<!DOCTYPE html>
<html>
<head>
<title>17.2.MDDN342 PS4</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.2.0/dist/leaflet.css" />
<style>
body {
padding: 0;
margin: 0;
}
html, body, #map {
height: 100%;
width: 100%;
}
</style>
</head>
<body>
<div id="map"></div>
<script src="http://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.14/p5.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.14/addons/p5.dom.js"></script>
<script src="https://unpkg.com/leaflet@1.2.0/dist/leaflet.js"></script>
<script src="leaflet-hash.js"></script>
<script src="10print.js"></script>
<script src="map.js"></script>
</body>
</html>
(function(window) {
var HAS_HASHCHANGE = (function() {
var doc_mode = window.documentMode;
return ('onhashchange' in window) &&
(doc_mode === undefined || doc_mode > 7);
})();
L.Hash = function(map) {
this.onHashChange = L.Util.bind(this.onHashChange, this);
if (map) {
this.init(map);
}
};
L.Hash.parseHash = function(hash) {
if(hash.indexOf('#') === 0) {
hash = hash.substr(1);
}
var args = hash.split("/");
if (args.length == 5) {
var seed = parseInt(args[0], 10),
zoom = parseInt(args[1], 10),
lat = parseFloat(args[2]),
lon = parseFloat(args[3]);
depth = parseFloat(args[4]);
if (isNaN(zoom) || isNaN(lat) || isNaN(lon)) {
return false;
} else {
return {
center: new L.LatLng(lat, lon),
zoom: zoom,
seed: seed,
depth: depth
};
}
} else {
return false;
}
};
L.Hash.formatHash = function(map) {
var seed = map._p5_seed,
depth = map._p5_depth,
center = map.getCenter(),
zoom = map.getZoom(),
precision = 12;
// precision = Math.max(0, Math.ceil(Math.log(zoom*zoom) / Math.LN2));
return "#" + [seed, zoom,
center.lat.toFixed(precision),
center.lng.toFixed(precision),
depth.toFixed(precision)
].join("/");
},
L.Hash.prototype = {
map: null,
lastHash: null,
parseHash: L.Hash.parseHash,
formatHash: L.Hash.formatHash,
init: function(map) {
this.map = map;
// reset the hash
this.lastHash = null;
this.onHashChange();
if (!this.isListening) {
this.startListening();
}
},
removeFrom: function(map) {
if (this.changeTimeout) {
clearTimeout(this.changeTimeout);
}
if (this.isListening) {
this.stopListening();
}
this.map = null;
},
onMapMove: function() {
// bail if we're moving the map (updating from a hash),
// or if the map is not yet loaded
if (this.movingMap || !this.map._loaded) {
return false;
}
var hash = this.formatHash(this.map);
if (this.lastHash != hash) {
location.replace(hash);
this.lastHash = hash;
}
},
movingMap: false,
update: function() {
var hash = location.hash;
if (hash === this.lastHash) {
return;
}
var parsed = this.parseHash(hash);
if (parsed) {
var do_reset = false;
if (!("_hash_parsed" in this.map)) {
do_reset = true;
}
this.map._hash_parsed = true;
this.map._p5_seed = parsed.seed;
this.map._p5_depth = parsed.depth;
this.movingMap = true;
this.map.setView(parsed.center, parsed.zoom, {reset: do_reset});
this.movingMap = false;
}
else if (!("_hash_parsed" in this.map)) {
this.map._hash_parsed = true;
var center = this.map.getCenter();
var zoom = this.map.getZoom();
this.map.setView(center, zoom, {reset: true});
}
else {
this.onMapMove(this.map);
}
},
// defer hash change updates every 100ms
changeDefer: 100,
changeTimeout: null,
onHashChange: function() {
// throttle calls to update() so that they only happen every
// `changeDefer` ms
if (!this.changeTimeout) {
var that = this;
this.changeTimeout = setTimeout(function() {
that.update();
that.changeTimeout = null;
}, this.changeDefer);
}
},
isListening: false,
hashChangeInterval: null,
startListening: function() {
this.map.on("moveend", this.onMapMove, this);
if (HAS_HASHCHANGE) {
L.DomEvent.addListener(window, "hashchange", this.onHashChange);
} else {
clearInterval(this.hashChangeInterval);
this.hashChangeInterval = setInterval(this.onHashChange, 50);
}
this.isListening = true;
},
stopListening: function() {
this.map.off("moveend", this.onMapMove, this);
if (HAS_HASHCHANGE) {
L.DomEvent.removeListener(window, "hashchange", this.onHashChange);
} else {
clearInterval(this.hashChangeInterval);
}
this.isListening = false;
}
};
L.hash = function(map) {
return new L.Hash(map);
};
L.Map.prototype.addHash = function() {
this._hash = L.hash(this);
};
L.Map.prototype.removeHash = function() {
this._hash.removeFrom();
};
})(window);
var worldMap = new L.Map('map', {
continuousWorld:true,
minZoom: 0,
maxZoom: 45,
crs: L.CRS.Simple,
attributionControl: false,
center: [512, 512],
zoom: 0});
worldMap._p5_seed = Math.floor(Math.random() * 1000);
worldMap._p5_depth = 0.0;
// console.log("Seed start", worldMap._p5_seed)
// Assuming your map instance is in a variable called map
var hash = new L.Hash(worldMap);
// console.log("Seed now", worldMap._p5_seed)
var s = function( p ) {
p.setup = function() {
canvas = p.createCanvas(p._L_width, p._L_height);
p.noLoop();
};
p.draw = function() {
if ("_L_size" in p && "_L_nw" in p) {
var nw = p._L_nw;
var t_size = p._L_size;
var zoom = p._L_zoom;
var m_x1 = nw.lng;
var m_y1 = -nw.lat;
var m_x2 = m_x1 + t_size;
var m_y2 = m_y1 + t_size;
var depth = p._L_depth;
p.noiseSeed(p._L_seed)
drawGrid(p, m_x1, m_x2, m_y1, m_y2, depth, zoom);
}
};
};
var tiles = new L.GridLayer({continuousWorld: true});
tiles.createTile = function(coords) {
if (!("_hash_parsed" in worldMap)) {
return L.DomUtil.create('canvas', 'leaflet-tile');
}
var size = this.getTileSize();
var myp5 = new p5(s);
myp5._L_width = size.x;
myp5._L_height = size.y;
myp5._L_zoom = coords.z;
myp5._L_seed = worldMap._p5_seed;
myp5._L_depth = worldMap._p5_depth;
myp5._L_coords = coords;
// calculate projection coordinates of top left tile pixel
myp5._L_nwPoint = coords.scaleBy(size);
myp5._L_size = 256.0 / Math.pow(2, coords.z)
// calculate geographic coordinates of top left tile pixel
myp5._L_nw = worldMap.unproject(myp5._L_nwPoint, coords.z)
myp5._start();
var tile = myp5.canvas;
L.DomUtil.addClass(tile, 'leaflet-tile');
return tile;
}
tiles.addTo(worldMap)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment