Adding animation based on z.
-
-
Save uwcc/d02410a84de1c7fb006fb0488da00019 to your computer and use it in GitHub Desktop.
PS4 MDDN 342 2018
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
license: mit | |
height: 720 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const max_thickness = 64; | |
const max_movement = 0; | |
const ball_radius = 32; | |
const line_width = 8; | |
const grid_size = 64; | |
let do_animation = true; | |
/* the random number seed for the tour */ | |
var tourSeed = 150; | |
/* triplets of locations: zoom, x, y */ | |
var tourPath = [ | |
[2, -146, 1132], | |
[2, -149, 1257] | |
] | |
/* this function takes a coordinate and aligns to a grid of size gsize */ | |
function snap_to_grid(num, gsize) { | |
return (num - (num % gsize)); | |
} | |
/* this function returns a point offset by noise at that location */ | |
function getOffsetPoint(p5, x, y, z, noiseScale) { | |
let offsetX = getRandomValue(p5, x, y, z, "offsetX", -max_movement, max_movement, noiseScale); | |
let offsetY = getRandomValue(p5, x, y, z, "offsetY", -max_movement, max_movement, noiseScale); | |
return [x+offsetX, y+offsetY] | |
} | |
function drawPetals(p5, x1, x2, y1, y2, pos_x, pos_y, rad1, rad2, z) { | |
const sqrt2 = 1.4142/2; | |
let offsets = [ | |
[sqrt2, sqrt2], | |
[-sqrt2, sqrt2], | |
[-sqrt2, -sqrt2], | |
[sqrt2, -sqrt2] | |
] | |
let phase = getRandomValue(p5, pos_x, pos_y, z, "phase", 0, 2*p5.PI, 0.1); | |
let freq = getRandomValue(p5, pos_x, pos_y, z, "freq", 10, 50, 0.1); | |
let sineWave = p5.sin(phase + (p5.globalFrameCount / freq)); | |
let radiusScale = p5.map(sineWave, -1, 1, 0.80, 1.0); | |
let pixel_posx1 = p5.map(pos_x, x1, x2, 0, 256); | |
let pixel_posx2 = p5.map(pos_x+rad2, x1, x2, 0, 256); | |
let pixel_radius = pixel_posx2 - pixel_posx1; | |
pixel_radius = radiusScale * pixel_radius; | |
for(let i=0; i<offsets.length; i++) { | |
let offset = offsets[i]; | |
let pixel_x = p5.map(pos_x+0.5*rad1*offset[0], x1, x2, 0, 256); | |
let pixel_y = p5.map(pos_y+0.5*rad1*offset[1], y1, y2, 0, 256); | |
p5.ellipse(pixel_x, pixel_y, pixel_radius); | |
} | |
} | |
function drawStamens(p5, x1, x2, y1, y2, pos_x, pos_y, rad1, rad2, drawLines, z) { | |
const offsets = [ | |
[1, 1], | |
[1, -1], | |
[-1, 1], | |
[-1, -1] | |
] | |
let pixel_posx1 = p5.map(pos_x, x1, x2, 0, 256); | |
let pixel_posx2 = p5.map(pos_x+rad2, x1, x2, 0, 256); | |
let pixel_radius = pixel_posx2 - pixel_posx1; | |
let z_fraction = z % 1.0; | |
let num_stamens = p5.map(z_fraction, 0, 1, 0, offsets.length) | |
for(var i=0; i<offsets.length; i++) { | |
let offset = offsets[i]; | |
let pixel_x = p5.map(pos_x+0.5*rad1*offset[0], x1, x2, 0, 256); | |
let pixel_y = p5.map(pos_y+0.5*rad1*offset[1], y1, y2, 0, 256); | |
p5.strokeWeight(0); | |
p5.ellipse(pixel_x, pixel_y, pixel_radius); | |
if(drawLines) { | |
p5.strokeWeight(pixel_radius / 20); | |
p5.line(pixel_x-pixel_radius, pixel_y, pixel_x+pixel_radius, pixel_y); | |
p5.line(pixel_x, pixel_y-pixel_radius, pixel_x, pixel_y+pixel_radius); | |
p5.strokeWeight(0); | |
p5.ellipse(pixel_x, pixel_y, pixel_radius / 12); | |
} | |
} | |
} | |
/* | |
* 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) { | |
/* max_shift is the amount of overlap a tile can spill over into its neighbors */ | |
let max_shift = max_thickness + max_movement; | |
/* For animation: updated z based on global frame count */ | |
let dz = p5.globalFrameCount / 100.0; | |
z = z + dz; | |
/* this rectangle defines the region that will be drawn and includes a margin */ | |
let min_x = snap_to_grid(x1 - max_shift, grid_size); | |
let max_x = snap_to_grid(x2 + max_shift + grid_size, grid_size); | |
let min_y = snap_to_grid(y1 - max_shift, grid_size); | |
let max_y = snap_to_grid(y2 + max_shift + grid_size, grid_size); | |
// debug version: draw one | |
// let half_x = (x1 + x2) / 2; | |
// let half_y = (y1 + y2) / 2; | |
// min_x = snap_to_grid(half_x, grid_size); | |
// max_x = snap_to_grid(half_x + grid_size, grid_size); | |
// min_y = snap_to_grid(half_y, grid_size); | |
// max_y = snap_to_grid(half_y + grid_size, grid_size); | |
let c_p00 = p5.map(0, x1, x2, 0, 256); | |
let c_plwidth = p5.map(line_width, x1, x2, 0, 256); | |
let c_pball = p5.map(ball_radius, x1, x2, 0, 256); | |
let cur_line_width = c_plwidth - c_p00; | |
let cur_ball_radius = c_pball - c_p00; | |
p5.background(255); | |
for(let x=min_x; x<max_x; x+=grid_size) { | |
for(let y=min_y; y<max_y; y+=grid_size) { | |
// First compute shifted point in grid | |
let offsetX = getRandomValue(p5, x, y, z, "shiftX", -max_movement, max_movement, 0.1); | |
let offsetY = getRandomValue(p5, x, y, z, "shiftY", -max_movement, max_movement, 0.1); | |
let shifted_x = x + offsetX; | |
let shifted_y = y + offsetY; | |
let x_pos = p5.map(shifted_x, x1, x2, 0, 256); | |
let y_pos = p5.map(shifted_y, y1, y2, 0, 256); | |
// now compute shifted point one step to the left | |
let x_left = x + grid_size; | |
let y_left = y; | |
let offsetX_left = getRandomValue(p5, x_left, y_left, z, "shiftX", -max_movement, max_movement, 0.1); | |
let offsetY_left = getRandomValue(p5, x_left, y_left, z, "shiftY", -max_movement, max_movement, 0.1); | |
let shifted_x_left = x_left + offsetX_left; | |
let shifted_y_left = y_left + offsetY_left; | |
let x_pos_left = p5.map(shifted_x_left, x1, x2, 0, 256); | |
let y_pos_left = p5.map(shifted_y_left, y1, y2, 0, 256); | |
// lastly compute shifted point one step down | |
let x_down = x; | |
let y_down = y + grid_size; | |
let offsetX_down = getRandomValue(p5, x_down, y_down, z, "shiftX", -max_movement, max_movement, 0.1); | |
let offsetY_down = getRandomValue(p5, x_down, y_down, z, "shiftY", -max_movement, max_movement, 0.1); | |
let shifted_x_down = x_down + offsetX_down; | |
let shifted_y_down = y_down + offsetY_down; | |
let x_pos_down = p5.map(shifted_x_down, x1, x2, 0, 256); | |
let y_pos_down = p5.map(shifted_y_down, y1, y2, 0, 256); | |
/* now draw all elements from back to front */ | |
if (zoom < 2) { | |
p5.strokeWeight(cur_line_width); | |
p5.stroke(150, 0, 0); | |
p5.line(x_pos, y_pos, x_pos_left, y_pos_left); | |
p5.stroke(0, 150, 0); | |
p5.line(x_pos, y_pos, x_pos_down, y_pos_down); | |
} | |
if (zoom >= 2) { | |
p5.fill(0, 0, 255); | |
p5.noStroke(); | |
drawPetals(p5, x1, x2, y1, y2, shifted_x, shifted_y, ball_radius, 2*line_width, z); | |
} | |
p5.stroke(0, 0, 150); | |
p5.fill(0, 0, 128); | |
p5.noStroke(); | |
p5.ellipse(x_pos, y_pos, cur_ball_radius); | |
if(zoom >= 3) { | |
// now if we are super zoomed, draw lines in the stamen | |
var drawLines = false; | |
if (zoom >= 5) drawLines = true; | |
p5.fill(0, 0, 255); | |
p5.stroke(0, 0, 128); | |
drawStamens(p5, x1, x2, y1, y2, shifted_x, shifted_y, ball_radius/3, line_width/2, drawLines, z); | |
} | |
} | |
} | |
// debug - show border | |
// p5.noFill(); | |
// p5.stroke(0, 200, 200) | |
// p5.strokeWeight(1); | |
// p5.rect(0, 0, 255, 255); | |
// p5.text("corner: (" + x1 + "," + y1 + ")", 10, 20); | |
// let sizex = x2 - x1; | |
// p5.text("width: " + sizex, 10, 40); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const max_thickness = 64; | |
const ball_radius = 32; | |
const line_width = 8; | |
const grid_size = 64; | |
const max_movement = 16; | |
/* the random number seed for the tour */ | |
var tourSeed = 301; | |
/* triplets of locations: zoom, x, y */ | |
var tourPath = [ | |
[1, 356.500000000000, 665.750000000000], | |
[3, 353.250000000000, 668.187500000000], | |
[4, 322.562500000000, 645.093750000000], | |
[5, 322.562500000000, 645.109375000000], | |
[7, 317.984375000000, 643.636718750000], | |
[3, 317.984375000000, 643.636718750000] | |
] | |
/* this function takes a coordinate and aligns to a grid of size gsize */ | |
function snap_to_grid(num, gsize) { | |
return (num - (num % gsize)); | |
} | |
/* this function returns a point offset by noise at that location */ | |
function getOffsetPoint(p5, x, y, z, noiseScale) { | |
let noiseX = p5.noise(x * noiseScale, | |
y * noiseScale, z); | |
let noiseY = p5.noise(x * noiseScale, | |
y * noiseScale, z+50); | |
let offsetX = p5.map(noiseX, 0, 1, -max_movement, max_movement); | |
let offsetY = p5.map(noiseY, 0, 1, -max_movement, max_movement); | |
return [x+offsetX, y+offsetY] | |
} | |
/* | |
* 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) { | |
/* max_shift is the amount of overlap a tile can spill over into its neighbors */ | |
let max_shift = max_thickness + max_movement; | |
/* this rectangle defines the region that will be drawn and includes a margin */ | |
let min_x = snap_to_grid(x1 - max_shift, grid_size); | |
let max_x = snap_to_grid(x2 + max_shift + grid_size, grid_size); | |
let min_y = snap_to_grid(y1 - max_shift, grid_size); | |
let max_y = snap_to_grid(y2 + max_shift + grid_size, grid_size); | |
// debug version: draw one | |
// let half_x = (x1 + x2) / 2; | |
// let half_y = (y1 + y2) / 2; | |
// min_x = snap_to_grid(half_x, grid_size); | |
// max_x = snap_to_grid(half_x + grid_size, grid_size); | |
// min_y = snap_to_grid(half_y, grid_size); | |
// max_y = snap_to_grid(half_y + grid_size, grid_size); | |
let c_p00 = p5.map(0, x1, x2, 0, 256); | |
let c_plwidth = p5.map(line_width, x1, x2, 0, 256); | |
let c_pball = p5.map(ball_radius, x1, x2, 0, 256); | |
let cur_line_width = c_plwidth - c_p00; | |
let cur_ball_radius = c_pball - c_p00; | |
p5.background(255); | |
p5.fill(0, 0, 128); | |
for(let x=min_x; x<max_x; x+=grid_size) { | |
for(let y=min_y; y<max_y; y+=grid_size) { | |
/* first compute all three points with offsets */ | |
let shift_point = getOffsetPoint(p5, x, y, z, 0.1); | |
let x_pos = p5.map(shift_point[0], x1, x2, 0, 256); | |
let y_pos = p5.map(shift_point[1], y1, y2, 0, 256); | |
let shift_point_left = getOffsetPoint(p5, x+grid_size, y, z, 0.1); | |
let x_pos_left = p5.map(shift_point_left[0], x1, x2, 0, 256); | |
let y_pos_left = p5.map(shift_point_left[1], y1, y2, 0, 256); | |
let shift_point_down = getOffsetPoint(p5, x, y+grid_size, z, 0.1); | |
let x_pos_down = p5.map(shift_point_down[0], x1, x2, 0, 256); | |
let y_pos_down = p5.map(shift_point_down[1], y1, y2, 0, 256); | |
/* now draw all elements from back to front */ | |
p5.strokeWeight(cur_line_width); | |
p5.stroke(150, 0, 0); | |
p5.line(x_pos, y_pos, x_pos_left, y_pos_left); | |
p5.stroke(0, 150, 0); | |
p5.line(x_pos, y_pos, x_pos_down, y_pos_down); | |
p5.stroke(0, 0, 150); | |
p5.noStroke(); | |
p5.ellipse(x_pos, y_pos, cur_ball_radius); | |
} | |
} | |
// debug - show border | |
// p5.noFill(); | |
// p5.stroke(0, 200, 200) | |
// p5.strokeWeight(1); | |
// p5.rect(0, 0, 255, 255); | |
// p5.text("corner: (" + x1 + "," + y1 + ")", 10, 20); | |
// let sizex = x2 - x1; | |
// p5.text("width: " + sizex, 10, 40); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const max_thickness = 64; | |
const max_movement = 16; | |
const ball_radius = 32; | |
const line_width = 8; | |
const grid_size = 64; | |
/* the random number seed for the tour */ | |
var tourSeed = 301; | |
/* triplets of locations: zoom, x, y */ | |
var tourPath = [ | |
[1, 356.500000000000, 665.750000000000], | |
[3, 353.250000000000, 668.187500000000], | |
[4, 322.562500000000, 645.093750000000], | |
[5, 322.562500000000, 645.109375000000], | |
[7, 317.984375000000, 643.636718750000], | |
[3, 317.984375000000, 643.636718750000] | |
] | |
/* this function takes a coordinate and aligns to a grid of size gsize */ | |
function snap_to_grid(num, gsize) { | |
return (num - (num % gsize)); | |
} | |
/* | |
* 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) { | |
/* max_shift is the amount of overlap a tile can spill over into its neighbors */ | |
let max_shift = max_thickness + max_movement; | |
/* this rectangle defines the region that will be drawn and includes a margin */ | |
let min_x = snap_to_grid(x1 - max_shift, grid_size); | |
let max_x = snap_to_grid(x2 + max_shift + grid_size, grid_size); | |
let min_y = snap_to_grid(y1 - max_shift, grid_size); | |
let max_y = snap_to_grid(y2 + max_shift + grid_size, grid_size); | |
// debug version: draw one | |
// let half_x = (x1 + x2) / 2; | |
// let half_y = (y1 + y2) / 2; | |
// min_x = snap_to_grid(half_x, grid_size); | |
// max_x = snap_to_grid(half_x + grid_size, grid_size); | |
// min_y = snap_to_grid(half_y, grid_size); | |
// max_y = snap_to_grid(half_y + grid_size, grid_size); | |
let c_p00 = p5.map(0, x1, x2, 0, 256); | |
let c_plwidth = p5.map(line_width, x1, x2, 0, 256); | |
let c_pball = p5.map(ball_radius, x1, x2, 0, 256); | |
let cur_line_width = c_plwidth - c_p00; | |
let cur_ball_radius = c_pball - c_p00; | |
p5.background(255); | |
p5.fill(0, 0, 128); | |
for(let x=min_x; x<max_x; x+=grid_size) { | |
for(let y=min_y; y<max_y; y+=grid_size) { | |
// First compute shifted point in grid | |
let offsetX = getRandomValue(p5, x, y, z, "shiftX", -max_movement, max_movement, 0.1); | |
let offsetY = getRandomValue(p5, x, y, z, "shiftY", -max_movement, max_movement, 0.1); | |
let shifted_x = x + offsetX; | |
let shifted_y = y + offsetY; | |
let x_pos = p5.map(shifted_x, x1, x2, 0, 256); | |
let y_pos = p5.map(shifted_y, y1, y2, 0, 256); | |
// now compute shifted point one step to the left | |
let x_left = x + grid_size; | |
let y_left = y; | |
let offsetX_left = getRandomValue(p5, x_left, y_left, z, "shiftX", -max_movement, max_movement, 0.1); | |
let offsetY_left = getRandomValue(p5, x_left, y_left, z, "shiftY", -max_movement, max_movement, 0.1); | |
let shifted_x_left = x_left + offsetX_left; | |
let shifted_y_left = y_left + offsetY_left; | |
let x_pos_left = p5.map(shifted_x_left, x1, x2, 0, 256); | |
let y_pos_left = p5.map(shifted_y_left, y1, y2, 0, 256); | |
// lastly compute shifted point one step down | |
let x_down = x; | |
let y_down = y + grid_size; | |
let offsetX_down = getRandomValue(p5, x_down, y_down, z, "shiftX", -max_movement, max_movement, 0.1); | |
let offsetY_down = getRandomValue(p5, x_down, y_down, z, "shiftY", -max_movement, max_movement, 0.1); | |
let shifted_x_down = x_down + offsetX_down; | |
let shifted_y_down = y_down + offsetY_down; | |
let x_pos_down = p5.map(shifted_x_down, x1, x2, 0, 256); | |
let y_pos_down = p5.map(shifted_y_down, y1, y2, 0, 256); | |
/* now draw all elements from back to front */ | |
p5.strokeWeight(cur_line_width); | |
p5.stroke(150, 0, 0); | |
p5.line(x_pos, y_pos, x_pos_left, y_pos_left); | |
p5.stroke(0, 150, 0); | |
p5.line(x_pos, y_pos, x_pos_down, y_pos_down); | |
p5.stroke(0, 0, 150); | |
p5.noStroke(); | |
p5.ellipse(x_pos, y_pos, cur_ball_radius); | |
} | |
} | |
// debug - show border | |
// p5.noFill(); | |
// p5.stroke(0, 200, 200) | |
// p5.strokeWeight(1); | |
// p5.rect(0, 0, 255, 255); | |
// p5.text("corner: (" + x1 + "," + y1 + ")", 10, 20); | |
// let sizex = x2 - x1; | |
// p5.text("width: " + sizex, 10, 40); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const max_thickness = 64; | |
const max_movement = 16; | |
const ball_radius = 32; | |
const line_width = 8; | |
const grid_size = 64; | |
/* the random number seed for the tour */ | |
var tourSeed = 301; | |
/* triplets of locations: zoom, x, y */ | |
var tourPath = [ | |
[1, 356.500000000000, 665.750000000000], | |
[3, 353.250000000000, 668.187500000000], | |
[4, 322.562500000000, 645.093750000000], | |
[5, 322.562500000000, 645.109375000000], | |
[7, 317.984375000000, 643.636718750000], | |
[3, 317.984375000000, 643.636718750000] | |
] | |
/* this function takes a coordinate and aligns to a grid of size gsize */ | |
function snap_to_grid(num, gsize) { | |
return (num - (num % gsize)); | |
} | |
/* this function returns a point offset by noise at that location */ | |
function getOffsetPoint(p5, x, y, z, noiseScale) { | |
let offsetX = getRandomValue(p5, x, y, z, "offsetX", -max_movement, max_movement, noiseScale); | |
let offsetY = getRandomValue(p5, x, y, z, "offsetY", -max_movement, max_movement, noiseScale); | |
return [x+offsetX, y+offsetY] | |
} | |
function drawPetals(p5, x1, x2, y1, y2, pos_x, pos_y, rad1, rad2) { | |
const sqrt2 = 1.4142/2; | |
let offsets = [ | |
[sqrt2, sqrt2], | |
[-sqrt2, sqrt2], | |
[-sqrt2, -sqrt2], | |
[sqrt2, -sqrt2] | |
] | |
let pixel_posx1 = p5.map(pos_x, x1, x2, 0, 256); | |
let pixel_posx2 = p5.map(pos_x+rad2, x1, x2, 0, 256); | |
let pixel_radius = pixel_posx2 - pixel_posx1; | |
for(let i=0; i<offsets.length; i++) { | |
let offset = offsets[i]; | |
let pixel_x = p5.map(pos_x+0.5*rad1*offset[0], x1, x2, 0, 256); | |
let pixel_y = p5.map(pos_y+0.5*rad1*offset[1], y1, y2, 0, 256); | |
p5.ellipse(pixel_x, pixel_y, pixel_radius); | |
} | |
} | |
function drawStamens(p5, x1, x2, y1, y2, pos_x, pos_y, rad1, rad2, drawLines) { | |
const offsets = [ | |
[1, 1], | |
[1, -1], | |
[-1, 1], | |
[-1, -1] | |
] | |
let pixel_posx1 = p5.map(pos_x, x1, x2, 0, 256); | |
let pixel_posx2 = p5.map(pos_x+rad2, x1, x2, 0, 256); | |
let pixel_radius = pixel_posx2 - pixel_posx1; | |
for(var i=0; i<offsets.length; i++) { | |
let offset = offsets[i]; | |
let pixel_x = p5.map(pos_x+0.5*rad1*offset[0], x1, x2, 0, 256); | |
let pixel_y = p5.map(pos_y+0.5*rad1*offset[1], y1, y2, 0, 256); | |
p5.strokeWeight(0); | |
p5.ellipse(pixel_x, pixel_y, pixel_radius); | |
if(drawLines) { | |
p5.strokeWeight(pixel_radius / 20); | |
p5.line(pixel_x-pixel_radius, pixel_y, pixel_x+pixel_radius, pixel_y); | |
p5.line(pixel_x, pixel_y-pixel_radius, pixel_x, pixel_y+pixel_radius); | |
p5.strokeWeight(0); | |
p5.ellipse(pixel_x, pixel_y, pixel_radius / 12); | |
} | |
} | |
} | |
/* | |
* 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) { | |
/* max_shift is the amount of overlap a tile can spill over into its neighbors */ | |
let max_shift = max_thickness + max_movement; | |
/* this rectangle defines the region that will be drawn and includes a margin */ | |
let min_x = snap_to_grid(x1 - max_shift, grid_size); | |
let max_x = snap_to_grid(x2 + max_shift + grid_size, grid_size); | |
let min_y = snap_to_grid(y1 - max_shift, grid_size); | |
let max_y = snap_to_grid(y2 + max_shift + grid_size, grid_size); | |
// debug version: draw one | |
// let half_x = (x1 + x2) / 2; | |
// let half_y = (y1 + y2) / 2; | |
// min_x = snap_to_grid(half_x, grid_size); | |
// max_x = snap_to_grid(half_x + grid_size, grid_size); | |
// min_y = snap_to_grid(half_y, grid_size); | |
// max_y = snap_to_grid(half_y + grid_size, grid_size); | |
let c_p00 = p5.map(0, x1, x2, 0, 256); | |
let c_plwidth = p5.map(line_width, x1, x2, 0, 256); | |
let c_pball = p5.map(ball_radius, x1, x2, 0, 256); | |
let cur_line_width = c_plwidth - c_p00; | |
let cur_ball_radius = c_pball - c_p00; | |
p5.background(255); | |
for(let x=min_x; x<max_x; x+=grid_size) { | |
for(let y=min_y; y<max_y; y+=grid_size) { | |
// First compute shifted point in grid | |
let offsetX = getRandomValue(p5, x, y, z, "shiftX", -max_movement, max_movement, 0.1); | |
let offsetY = getRandomValue(p5, x, y, z, "shiftY", -max_movement, max_movement, 0.1); | |
let shifted_x = x + offsetX; | |
let shifted_y = y + offsetY; | |
let x_pos = p5.map(shifted_x, x1, x2, 0, 256); | |
let y_pos = p5.map(shifted_y, y1, y2, 0, 256); | |
// now compute shifted point one step to the left | |
let x_left = x + grid_size; | |
let y_left = y; | |
let offsetX_left = getRandomValue(p5, x_left, y_left, z, "shiftX", -max_movement, max_movement, 0.1); | |
let offsetY_left = getRandomValue(p5, x_left, y_left, z, "shiftY", -max_movement, max_movement, 0.1); | |
let shifted_x_left = x_left + offsetX_left; | |
let shifted_y_left = y_left + offsetY_left; | |
let x_pos_left = p5.map(shifted_x_left, x1, x2, 0, 256); | |
let y_pos_left = p5.map(shifted_y_left, y1, y2, 0, 256); | |
// lastly compute shifted point one step down | |
let x_down = x; | |
let y_down = y + grid_size; | |
let offsetX_down = getRandomValue(p5, x_down, y_down, z, "shiftX", -max_movement, max_movement, 0.1); | |
let offsetY_down = getRandomValue(p5, x_down, y_down, z, "shiftY", -max_movement, max_movement, 0.1); | |
let shifted_x_down = x_down + offsetX_down; | |
let shifted_y_down = y_down + offsetY_down; | |
let x_pos_down = p5.map(shifted_x_down, x1, x2, 0, 256); | |
let y_pos_down = p5.map(shifted_y_down, y1, y2, 0, 256); | |
/* now draw all elements from back to front */ | |
if (zoom < 2) { | |
p5.strokeWeight(cur_line_width); | |
p5.stroke(150, 0, 0); | |
p5.line(x_pos, y_pos, x_pos_left, y_pos_left); | |
p5.stroke(0, 150, 0); | |
p5.line(x_pos, y_pos, x_pos_down, y_pos_down); | |
} | |
if (zoom >= 2) { | |
p5.fill(0, 0, 255); | |
p5.noStroke(); | |
drawPetals(p5, x1, x2, y1, y2, shifted_x, shifted_y, ball_radius, 2*line_width); | |
} | |
p5.stroke(0, 0, 150); | |
p5.fill(0, 0, 128); | |
p5.noStroke(); | |
p5.ellipse(x_pos, y_pos, cur_ball_radius); | |
if(zoom >= 3) { | |
// now if we are super zoomed, draw lines in the stamen | |
var drawLines = false; | |
if (zoom >= 5) drawLines = true; | |
p5.fill(0, 0, 255); | |
p5.stroke(0, 0, 128); | |
drawStamens(p5, x1, x2, y1, y2, shifted_x, shifted_y, ball_radius/3, line_width/2, drawLines); | |
} | |
} | |
} | |
// debug - show border | |
// p5.noFill(); | |
// p5.stroke(0, 200, 200) | |
// p5.strokeWeight(1); | |
// p5.rect(0, 0, 255, 255); | |
// p5.text("corner: (" + x1 + "," + y1 + ")", 10, 20); | |
// let sizex = x2 - x1; | |
// p5.text("width: " + sizex, 10, 40); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const max_thickness = 64; | |
const max_movement = 16; | |
const ball_radius = 32; | |
const line_width = 8; | |
const grid_size = 64; | |
let do_animation = true; | |
/* the random number seed for the tour */ | |
var tourSeed = 301; | |
/* triplets of locations: zoom, x, y */ | |
var tourPath = [ | |
[1, 356.500000000000, 665.750000000000], | |
[3, 353.250000000000, 668.187500000000], | |
[4, 322.562500000000, 645.093750000000], | |
[5, 322.562500000000, 645.109375000000], | |
[7, 317.984375000000, 643.636718750000], | |
[3, 317.984375000000, 643.636718750000] | |
] | |
/* this function takes a coordinate and aligns to a grid of size gsize */ | |
function snap_to_grid(num, gsize) { | |
return (num - (num % gsize)); | |
} | |
/* this function returns a point offset by noise at that location */ | |
function getOffsetPoint(p5, x, y, z, noiseScale) { | |
let offsetX = getRandomValue(p5, x, y, z, "offsetX", -max_movement, max_movement, noiseScale); | |
let offsetY = getRandomValue(p5, x, y, z, "offsetY", -max_movement, max_movement, noiseScale); | |
return [x+offsetX, y+offsetY] | |
} | |
function drawPetals(p5, x1, x2, y1, y2, pos_x, pos_y, rad1, rad2) { | |
const sqrt2 = 1.4142/2; | |
let offsets = [ | |
[sqrt2, sqrt2], | |
[-sqrt2, sqrt2], | |
[-sqrt2, -sqrt2], | |
[sqrt2, -sqrt2] | |
] | |
let pixel_posx1 = p5.map(pos_x, x1, x2, 0, 256); | |
let pixel_posx2 = p5.map(pos_x+rad2, x1, x2, 0, 256); | |
let pixel_radius = pixel_posx2 - pixel_posx1; | |
for(let i=0; i<offsets.length; i++) { | |
let offset = offsets[i]; | |
let pixel_x = p5.map(pos_x+0.5*rad1*offset[0], x1, x2, 0, 256); | |
let pixel_y = p5.map(pos_y+0.5*rad1*offset[1], y1, y2, 0, 256); | |
p5.ellipse(pixel_x, pixel_y, pixel_radius); | |
} | |
} | |
function drawStamens(p5, x1, x2, y1, y2, pos_x, pos_y, rad1, rad2, drawLines, z) { | |
const offsets = [ | |
[1, 1], | |
[1, -1], | |
[-1, 1], | |
[-1, -1] | |
] | |
let pixel_posx1 = p5.map(pos_x, x1, x2, 0, 256); | |
let pixel_posx2 = p5.map(pos_x+rad2, x1, x2, 0, 256); | |
let pixel_radius = pixel_posx2 - pixel_posx1; | |
let z_fraction = z % 1.0; | |
let num_stamens = p5.map(z_fraction, 0, 1, 0, offsets.length) | |
for(var i=0; i<num_stamens; i++) { | |
let offset = offsets[i]; | |
let pixel_x = p5.map(pos_x+0.5*rad1*offset[0], x1, x2, 0, 256); | |
let pixel_y = p5.map(pos_y+0.5*rad1*offset[1], y1, y2, 0, 256); | |
p5.strokeWeight(0); | |
p5.ellipse(pixel_x, pixel_y, pixel_radius); | |
if(drawLines) { | |
p5.strokeWeight(pixel_radius / 20); | |
p5.line(pixel_x-pixel_radius, pixel_y, pixel_x+pixel_radius, pixel_y); | |
p5.line(pixel_x, pixel_y-pixel_radius, pixel_x, pixel_y+pixel_radius); | |
p5.strokeWeight(0); | |
p5.ellipse(pixel_x, pixel_y, pixel_radius / 12); | |
} | |
} | |
} | |
/* | |
* 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) { | |
/* max_shift is the amount of overlap a tile can spill over into its neighbors */ | |
let max_shift = max_thickness + max_movement; | |
/* For animation: updated z based on global frame count */ | |
let dz = p5.globalFrameCount / 100.0; | |
z = z + dz; | |
/* this rectangle defines the region that will be drawn and includes a margin */ | |
let min_x = snap_to_grid(x1 - max_shift, grid_size); | |
let max_x = snap_to_grid(x2 + max_shift + grid_size, grid_size); | |
let min_y = snap_to_grid(y1 - max_shift, grid_size); | |
let max_y = snap_to_grid(y2 + max_shift + grid_size, grid_size); | |
// debug version: draw one | |
// let half_x = (x1 + x2) / 2; | |
// let half_y = (y1 + y2) / 2; | |
// min_x = snap_to_grid(half_x, grid_size); | |
// max_x = snap_to_grid(half_x + grid_size, grid_size); | |
// min_y = snap_to_grid(half_y, grid_size); | |
// max_y = snap_to_grid(half_y + grid_size, grid_size); | |
let c_p00 = p5.map(0, x1, x2, 0, 256); | |
let c_plwidth = p5.map(line_width, x1, x2, 0, 256); | |
let c_pball = p5.map(ball_radius, x1, x2, 0, 256); | |
let cur_line_width = c_plwidth - c_p00; | |
let cur_ball_radius = c_pball - c_p00; | |
p5.background(255); | |
for(let x=min_x; x<max_x; x+=grid_size) { | |
for(let y=min_y; y<max_y; y+=grid_size) { | |
// First compute shifted point in grid | |
let offsetX = getRandomValue(p5, x, y, z, "shiftX", -max_movement, max_movement, 0.1); | |
let offsetY = getRandomValue(p5, x, y, z, "shiftY", -max_movement, max_movement, 0.1); | |
let shifted_x = x + offsetX; | |
let shifted_y = y + offsetY; | |
let x_pos = p5.map(shifted_x, x1, x2, 0, 256); | |
let y_pos = p5.map(shifted_y, y1, y2, 0, 256); | |
// now compute shifted point one step to the left | |
let x_left = x + grid_size; | |
let y_left = y; | |
let offsetX_left = getRandomValue(p5, x_left, y_left, z, "shiftX", -max_movement, max_movement, 0.1); | |
let offsetY_left = getRandomValue(p5, x_left, y_left, z, "shiftY", -max_movement, max_movement, 0.1); | |
let shifted_x_left = x_left + offsetX_left; | |
let shifted_y_left = y_left + offsetY_left; | |
let x_pos_left = p5.map(shifted_x_left, x1, x2, 0, 256); | |
let y_pos_left = p5.map(shifted_y_left, y1, y2, 0, 256); | |
// lastly compute shifted point one step down | |
let x_down = x; | |
let y_down = y + grid_size; | |
let offsetX_down = getRandomValue(p5, x_down, y_down, z, "shiftX", -max_movement, max_movement, 0.1); | |
let offsetY_down = getRandomValue(p5, x_down, y_down, z, "shiftY", -max_movement, max_movement, 0.1); | |
let shifted_x_down = x_down + offsetX_down; | |
let shifted_y_down = y_down + offsetY_down; | |
let x_pos_down = p5.map(shifted_x_down, x1, x2, 0, 256); | |
let y_pos_down = p5.map(shifted_y_down, y1, y2, 0, 256); | |
/* now draw all elements from back to front */ | |
if (zoom < 2) { | |
p5.strokeWeight(cur_line_width); | |
p5.stroke(150, 0, 0); | |
p5.line(x_pos, y_pos, x_pos_left, y_pos_left); | |
p5.stroke(0, 150, 0); | |
p5.line(x_pos, y_pos, x_pos_down, y_pos_down); | |
} | |
if (zoom >= 2) { | |
p5.fill(0, 0, 255); | |
p5.noStroke(); | |
drawPetals(p5, x1, x2, y1, y2, shifted_x, shifted_y, ball_radius, 2*line_width); | |
} | |
p5.stroke(0, 0, 150); | |
p5.fill(0, 0, 128); | |
p5.noStroke(); | |
p5.ellipse(x_pos, y_pos, cur_ball_radius); | |
if(zoom >= 3) { | |
// now if we are super zoomed, draw lines in the stamen | |
var drawLines = false; | |
if (zoom >= 5) drawLines = true; | |
p5.fill(0, 0, 255); | |
p5.stroke(0, 0, 128); | |
drawStamens(p5, x1, x2, y1, y2, shifted_x, shifted_y, ball_radius/3, line_width/2, drawLines, z); | |
} | |
} | |
} | |
// debug - show border | |
// p5.noFill(); | |
// p5.stroke(0, 200, 200) | |
// p5.strokeWeight(1); | |
// p5.rect(0, 0, 255, 255); | |
// p5.text("corner: (" + x1 + "," + y1 + ")", 10, 20); | |
// let sizex = x2 - x1; | |
// p5.text("width: " + sizex, 10, 40); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* This is the a class example of the abstract design framework. | |
* | |
* 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. | |
*/ | |
/* the random number seed for the tour */ | |
var tourSeed = 301; | |
/* triplets of locations: zoom, x, y */ | |
var tourPath = [ | |
[2, 512, 512], | |
[2, 420, 400], | |
[4, 420, 400] | |
] | |
// This version draws two rectangles and two ellipses. | |
// The rectangles are 960x720 and centered at 512,512. | |
function drawGrid(p5, x1, x2, y1, y2, z, zoom) { | |
// temporary variables used for object placement | |
let cx=0, cy=0, cx2=0, cy2=0; | |
p5.background(255); | |
p5.rectMode(p5.CORNERS); | |
// The first red rectangle fills the entire space | |
cx = p5.map(512-960/2, x1, x2, 0, 256); | |
cy = p5.map(512-720/2, y1, y2, 0, 256); | |
cx2 = p5.map(512+960/2, x1, x2, 0, 256); | |
cy2 = p5.map(512+720/2, y1, y2, 0, 256); | |
p5.fill(255, 0, 0); | |
p5.rect(cx, cy, cx2, cy2); | |
// The second black rectangle is inset to form a frame inset by 20 units | |
cx = p5.map(512-940/2, x1, x2, 0, 256); | |
cy = p5.map(512-700/2, y1, y2, 0, 256); | |
cx2 = p5.map(512+940/2, x1, x2, 0, 256); | |
cy2 = p5.map(512+700/2, y1, y2, 0, 256); | |
p5.fill(0); | |
p5.rect(cx, cy, cx2, cy2); | |
// Two ellipses with a radius of 50 units are then added. | |
cx = p5.map(512, x1, x2, 0, 256); | |
cy = p5.map(512, y1, y2, 0, 256); | |
cx2 = p5.map(512+50, x1, x2, 0, 256); | |
p5.fill(0, 0, 255); | |
p5.ellipse(cx, cy, (cx2-cx)); | |
// The second green ellipse is above and to the left of the first one. | |
cx = p5.map(412, x1, x2, 0, 256); | |
cy = p5.map(412, y1, y2, 0, 256); | |
cx2 = p5.map(412+50, x1, x2, 0, 256); | |
p5.fill(0, 255, 0); | |
p5.ellipse(cx, cy, (cx2-cx)); | |
// debug - show border | |
// p5.noFill(); | |
// p5.stroke(255, 0, 0) | |
// p5.rect(0, 0, 255, 255); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<title>framed version</title> | |
<div class="column"> | |
<h3>960x720 preview</h3> | |
<div class="index"> | |
<iframe sandbox="allow-popups allow-scripts allow-forms allow-same-origin" src="index.html" marginwidth="0" marginheight="0" style="width:960px;height:720px;" scrolling="no"></iframe> | |
</div> | |
</div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>17.2.MDDN342 PS4</title> | |
<meta charset="utf-8" /> | |
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" /> | |
<style> | |
body { | |
padding: 0; | |
margin: 0; | |
} | |
html, body, #map { | |
height: 100%; | |
width: 100%; | |
background-color: white; | |
} | |
.leaflet-control-attribution { | |
font-size: 24px !important; | |
} | |
</style> | |
</head> | |
<body> | |
<div id="map"></div> | |
<script src="http://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.2/p5.js"></script> | |
<script src="http://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.2/addons/p5.dom.js"></script> | |
<script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script> | |
<script src="leaflet-hash.js"></script> | |
<script src="drawgrid.js"></script> | |
<script src="map.js"></script> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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); | |
String.prototype.hashCode = function() { | |
var hash = 0, i, chr; | |
if (this.length === 0) return hash; | |
for (i = 0; i < this.length; i++) { | |
chr = this.charCodeAt(i); | |
hash = ((hash << 5) - hash) + chr; | |
hash |= 0; // Convert to 32bit integer | |
} | |
return hash; | |
}; | |
function getRandomValue(p5, x, y, z, name, min, max, scale) { | |
let hashNumber = name.hashCode(); | |
let noiseVal = p5.noise(x * scale, y * scale, (z + hashNumber)); | |
return p5.map(noiseVal, 0, 1, min, max); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var myCRS = L.extend({}, L.CRS.Simple, { | |
transformation: new L.Transformation(1, 0, | |
// -1, // works like expected | |
1, // image travels while zooming | |
0) | |
}); | |
if (typeof initialZoomLevel === 'undefined') { | |
var initialZoomLevel = 0; | |
} | |
if (typeof maxZoomLevel === 'undefined') { | |
var maxZoomLevel = 16; | |
} | |
var worldMap = new L.Map('map', { | |
continuousWorld:true, | |
minZoom: 0, | |
maxZoom: maxZoomLevel, | |
crs: myCRS, | |
attributionControl: false, | |
center: [512, 512], | |
zoom: initialZoomLevel}); | |
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) | |
// sloppy way to set tile size | |
var g_tileSize = null; | |
var s = function( p ) { | |
p.setup = function() { | |
canvas = p.createCanvas(g_tileSize.x, g_tileSize.y); | |
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(); | |
g_tileSize = size; | |
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) | |
var tile = myp5.canvas; | |
tile.rendering = true; | |
if(typeof do_animation !== 'undefined' && do_animation) { | |
(function doAnimate(){ | |
if(tile.rendering){ | |
myp5.globalFrameCount = worldMap.globalFrameCount; | |
myp5.redraw() | |
requestAnimationFrame(doAnimate) | |
} | |
})() | |
} | |
myp5._start(); | |
tile.p5 = myp5 | |
L.DomUtil.addClass(tile, 'leaflet-tile'); | |
return tile; | |
} | |
tiles.on('tileunload', function(e){ | |
e.tile.rendering = false; | |
}) | |
// tiles.on('tileload', function(e){ | |
// /** @type {HTMLCanvasElement} */ | |
// var tile = e.tile | |
// /** @type {p5} */ | |
// var p5 = tile.p5; | |
// if(p5){ | |
// console.log(e) | |
// p5.redraw() | |
// } | |
// }) | |
// setInterval(function(){ | |
// if(!tiles.isLoading()){ | |
// tiles.redraw() | |
// } | |
// }, 1000) | |
tiles.addTo(worldMap) | |
var curLinkIndex = 0; | |
linkHome = "#0/0/512/512/0" | |
if (typeof tourPath === 'undefined') { | |
var tourPath = [ | |
[2, 512, 512], | |
[4, 512, 512], | |
[6, 512, 512], | |
[8, 512, 512] | |
] | |
} | |
tourPath.unshift([initialZoomLevel, 512, 512]); | |
if (typeof tourSeed === 'undefined') { | |
var tourSeed = 0; | |
} | |
function clickHome() { | |
worldMap.flyTo([tourPath[0][1], tourPath[0][2]], tourPath[0][0]); | |
} | |
worldMap.globalFrameCount = 0; | |
if(typeof do_animation !== 'undefined' && do_animation) { | |
(function doCounter() { | |
worldMap.globalFrameCount = worldMap.globalFrameCount + 1; | |
requestAnimationFrame(doCounter); | |
})() | |
} | |
function clickDemo() { | |
if(worldMap._p5_seed != tourSeed) { | |
var center = worldMap.getCenter(); | |
var zoom = worldMap.getZoom(); | |
worldMap._p5_seed = tourSeed; | |
tiles.redraw(); | |
// worldMap.setView(center, zoom, {reset: true}); | |
curLinkIndex = 0; | |
} | |
else { | |
curLinkIndex = (curLinkIndex + 1) % tourPath.length | |
} | |
var curDest = tourPath[curLinkIndex] | |
worldMap.flyTo([curDest[1], curDest[2]], curDest[0]); | |
} | |
function clickReset() { | |
window.location.reload(); | |
} | |
attrib = new L.Control.Attribution | |
attrib.setPrefix("") | |
attrStr = '<a href="#" onclick="javascript:clickHome();">home</a> | ' | |
attrStr += '<a href="#" onclick="javascript:clickReset();">reset</a> | ' | |
attrStr += '<a href="#" onclick="javascript:clickDemo();">tour</a>' | |
attrib.addAttribution(attrStr) | |
worldMap.addControl(attrib) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<head> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.2/p5.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.2/addons/p5.dom.js"></script> | |
<script language="javascript" type="text/javascript" src="owl.js"></script> | |
<style> body {padding: 0; margin: 0;} </style> | |
</head> | |
<body style="background-color:white"> | |
</body> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function setup () { | |
createCanvas(960, 500); | |
} | |
function keyTyped() { | |
if (key == '!') { | |
saveBlocksImages(); | |
} | |
else if (key == '@') { | |
saveBlocksImages(true); | |
} | |
} | |
function draw() { | |
background(204); | |
owl(110, 110); | |
owl(180, 110); | |
owl(400, 110); | |
} | |
function owl(x, y) { | |
push(); | |
translate(x, y); | |
stroke(0); | |
strokeWeight(70); | |
line(0, -35, 0, -65); // Body | |
noStroke(); | |
fill(255); | |
ellipse(-17.5, -65, 35, 35); // Left eye dome | |
ellipse(17.5, -65, 35, 35); // Right eye dome | |
arc(0, -65, 70, 70, 0, PI); // Chin | |
fill(0); | |
ellipse(-14, -65, 8, 8); // Left eye | |
ellipse(14, -65, 8, 8); // Right eye | |
quad(0, -58, 4, -51, 0, -44, -4, -51); // Beak | |
pop(); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"commits": [ | |
{ | |
"name": "p5.globalFrameCount animation", | |
"sha": "04f772f7e3e304fcb365b3f1f542973c1178d278" | |
}, | |
{ | |
"name": "tourPath and tourSeed", | |
"sha": "c5125f80061df144941ef86007013c7b4cccd1ba" | |
}, | |
{ | |
"name": "animation example", | |
"sha": "f3f6acf5d777346fa69f1b45602d71de0a73fb94" | |
}, | |
{ | |
"name": "zoom details example", | |
"sha": "dfcfe7027c22c19021e6c6174a6bfe4719720e82" | |
}, | |
{ | |
"name": "randomness example", | |
"sha": "b28b6e3e495f118d37a2d940eb77fe2fbec67c98" | |
}, | |
{ | |
"name": "first grid example", | |
"sha": "be74e2a4628b630d67d0abe12a637df3bcfadb53" | |
}, | |
{ | |
"name": "adapting owl example", | |
"sha": "45fac8111292984d0b605792173574beb0d0b229" | |
}, | |
{ | |
"name": "first class example", | |
"sha": "445b5ba0d2554f3fa7b1a6bfdff5439f2d2a6b66" | |
}, | |
{ | |
"name": "starting code", | |
"sha": "fc7fe100e8dc0cd48f5bda374669ecb56ccb8513" | |
} | |
] | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<head> | |
<style> body {padding: 0; margin: 0;} </style> | |
</head> | |
<body style="background-color:white"> | |
<img src="sketch.png" width="960" height="720"/> | |
</body> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment