Skip to content

Instantly share code, notes, and snippets.

@EmilyAShaw
Forked from dribnet/.block
Last active October 29, 2018 21:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save EmilyAShaw/2d7f34790f4961f9a6caa1371b174e29 to your computer and use it in GitHub Desktop.
Save EmilyAShaw/2d7f34790f4961f9a6caa1371b174e29 to your computer and use it in GitHub Desktop.
PS4 MDDN 342 2018
license: mit
height: 720

PS4 MDDN 342 2018

30/10/2018

FINAL VERSION - A WEEK IN THE LIFE OF A CHRISTMAS TREE

I am happy with my change of design, I really like the idea of 'a week in the life of a christmas tree'.

The tour starts off the week before chirstmas, where the trees are growing in a christmas tree farm (hence the grid formation), in somw snow banks. An addition I added at the last minute was 'snow contours'. I decided to add this in order to give the landscape some subtle dimension.

The tour then goes to zoom in. The contours are gone but there are presents starting to apear (this is supposed to represent a family buying the tree. The next zoom in introduces some more presents, a calendar, and decorations on the tree. The lights are subtly animated. The date is the 23rd, a couple of days before chirstmas.

The next zoom is the 25th, christmas day. There are more presents. The next zoom is two days after christmas, the decorations are turned off, and the tree is begining to droop.

The last zoom is the 31st, the last day of the year. The christmas tree is dead.

If had to have a narrative for this, I would say it shows the commericalisation of christmas, and how fleeting and weird the tradition of having a tree for a couple of days is. In reflection on this asignment, I found the code quite hard at the start. But once I got into it and began to make a decent effort in order to understand it, it was very easy to use. The code for the animation was a little confusing but I ended up basing my code of the example code, so it was fine.

the only thing that I couldnt get working in the end, was importing font. I wanted to improt a pixel font for the calendar, but It didn't end up working :(

I have really enjoyed these last two years in creative coding, it has definitly been my favourite course so far. Thank you Tom and Pheobe for making it so fun, and for helping me make cool things for my portfolio :)

29/10/2018 I have made the skeleton. I also made every zoom smaller by one, as when I zoomed in to the last zoom it was too close. I also have made a calendar which apears on the 23rd, 25th, 27th, 31st.

I have made the zoom for 7 begin to make the tree look like it is 'decaying'. I have also staggard the adition of presents so that they add in the 'lead up' to christmas. I think the things I will add after this point, is the skeleton on the tree (on zoom 8), and I will also add a calendar. If I have time I will add a background other than white.

24/10/2018

I have added some presents, I will probably make more details on them in the future. Like a bow, ribons, ect. I will also want to fade them in a bit more.

//24/10/2018

I For this commit, I have added using tom's movement code (kind of) for the staments. I have added christmas lights. I changed the circles to rectangles and put more coordernates into the array to do this. I also have added snow onto the branches rto give it a more winter feel. The only problem with the animation thoughg is that it makes the window slow :(. It works fine when the window is small. but will not work or be extremely glitchy at fill screen. I guess this is not something I could easily optimise though, so it will just have to do.

The last things I need to do are to make the presents, and to make the date calendar thing. I think it would be a cool idea to still incorporate a skiier, or even the snow down to a molecular level. But I will put these on the back burner to implement until my exam is over. If I do end up doiing these it will probably be too close to thr due date to do perfectly.

//22/10/2018

I have added the detail features on the tree. You can see in the image that I have also changed the shadow around the bottom to a pixel circle instead of a real circle. Just to have some continuity

The next commit I do will be the lights and the star probably.

//20/10/2018

Created a christmas Tree grid

I had created a non zoomable christmas tree origionally, and had help from pheobe to put it into my grid. I think I am going to change my idea a little though.

I want to do a sort of 'week in the life of a christmas tree'. What will happen, is the user will zoom in on a christmas tree farm. (i.e a uniform grid of trees which look exactly the same). The further the user will zoom in, the further they will get into the christmas time line. On the second zoom in you will see more details of the tree, including a shadow (in pixel form) and some snow on the branches. The next zoom will be a star on the top of the tree (representing the person has bought the tree and is decorating it). The next will be lights which will be animated and move and blink in a random order. the next zoom will be presents. The very last zoom will be the tree, skelleton, or the process of the tree dying.

The narrative for this I suppose could be the commericalisation of christmas, and how everything is dumped after december 25th. I may if I have enough time include like a pixel calendar or something which pushes this narrative a little more.

const max_thickness = 64;
const max_movement = 1;
const ball_radius = 32;
const line_width = 8;
const grid_size = 64;
var do_animation = true;
/* the random number seed for the tour */
var tourSeed = 301;
/* triplets of locations: zoom, x, y */
var tourPath = [
[0, 356.500000000000, 665.750000000000],
[1, 356.500000000000, 665.750000000000],
[2, 498.250000000000, 582.187500000000],
[3, 501.125000000000, 622.000000000000],
[4, 509.062500000000, 517.937500000000],
[5, 509.062500000000, 517.906250000000],
[6, 506.359375000000, 518.125000000000]
];
/* 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 drawLights(p5, x1, x2, y1, y2, pos_x, pos_y, rad1, rad2, z, zoom) {
const sqrt2 = 1.4142/2;
//offsets of the chritsmas tree lights for animation
let offsets = [
[0.380, -0.5], //1 (top)
[0.32, -0.44], //2
[0.23, -0.40], //3
[0.13, -0.38], //4
[0.23, -0.31], //5
[0.35, -0.27], //6
[0.50, -0.25], //7
[0.37, -0.18], //8
[0.23, -0.14], //9
[0.05, -0.13], //10
[0.2, -0.01], //11
[0.40, 0.04],
[0.59, 0.085]
]
//code from lectures
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)/25;
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);
if(zoom > 2){
//only draws lights if zoom is big enough
p5.rect(pixel_x, pixel_y, pixel_radius, pixel_radius);
}
else{
p5.noFill();
}
}
}
function tree (p5, x, y, x1, x2, y1, y2, z, zoom){
//base of tree
if (zoom <= 5){
// bottom rec 512
let rect1x = p5.map(x, x1, x2, 0, 256);
let rect1y = p5.map(y, y1, y2, 0, 256);
let radiusRect1 = p5.map(x+10, x1, x2, 0, 256);
// seccond rect
let rect2x = p5.map(x+0.8, x1, x2, 0, 256);
let rect2y = p5.map(y-2, y1, y2, 0, 256);
let radiusRect2 = p5.map(x+10.8, x1, x2, 0, 256);
//third rect
let rect3x = p5.map(x+1.4, x1, x2, 0, 256);
let rect3y = p5.map(y-4, y1, y2, 0, 256);
let radiusRect3 = p5.map(x+11.4, x1, x2, 0, 256);
//fourth rect
let rect4x = p5.map(x+2.1, x1, x2, 0, 256);
let rect4y = p5.map(y-6, y1, y2, 0, 256);
let radiusRect4 = p5.map(x+12.1, x1, x2, 0, 256);
//fifth rect
let rect5x = p5.map(x+2.9, x1, x2, 0, 256);
let rect5y = p5.map(y-8, y1, y2, 0, 256);
let radiusRect5 = p5.map(x+12.9, x1, x2, 0, 256);
//base of tree
let basex = p5.map(x+2.9, x1, x2, 0, 256);
let basey = p5.map(y+2, y1, y2, 0, 256);
let radiusbase = p5.map(x+12.9, x1, x2, 0, 256);
//snow hole thing
let base2x = p5.map(x+1.5, x1, x2, 0, 256);
let base2y = p5.map(y+3, y1, y2, 0, 256);
let radiusbase2 = p5.map(x+11.5, x1, x2, 0, 256);
let base3x = p5.map(x+1, x1, x2, 0, 256);
let base3y = p5.map(y+3.4, y1, y2, 0, 256);
let radiusbase3 = p5.map(x+11, x1, x2, 0, 256);
p5.strokeWeight(0);
// furst rec 512
p5.fill(34, 99, 36);
p5.rect(rect1x, rect1y, (radiusRect1-rect1x),(radiusRect1-rect1x)/5);
// seccond rect
p5.fill(38, 109, 40);
p5.rect(rect2x, rect2y, (radiusRect2-rect2x)/1.20,(radiusRect2-rect2x)/5);
//third rect
p5.fill(58, 153, 61);
p5.rect(rect3x, rect3y, (radiusRect3-rect3x)/1.40,(radiusRect3-rect3x)/5);
//fourth rect
p5.fill(49, 137, 52);
p5.rect(rect4x, rect4y, (radiusRect4-rect4x)/1.80,(radiusRect4-rect4x)/5);
//fifth rect
p5.fill(63, 175, 66);
p5.rect(rect5x, rect5y, (radiusRect5-rect5x)/2.6,(radiusRect5-rect5x)/5);
//zoom 2 introduces snow base around the botto of tree
if(zoom > 0){
p5.fill(220);
p5.rect(base2x, base2y, (radiusbase2-base2x)/1.5,(radiusbase2-base2x)/5);
p5.rect(base3x, base3y, (radiusbase3-base3x)/1.3,(radiusbase3-base3x)/8);
}
//zoom 3 introduces smaller details and shades on the tree
if (zoom > 1){
p5.fill(53, 132, 55);
p5.rect(rect1x, rect1y, (radiusRect1-rect1x),(radiusRect1-rect1x)/7);
p5.fill(59, 137, 61);
p5.rect(rect2x, rect2y, (radiusRect2-rect2x)/1.20,(radiusRect2-rect2x)/7);
p5.fill(78, 173, 81);
p5.rect(rect3x, rect3y, (radiusRect3-rect3x)/1.40,(radiusRect3-rect3x)/7);
p5.fill(68, 155, 71);
p5.rect(rect4x, rect4y, (radiusRect4-rect4x)/1.80,(radiusRect4-rect4x)/7);
p5.fill(84, 188, 87);
p5.rect(rect5x, rect5y, (radiusRect5-rect5x)/2.6,(radiusRect5-rect5x)/7);
}
//zoom 4 introduces snowcaps to the top of trees
if (zoom > 2){
p5.fill(240);
p5.rect(rect1x, rect1y, (radiusRect1-rect1x),(radiusRect1-rect1x)/20);
p5.rect(rect2x, rect2y, (radiusRect2-rect2x)/1.20,(radiusRect2-rect2x)/20);
p5.rect(rect3x, rect3y, (radiusRect3-rect3x)/1.40,(radiusRect3-rect3x)/20);
p5.rect(rect4x, rect4y, (radiusRect4-rect4x)/1.80,(radiusRect4-rect4x)/20);
p5.rect(rect5x, rect5y, (radiusRect5-rect5x)/2.6,(radiusRect5-rect5x)/20);
}
p5.fill(99, 60, 34);
p5.rect(basex, basey, (radiusbase-basex)/2.6,(radiusbase-basex)/5);
//places the brown stem of the tree back ontop of the snow circle well thing. Also adds some more rendering detail
if (zoom > 1){
p5.fill(114, 75, 49);
p5.rect(basex, basey, (radiusbase-basex)/8,(radiusbase-basex)/5);
}
if ((zoom > 2) && (zoom <= 5)){
//making the star for the top of the tree
//star 1
let star1x = p5.map(x+4.7, x1, x2, 0, 256);
let star1y = p5.map(y-11, y1, y2, 0, 256);
let radiusstar1 = p5.map(x+14.7, x1, x2, 0, 256);
//green if so big
if (zoom == 5){
p5.fill(78,95,62);
}
else{
p5.fill(255, 226, 86);
}
p5.rect(star1x, star1y, (radiusstar1-star1x)/25,(radiusstar1-star1x)/4);
//star 2
let star2x = p5.map(x+4.01, x1, x2, 0, 256);
let star2y = p5.map(y-10, y1, y2, 0, 256);
let radiusstar2 = p5.map(x+14.7, x1, x2, 0, 256);
p5.rect(star2x, star2y, (radiusstar2-star2x)/6,(radiusstar2-star2x)/25);
//star 3
let star3x = p5.map(x+4.4, x1, x2, 0, 256);
let star3y = p5.map(y-10.3, y1, y2, 0, 256);
let radiusstar3 = p5.map(x+14.4, x1, x2, 0, 256);
p5.rect(star3x, star3y, (radiusstar3-star3x)/10,(radiusstar3-star3x)/10);
}
//presents gradually appear and user zooms in
if ((zoom == 2) || (zoom == 3) || (zoom == 4)){
p5.fill(163, 195, 247);
let present1x = p5.map(x+6.4, x1, x2, 0, 256);
let present1y = p5.map(y+3, y1, y2, 0, 256);
let radiuspresent1 = p5.map(x+16.4, x1, x2, 0, 256);
p5.rect(present1x, present1y, (radiuspresent1-present1x)/5,(radiuspresent1-present1x)/5);
p5.fill(245);
let present1ax = p5.map(x+7.2, x1, x2, 0, 256);
let present1ay = p5.map(y+3, y1, y2, 0, 256);
let radiuspresent1a = p5.map(x+17.2, x1, x2, 0, 256);
p5.rect(present1ax, present1ay, (radiuspresent1a-present1ax)/20,(radiuspresent1a-present1ax)/5);
let present1bx = p5.map(x+6.4, x1, x2, 0, 256);
let present1by = p5.map(y+3.8, y1, y2, 0, 256);
let radiuspresent1b = p5.map(x+16.4, x1, x2, 0, 256);
p5.rect(present1bx, present1by, (radiuspresent1b-present1bx)/5,(radiuspresent1b-present1bx)/20);
}
if ((zoom == 3) || (zoom == 4) ){
p5.fill(239, 124, 180);
let present2x = p5.map(x+2.4, x1, x2, 0, 256);
let present2y = p5.map(y+3, y1, y2, 0, 256);
let radiuspresent2 = p5.map(x+12.4, x1, x2, 0, 256);
p5.rect(present2x, present2y, (radiuspresent2-present2x)/7,(radiuspresent2-present2x)/7);
p5.fill(255);
let present2ax = p5.map(x+3, x1, x2, 0, 256);
let present2ay = p5.map(y+3, y1, y2, 0, 256);
let radiuspresent2a = p5.map(x+13, x1, x2, 0, 256);
p5.rect(present2ax, present2ay, (radiuspresent2a-present2ax)/40,(radiuspresent2a-present2ax)/7);
let present2bx = p5.map(x+2.4, x1, x2, 0, 256);
let present2by = p5.map(y+3.6, y1, y2, 0, 256);
let radiuspresent2b = p5.map(x+12.4, x1, x2, 0, 256);
p5.rect(present2bx, present2by, (radiuspresent2b-present2bx)/7,(radiuspresent2b-present2bx)/40);
}
if(zoom == 4){
p5.fill(127, 195, 244);
let present3x = p5.map(x+0, x1, x2, 0, 256);
let present3y = p5.map(y+4, y1, y2, 0, 256);
let radiuspresent3 = p5.map(x+10, x1, x2, 0, 256);
p5.rect(present3x, present3y, (radiuspresent3-present3x)/3,(radiuspresent3-present3x)/10);
p5.fill(240);
let present3ax = p5.map(x+0, x1, x2, 0, 256);
let present3ay = p5.map(y+4.4, y1, y2, 0, 256);
let radiuspresent3a = p5.map(x+10, x1, x2, 0, 256);
p5.rect(present3ax, present3ay, (radiuspresent3a-present3ax)/3,(radiuspresent3a-present3ax)/40);
let present3bx = p5.map(x+1, x1, x2, 0, 256);
let present3by = p5.map(y+4, y1, y2, 0, 256);
let radiuspresent3b = p5.map(x+11, x1, x2, 0, 256);
p5.rect(present3bx, present3by, (radiuspresent3b-present3bx)/40,(radiuspresent3b-present3bx)/10);
p5.fill(206, 178, 255);
let present4x = p5.map(x+5, x1, x2, 0, 256);
let present4y = p5.map(y+3.3, y1, y2, 0, 256);
let radiuspresent4 = p5.map(x+15, x1, x2, 0, 256);
p5.rect(present4x, present4y, (radiuspresent4-present4x)/10,(radiuspresent4-present4x)/10);
p5.fill(240);
let present4ax = p5.map(x+5.4, x1, x2, 0, 256);
let present4ay = p5.map(y+3.3, y1, y2, 0, 256);
let radiuspresent4a = p5.map(x+15.4, x1, x2, 0, 256);
p5.rect(present4ax, present4ay, (radiuspresent4a-present4ax)/45,(radiuspresent4a-present4ax)/10);
let present4bx = p5.map(x+5, x1, x2, 0, 256);
let present4by = p5.map(y+3.7, y1, y2, 0, 256);
let radiuspresent4b = p5.map(x+15, x1, x2, 0, 256);
p5.rect(present4bx, present4by, (radiuspresent4b-present4bx)/10,(radiuspresent4b-present4bx)/45);
}
p5.fill(255, 226, 86);
//introduces decaying tree details once zoom is big enough
if (zoom > 4){
p5.fill(80, 55, 39);
p5.rect(rect1x, rect1y, (radiusRect1-rect1x),(radiusRect1-rect1x)/10);
p5.rect(rect2x, rect2y, (radiusRect2-rect2x)/1.20,(radiusRect2-rect2x)/10);
p5.rect(rect3x, rect3y, (radiusRect3-rect3x)/1.40,(radiusRect3-rect3x)/10);
p5.rect(rect4x, rect4y, (radiusRect4-rect4x)/1.80,(radiusRect4-rect4x)/10);
p5.rect(rect5x, rect5y, (radiusRect5-rect5x)/2.6,(radiusRect5-rect5x)/10);
p5.fill(78,95,62);
p5.rect(rect1x, rect1y, (radiusRect1-rect1x),(radiusRect1-rect1x)/20);
p5.rect(rect2x, rect2y, (radiusRect2-rect2x)/1.20,(radiusRect2-rect2x)/20);
p5.rect(rect3x, rect3y, (radiusRect3-rect3x)/1.40,(radiusRect3-rect3x)/20);
p5.rect(rect4x, rect4y, (radiusRect4-rect4x)/1.80,(radiusRect4-rect4x)/20);
p5.rect(rect5x, rect5y, (radiusRect5-rect5x)/2.6,(radiusRect5-rect5x)/20);
p5.fill(255);
}
}
if (zoom >= 6){
p5.fill(220);
let baseDEADx = p5.map(x+1, x1, x2, 0, 256);
let baseDEADy = p5.map(y+3.4, y1, y2, 0, 256);
let radiusbaseDEAD = p5.map(x+11, x1, x2, 0, 256);
p5.rect(baseDEADx, baseDEADy, (radiusbaseDEAD-baseDEADx)/1.3,(radiusbaseDEAD-baseDEADx)/8);
//first trunk of dead tree
p5.fill(99, 60, 34);
let trunkSkelx = p5.map(x+3.6, x1, x2, 0, 256);
let trunkSkely = p5.map(y+0.7, y1, y2, 0, 256);
let radiustrunkSkel1 = p5.map(x+13.6, x1, x2, 0, 256);
p5.rect(trunkSkelx, trunkSkely, (radiustrunkSkel1-trunkSkelx)/4,(radiustrunkSkel1-trunkSkelx)/3);
//second trunk
let trunkSkel2x = p5.map(x+4.1, x1, x2, 0, 256);
let trunkSkel2y = p5.map(y-4, y1, y2, 0, 256);
let radiustrunkSkel2 = p5.map(x+14.1, x1, x2, 0, 256);
p5.rect(trunkSkel2x, trunkSkel2y, (radiustrunkSkel2-trunkSkel2x)/7,(radiustrunkSkel2-trunkSkel2x)/2);
//third trunk
let trunkSkel3x = p5.map(x+4.5, x1, x2, 0, 256);
let trunkSkel3y = p5.map(y-8, y1, y2, 0, 256);
let radiustrunkSkel3 = p5.map(x+14.1, x1, x2, 0, 256);
p5.rect(trunkSkel3x, trunkSkel3y, (radiustrunkSkel3-trunkSkel3x)/15,(radiustrunkSkel3-trunkSkel3x));
p5.fill(88, 42, 11);
//first branch
let trunkSkelbranchx = p5.map(x+0.8, x1, x2, 0, 256);
let trunkSkelbranchy = p5.map(y+1.5, y1, y2, 0, 256);
let radiustrunkSkelbranch = p5.map(x+10.8, x1, x2, 0, 256);
p5.rect(trunkSkelbranchx, trunkSkelbranchy, (radiustrunkSkelbranch-trunkSkelbranchx)/1.2,(radiustrunkSkelbranch-trunkSkelbranchx)/20);
//smaller parts
p5.fill(80, 55, 39);
let trunkSkelRightSmall1x = p5.map(x+0.2, x1, x2, 0, 256);
let trunkSkelRightSmall1y = p5.map(y+2, y1, y2, 0, 256);
let radiustrunkSkelRightSmall1 = p5.map(x+10.2, x1, x2, 0, 256);
p5.rect(trunkSkelRightSmall1x, trunkSkelRightSmall1y, (radiustrunkSkelRightSmall1-trunkSkelRightSmall1x)/18,(radiustrunkSkelRightSmall1-trunkSkelRightSmall1x)/20);
let trunkSkelRightSmall2x = p5.map(x+9.2, x1, x2, 0, 256);
let trunkSkelRightSmall2y = p5.map(y+2, y1, y2, 0, 256);
let radiustrunkSkelRightSmall2 = p5.map(x+19.2, x1, x2, 0, 256);
p5.rect(trunkSkelRightSmall2x, trunkSkelRightSmall2y, (radiustrunkSkelRightSmall2-trunkSkelRightSmall2x)/18,(radiustrunkSkelRightSmall2-trunkSkelRightSmall2x)/20);
p5.fill(88, 42, 11);
//seccond branch
let trunkSkelbranch2x = p5.map(x+1.6, x1, x2, 0, 256);
let trunkSkelbranch2y = p5.map(y-0.5, y1, y2, 0, 256);
let radiustrunkSkelbranch2 = p5.map(x+11.6, x1, x2, 0, 256);
p5.rect(trunkSkelbranch2x, trunkSkelbranch2y, (radiustrunkSkelbranch2-trunkSkelbranch2x)/1.5,(radiustrunkSkelbranch2-trunkSkelbranch2x)/20);
//smaller parts
p5.fill(80, 55, 39);
let trunkSkelRightSmall3x = p5.map(x+1, x1, x2, 0, 256);
let trunkSkelRightSmall3y = p5.map(y, y1, y2, 0, 256);
let radiustrunkSkelRightSmall3 = p5.map(x+10.2, x1, x2, 0, 256);
p5.rect(trunkSkelRightSmall3x, trunkSkelRightSmall3y, (radiustrunkSkelRightSmall3-trunkSkelRightSmall3x)/18,(radiustrunkSkelRightSmall3-trunkSkelRightSmall3x)/20);
let trunkSkelRightSmall4x = p5.map(x+8.30, x1, x2, 0, 256);
let trunkSkelRightSmall4y = p5.map(y, y1, y2, 0, 256);
let radiustrunkSkelRightSmall4 = p5.map(x+18.3, x1, x2, 0, 256);
p5.rect(trunkSkelRightSmall4x, trunkSkelRightSmall4y, (radiustrunkSkelRightSmall4-trunkSkelRightSmall4x)/18,(radiustrunkSkelRightSmall4-trunkSkelRightSmall4x)/20);
p5.fill(88, 42, 11);
//third branch
let trunkSkelbranch3x = p5.map(x+2.5, x1, x2, 0, 256);
let trunkSkelbranch3y = p5.map(y-2.5, y1, y2, 0, 256);
let radiustrunkSkelbranch3 = p5.map(x+12.5, x1, x2, 0, 256);
p5.rect(trunkSkelbranch3x, trunkSkelbranch3y, (radiustrunkSkelbranch3-trunkSkelbranch3x)/2,(radiustrunkSkelbranch3-trunkSkelbranch3x)/20);
//smaller parts
p5.fill(80, 55, 39);
let trunkSkelRightSmall5x = p5.map(x+1.9, x1, x2, 0, 256);
let trunkSkelRightSmall5y = p5.map(y-2, y1, y2, 0, 256);
let radiustrunkSkelRightSmall5 = p5.map(x+11.9, x1, x2, 0, 256);
p5.rect(trunkSkelRightSmall5x, trunkSkelRightSmall5y, (radiustrunkSkelRightSmall5-trunkSkelRightSmall5x)/18,(radiustrunkSkelRightSmall5-trunkSkelRightSmall5x)/20);
let trunkSkelRightSmall6x = p5.map(x+7.50, x1, x2, 0, 256);
let trunkSkelRightSmall6y = p5.map(y-2, y1, y2, 0, 256);
let radiustrunkSkelRightSmall6 = p5.map(x+17.5, x1, x2, 0, 256);
p5.rect(trunkSkelRightSmall6x, trunkSkelRightSmall6y, (radiustrunkSkelRightSmall6-trunkSkelRightSmall6x)/18,(radiustrunkSkelRightSmall6-trunkSkelRightSmall6x)/20);
p5.fill(88, 42, 11);
//fourth branch
let trunkSkelbranch4x = p5.map(x+3.2, x1, x2, 0, 256);
let trunkSkelbranch4y = p5.map(y-4.5, y1, y2, 0, 256);
let radiustrunkSkelbranch4 = p5.map(x+13.2, x1, x2, 0, 256);
p5.rect(trunkSkelbranch4x, trunkSkelbranch4y, (radiustrunkSkelbranch4-trunkSkelbranch4x)/2.8,(radiustrunkSkelbranch4-trunkSkelbranch4x)/20);
//smaller parts
p5.fill(80, 55, 39);
let trunkSkelRightSmall7x = p5.map(x+2.6, x1, x2, 0, 256);
let trunkSkelRightSmall7y = p5.map(y-4, y1, y2, 0, 256);
let radiustrunkSkelRightSmall7 = p5.map(x+12.6, x1, x2, 0, 256);
p5.rect(trunkSkelRightSmall7x, trunkSkelRightSmall7y, (radiustrunkSkelRightSmall7-trunkSkelRightSmall7x)/18,(radiustrunkSkelRightSmall7-trunkSkelRightSmall7x)/20);
let trunkSkelRightSmall8x = p5.map(x+6.80, x1, x2, 0, 256);
let trunkSkelRightSmall8y = p5.map(y-4, y1, y2, 0, 256);
let radiustrunkSkelRightSmall8 = p5.map(x+16.8, x1, x2, 0, 256);
p5.rect(trunkSkelRightSmall8x, trunkSkelRightSmall8y, (radiustrunkSkelRightSmall8-trunkSkelRightSmall8x)/18,(radiustrunkSkelRightSmall8-trunkSkelRightSmall8x)/20);
p5.fill(88, 42, 11);
//fifth branch
let trunkSkelbranch5x = p5.map(x+3.6, x1, x2, 0, 256);
let trunkSkelbranch5y = p5.map(y-6.5, y1, y2, 0, 256);
let radiustrunkSkelbranch5 = p5.map(x+13.6, x1, x2, 0, 256);
p5.rect(trunkSkelbranch5x, trunkSkelbranch5y, (radiustrunkSkelbranch5-trunkSkelbranch5x)/4,(radiustrunkSkelbranch5-trunkSkelbranch5x)/20);
//smaller parts
p5.fill(80, 55, 39);
let trunkSkelRightSmall9x = p5.map(x+3, x1, x2, 0, 256);
let trunkSkelRightSmall9y = p5.map(y-6, y1, y2, 0, 256);
let radiustrunkSkelRightSmall9 = p5.map(x+13, x1, x2, 0, 256);
p5.rect(trunkSkelRightSmall9x, trunkSkelRightSmall9y, (radiustrunkSkelRightSmall9-trunkSkelRightSmall9x)/18,(radiustrunkSkelRightSmall9-trunkSkelRightSmall9x)/20);
let trunkSkelRightSmall10x = p5.map(x+6.1, x1, x2, 0, 256);
let trunkSkelRightSmall10y = p5.map(y-6, y1, y2, 0, 256);
let radiustrunkSkelRightSmall10 = p5.map(x+16.1, x1, x2, 0, 256);
p5.rect(trunkSkelRightSmall10x, trunkSkelRightSmall10y, (radiustrunkSkelRightSmall10-trunkSkelRightSmall10x)/18,(radiustrunkSkelRightSmall10-trunkSkelRightSmall10x)/20);
}
}
/*
* 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 < 0) {
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 >= 0) {
p5.fill(0, 0, 255);
p5.noStroke();
}
p5.stroke(0, 0, 150);
p5.fill(0, 0, 128);
p5.noStroke();
//p5.ellipse(x_pos, y_pos, cur_ball_radius);
//if (zoom <= 5){
//snowcontours
p5.fill(250);
let backx = p5.map(x-5, x1, x2, 0, 256);
let backy = p5.map(y-12, y1, y2, 0, 256);
let radiusback = p5.map(x+5, x1, x2, 0, 256);
let back2x = p5.map(x-3.5, x1, x2, 0, 256);
let back2y = p5.map(y-13, y1, y2, 0, 256);
let radiusback2 = p5.map(x+6.5, x1, x2, 0, 256);
let back3x = p5.map(x-2, x1, x2, 0, 256);
let back3y = p5.map(y-15, y1, y2, 0, 256);
let radiusback3 = p5.map(x+8, x1, x2, 0, 256);
let back4x = p5.map(x-0.5, x1, x2, 0, 256);
let back4y = p5.map(y-18, y1, y2, 0, 256);
let radiusback4 = p5.map(x+9.5, x1, x2, 0, 256);
let back5x = p5.map(x+1.5, x1, x2, 0, 256);
let back5y = p5.map(y-22, y1, y2, 0, 256);
let radiusback5 = p5.map(x+11.5, x1, x2, 0, 256);
let back6x = p5.map(x+3.3, x1, x2, 0, 256);
let back6y = p5.map(y-27, y1, y2, 0, 256);
let radiusback6 = p5.map(x+13.3, x1, x2, 0, 256);
let backax = p5.map(x-6.5, x1, x2, 0, 256);
let backay = p5.map(y-9.5, y1, y2, 0, 256);
let radiusbacka = p5.map(x+3.5, x1, x2, 0, 256);
if (zoom <= 1){
//actually cteates the snow contours
p5.rect(backx, backy, (radiusback-backx)*2,(radiusback-backx)*2);
p5.rect(back2x, back2y, (radiusback2-back2x)*1.7,(radiusback2-back2x)*2.2);
p5.rect(back3x, back3y, (radiusback3-back3x)*1.4,(radiusback3-back3x)*2.6);
p5.rect(back4x, back4y, (radiusback4-back4x)*1.1,(radiusback4-back4x)*3.2);
p5.rect(back5x, back5y, (radiusback5-back5x)/1.5,(radiusback5-back5x)*4);
p5.rect(back6x, back6y, (radiusback5-back6x)/2.6,(radiusback6-back6x)*5);
//p5.fill(0);
p5.rect(backax, backay, (radiusbacka-backax)*2.3,(radiusbacka-backax)*1.5);
}
//draws the tree from a fucntion
tree(p5, x , y, x1, x2, y1, y2, z, zoom);
if (zoom <= 4){
//draws the lights when zoom is ewqual to 4
drawLights(p5, x1, x2, y1, y2, shifted_x, shifted_y, ball_radius, 2*line_width, z, zoom);
}
p5.fill(230);
let calendarx = p5.map(x+9, x1, x2, 0, 256);
let calendary = p5.map(y-10, y1, y2, 0, 256);
let radiuscalendar = p5.map(x+19, x1, x2, 0, 256);
//draws the calendar and text, only when it is big enough to properly read
if (zoom >= 3){
p5.rect(calendarx, calendary, (radiuscalendar-calendarx)/5,(radiuscalendar-calendarx)/5);
p5.fill(200,0,0);
p5.rect(calendarx, calendary, (radiuscalendar-calendarx)/5,(radiuscalendar-calendarx)/20);
}
let fontx = p5.map(x+9.1, x1, x2, 0, 256);
let fonty = p5.map(y-8.2, y1, y2, 0, 256);
let radiusfont = p5.map(x+19, x1, x2, 0, 256);
p5.fill(0);
p5.stroke(0);
p5.strokeWeight(1);
let sizex = x2 - x1;
p5.textSize(radiusfont/12);
//changes the date when zoom in/ time passes
if (zoom ==3){
p5.text("23", fontx, fonty);
}
if (zoom ==4){
p5.text("25", fontx, fonty);
}
if (zoom ==5){
p5.textSize(radiusfont/7);
p5.text("27", fontx, fonty);
}
if (zoom ==6){
p5.textSize(radiusfont/7);
p5.text("31", fontx, fonty);
}
}
}
//p5.fill(0)
// let backx = p5.map(x+9.1, x1, x2, 0, 256);
// let backy = p5.map(y-8.2, y1, y2, 0, 256);
// let radiusback = p5.map(x+19, x1, x2, 0, 256);
// p5.rect(backx, backy, (radiusback-backx),(radiusback-backx));
//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);
}
const max_thickness = 64;
const ball_radius = 32;
const line_width = 8;
const grid_size = 64;
const max_movement = 100;
let do_animation = true;
// var r = random(255);
/* 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 */
/* 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]
}
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) {
/* For animation: updated z based on global frame count */
let dz = p5.globalFrameCount / 100.0;
z = z + dz;
/* 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);
tree(p5, x , y, x1, x2, y1, y2, z, zoom);
/* 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.rect(x_pos, y_pos, cur_ball_radius/2,cur_ball_radius/8);
// p5.fill(200);
// p5.rect(x_pos+ (cur_ball_radius/20), y_pos-32, cur_ball_radius/2.5,cur_ball_radius/8);
// p5.fill(210);
// p5.rect(x_pos+ (cur_ball_radius/20), y_pos-64, cur_ball_radius/5,cur_ball_radius/8);
}
}
// 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);
}
function tree (p5, x, y, x1, x2, y1, y2, z, zoom){
// bottom rec 512
let rect1x = p5.map(x, x1, x2, 0, 256);
let rect1y = p5.map(y, y1, y2, 0, 256);
let radiusRect1 = p5.map(x+10, x1, x2, 0, 256);
// seccond rect
let rect2x = p5.map(x+0.8, x1, x2, 0, 256);
let rect2y = p5.map(y-2, y1, y2, 0, 256);
let radiusRect2 = p5.map(x+10.8, x1, x2, 0, 256);
//third rect
let rect3x = p5.map(x+1.4, x1, x2, 0, 256);
let rect3y = p5.map(y-4, y1, y2, 0, 256);
let radiusRect3 = p5.map(x+11.4, x1, x2, 0, 256);
//fourth rect
let rect4x = p5.map(x+2.1, x1, x2, 0, 256);
let rect4y = p5.map(y-6, y1, y2, 0, 256);
let radiusRect4 = p5.map(x+12.1, x1, x2, 0, 256);
//fifth rect
let rect5x = p5.map(x+2.9, x1, x2, 0, 256);
let rect5y = p5.map(y-8, y1, y2, 0, 256);
let radiusRect5 = p5.map(x+12.9, x1, x2, 0, 256);
//base of tree
let basex = p5.map(x+2.9, x1, x2, 0, 256);
let basey = p5.map(y+2, y1, y2, 0, 256);
let radiusbase = p5.map(x+12.9, x1, x2, 0, 256);
//snow hole thing
let base2x = p5.map(x+1.5, x1, x2, 0, 256);
let base2y = p5.map(y+3, y1, y2, 0, 256);
let radiusbase2 = p5.map(x+11.5, x1, x2, 0, 256);
let base3x = p5.map(x+1, x1, x2, 0, 256);
let base3y = p5.map(y+3.4, y1, y2, 0, 256);
let radiusbase3 = p5.map(x+11, x1, x2, 0, 256);
p5.strokeWeight(0);
// furst rec 512
p5.fill(34, 99, 36);
p5.rect(rect1x, rect1y, (radiusRect1-rect1x),(radiusRect1-rect1x)/5);
// seccond rect
p5.fill(38, 109, 40);
p5.rect(rect2x, rect2y, (radiusRect2-rect2x)/1.20,(radiusRect2-rect2x)/5);
//third rect
p5.fill(58, 153, 61);
p5.rect(rect3x, rect3y, (radiusRect3-rect3x)/1.40,(radiusRect3-rect3x)/5);
//fourth rect
p5.fill(49, 137, 52);
p5.rect(rect4x, rect4y, (radiusRect4-rect4x)/1.80,(radiusRect4-rect4x)/5);
//fifth rect
p5.fill(63, 175, 66);
p5.rect(rect5x, rect5y, (radiusRect5-rect5x)/2.6,(radiusRect5-rect5x)/5);
//zoom 2 introduces snow base around the botto of tree
if(zoom > 2){
p5.fill(220);
p5.rect(base2x, base2y, (radiusbase2-base2x)/1.5,(radiusbase2-base2x)/5);
p5.rect(base3x, base3y, (radiusbase3-base3x)/1.3,(radiusbase3-base3x)/8);
}
//zoom 3 introduces smaller details and shades on the tree
if (zoom > 3){
p5.fill(53, 132, 55);
p5.rect(rect1x, rect1y, (radiusRect1-rect1x),(radiusRect1-rect1x)/7);
p5.fill(59, 137, 61);
p5.rect(rect2x, rect2y, (radiusRect2-rect2x)/1.20,(radiusRect2-rect2x)/7);
p5.fill(78, 173, 81);
p5.rect(rect3x, rect3y, (radiusRect3-rect3x)/1.40,(radiusRect3-rect3x)/7);
p5.fill(68, 155, 71);
p5.rect(rect4x, rect4y, (radiusRect4-rect4x)/1.80,(radiusRect4-rect4x)/7);
p5.fill(84, 188, 87);
p5.rect(rect5x, rect5y, (radiusRect5-rect5x)/2.6,(radiusRect5-rect5x)/7);
}
//zoom 4 introduces snowcaps to the top of trees
if (zoom > 4){
p5.fill(240);
p5.rect(rect1x, rect1y, (radiusRect1-rect1x),(radiusRect1-rect1x)/20);
p5.rect(rect2x, rect2y, (radiusRect2-rect2x)/1.20,(radiusRect2-rect2x)/20);
p5.rect(rect3x, rect3y, (radiusRect3-rect3x)/1.40,(radiusRect3-rect3x)/20);
p5.rect(rect4x, rect4y, (radiusRect4-rect4x)/1.80,(radiusRect4-rect4x)/20);
p5.rect(rect5x, rect5y, (radiusRect5-rect5x)/2.6,(radiusRect5-rect5x)/20);
}
p5.fill(99, 60, 34);
p5.rect(basex, basey, (radiusbase-basex)/2.6,(radiusbase-basex)/5);
//places the brown stem of the tree back ontop of the snow circle well thing. Also adds some more rendering detail
if (zoom > 3){
p5.fill(114, 75, 49);
p5.rect(basex, basey, (radiusbase-basex)/8,(radiusbase-basex)/5);
}
if (zoom > 4){
//star 1
let star1x = p5.map(x+4.7, x1, x2, 0, 256);
let star1y = p5.map(y-11, y1, y2, 0, 256);
let radiusstar1 = p5.map(x+14.7, x1, x2, 0, 256);
p5.fill(255, 226, 86);
p5.rect(star1x, star1y, (radiusstar1-star1x)/25,(radiusstar1-star1x)/4);
//star 2
let star2x = p5.map(x+4.01, x1, x2, 0, 256);
let star2y = p5.map(y-10, y1, y2, 0, 256);
let radiusstar2 = p5.map(x+14.7, x1, x2, 0, 256);
p5.rect(star2x, star2y, (radiusstar2-star2x)/6,(radiusstar2-star2x)/25);
//star 3
let star3x = p5.map(x+4.4, x1, x2, 0, 256);
let star3y = p5.map(y-10.3, y1, y2, 0, 256);
let radiusstar3 = p5.map(x+14.4, x1, x2, 0, 256);
p5.rect(star3x, star3y, (radiusstar3-star3x)/10,(radiusstar3-star3x)/10);
//light 1
let light1x = p5.map(x+2.9, x1, x2, 0, 256);
let light1y = p5.map(y-8, y1, y2, 0, 256);
let radiuslight1 = p5.map(x+12.9, x1, x2, 0, 256);
//p5.fill(255,0,0);
p5.rect(light1x, light1y, (radiuslight1-light1x)/20,(radiuslight1-light1x)/20);
//2
let light3x = p5.map(x+5.6, x1, x2, 0, 256);
let light3y = p5.map(y-6.3, y1, y2, 0, 256);
let radiuslight3 = p5.map(x+15.6, x1, x2, 0, 256);
p5.rect(light3x, light3y, (radiuslight3-light3x)/20,(radiuslight3-light3x)/20);
//3
let light4x = p5.map(x+4, x1, x2, 0, 256);
let light4y = p5.map(y-7, y1, y2, 0, 256);
let radiuslight4 = p5.map(x+14, x1, x2, 0, 256);
p5.rect(light4x, light4y, (radiuslight4-light4x)/20,(radiuslight4-light4x)/20);
//light 4
let light2x = p5.map(x+7.2, x1, x2, 0, 256);
let light2y = p5.map(y-6, y1, y2, 0, 256);
let radiuslight2 = p5.map(x+17.2, x1, x2, 0, 256);
p5.rect(light2x, light2y, (radiuslight2-light2x)/20,(radiuslight2-light2x)/20);
//5
let light5x = p5.map(x+6, x1, x2, 0, 256);
let light5y = p5.map(y-5, y1, y2, 0, 256);
let radiuslight5 = p5.map(x+16, x1, x2, 0, 256);
p5.rect(light5x, light5y, (radiuslight5-light5x)/20,(radiuslight5 - light5x)/20);
//6
let light6x = p5.map(x+4.5, x1, x2, 0, 256);
let light6y = p5.map(y-4.5, y1, y2, 0, 256);
let radiuslight6 = p5.map(x+14.5, x1, x2, 0, 256);
p5.rect(light6x, light6y, (radiuslight6-light6x)/20,(radiuslight6 - light6x)/20);
//7
let light7x = p5.map(x+3, x1, x2, 0, 256);
let light7y = p5.map(y-4.2, y1, y2, 0, 256);
let radiuslight7 = p5.map(x+13, x1, x2, 0, 256);
p5.rect(light7x, light7y, (radiuslight7-light7x)/20,(radiuslight7 - light7x)/20);
//8
let light8x = p5.map(x+1.4, x1, x2, 0, 256);
let light8y = p5.map(y-4, y1, y2, 0, 256);
let radiuslight8 = p5.map(x+11.4, x1, x2, 0, 256);
p5.rect(light8x, light8y, (radiuslight8-light8x)/20,(radiuslight8-light8x)/20);
//9
let light9x = p5.map(x+2.6, x1, x2, 0, 256);
let light9y = p5.map(y-3.2, y1, y2, 0, 256);
let radiuslight9 = p5.map(x+12.6, x1, x2, 0, 256);
p5.rect(light9x, light9y, (radiuslight9-light9x)/20,(radiuslight9 - light9x)/20);
//10
let light10x = p5.map(x+4.5, x1, x2, 0, 256);
let light10y = p5.map(y-2.6, y1, y2, 0, 256);
let radiuslight10 = p5.map(x+14.5, x1, x2, 0, 256);
p5.rect(light10x, light10y, (radiuslight10-light10x)/20,(radiuslight10 - light10x)/20);
//11
let light11x = p5.map(x+6.5, x1, x2, 0, 256);
let light11y = p5.map(y-2.2, y1, y2, 0, 256);
let radiuslight11 = p5.map(x+16.5, x1, x2, 0, 256);
p5.rect(light11x, light11y, (radiuslight11-light11x)/20,(radiuslight11 - light11x)/20);
//12
let light12x = p5.map(x+8.6, x1, x2, 0, 256);
let light12y = p5.map(y-2, y1, y2, 0, 256);
let radiuslight12 = p5.map(x+18.6, x1, x2, 0, 256);
p5.rect(light12x, light12y, (radiuslight12-light12x)/20,(radiuslight12 - light12x)/20);
//13
let light13x = p5.map(x+7, x1, x2, 0, 256);
let light13y = p5.map(y-0.7, y1, y2, 0, 256);
let radiuslight13 = p5.map(x+17, x1, x2, 0, 256);
p5.rect(light13x, light13y, (radiuslight13-light13x)/20,(radiuslight13 - light13x)/20);
//14
let light14x = p5.map(x+5, x1, x2, 0, 256);
let light14y = p5.map(y+0.3, y1, y2, 0, 256);
let radiuslight14 = p5.map(x+15, x1, x2, 0, 256);
p5.rect(light14x, light14y, (radiuslight14-light14x)/20,(radiuslight14 - light14x)/20);
//15
let light15x = p5.map(x+2.5, x1, x2, 0, 256);
let light15y = p5.map(y+1, y1, y2, 0, 256);
let radiuslight15 = p5.map(x+12.5, x1, x2, 0, 256);
p5.rect(light15x, light15y, (radiuslight15-light15x)/20,(radiuslight15 - light15x)/20);
//17
let light17x = p5.map(x, x1, x2, 0, 256);
let light17y = p5.map(y+1.5, y1, y2, 0, 256);
let radiuslight17 = p5.map(x+10, x1, x2, 0, 256);
p5.rect(light17x, light17y, (radiuslight17-light17x)/20,(radiuslight17 - light17x)/20);
}
}
/*
* 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 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 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.strokeWeight(10);
// p5.stroke(255, 0, 0)
// p5.rect(0, 0, 255, 255);
}
<!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>
<!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%;
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/leaflet@1.2.0/dist/leaflet.js"></script>
<script src="leaflet-hash.js"></script>
<script src="drawgrid.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);
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);
}
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)
{
"commits": [
{
"sha": "0000000000000000000000000000000000000006",
"name": "final"
},
{
"sha": "728981d99daad831b26bc5336fbfeb12673ce013",
"name": "tour"
},
{
"sha": "4429d1d63d7283bfe3787233d0c32db68e524dee",
"name": "animation"
},
{
"sha": "2d803a05d292cdcc578c4d7a604598e5930c2fb6",
"name": "tree grid"
},
{
"sha": "93ebd2fad59c4af73b399929f1308a6bda97c39e",
"name": "sketch"
}
]
}
This file has been truncated, but you can view the full file.
View raw

(Sorry about that, but we can’t show files that are this big right now.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment