From 0b0be165f273afa7d11256ebf4eef461b39450b1 Mon Sep 17 00:00:00 2001 From: Stalgia Grigg Date: Thu, 29 Feb 2024 10:57:58 -0800 Subject: [PATCH] Access all examples through Astro --- src/content/config.ts | 2 + src/content/examples/config.ts | 9 + .../08_Trig_Wheels_and_Pie_Chart/code.js | 75 -------- .../description.mdx | 3 - .../03_Walk_Over_2dArray/description.mdx | 11 +- .../00_ Pixel_Array/description.mdx | 2 +- .../01_ Histogram/description.mdx | 2 +- .../11_SmokeParticleSystem/code.js | 176 ------------------ .../11_SmokeParticleSystem/description.mdx | 3 - .../en/10_Interaction/23_snake/code.js | 166 ----------------- .../10_Interaction/23_snake/description.mdx | 3 - src/pages/examples/[...slug].astro | 17 ++ src/pages/examples/index.astro | 14 ++ 13 files changed, 53 insertions(+), 430 deletions(-) create mode 100644 src/content/examples/config.ts delete mode 100644 src/content/examples/en/01_Form/08_Trig_Wheels_and_Pie_Chart/code.js delete mode 100644 src/content/examples/en/01_Form/08_Trig_Wheels_and_Pie_Chart/description.mdx delete mode 100644 src/content/examples/en/09_Simulate/11_SmokeParticleSystem/code.js delete mode 100644 src/content/examples/en/09_Simulate/11_SmokeParticleSystem/description.mdx delete mode 100644 src/content/examples/en/10_Interaction/23_snake/code.js delete mode 100644 src/content/examples/en/10_Interaction/23_snake/description.mdx create mode 100644 src/pages/examples/[...slug].astro create mode 100644 src/pages/examples/index.astro diff --git a/src/content/config.ts b/src/content/config.ts index 38cd155fac..645cde34e5 100644 --- a/src/content/config.ts +++ b/src/content/config.ts @@ -4,6 +4,7 @@ import { librariesCollection } from "./libraries/config"; import { peopleCollection } from "./people/config"; import { sketchesCollection } from "./sketches/config"; import { referenceCollection } from "./reference/config"; +import { examplesCollection } from "./examples/config"; export const collections = { tutorials: tutorialsCollection, @@ -12,4 +13,5 @@ export const collections = { people: peopleCollection, sketches: sketchesCollection, reference: referenceCollection, + examples: examplesCollection, }; diff --git a/src/content/examples/config.ts b/src/content/examples/config.ts new file mode 100644 index 0000000000..1929c39826 --- /dev/null +++ b/src/content/examples/config.ts @@ -0,0 +1,9 @@ +import { z, defineCollection } from "astro:content"; + +export const examplesCollection = defineCollection({ + type: "content", + schema: z.object({ + title: z.string(), + arialabel: z.string().optional(), + }), +}); diff --git a/src/content/examples/en/01_Form/08_Trig_Wheels_and_Pie_Chart/code.js b/src/content/examples/en/01_Form/08_Trig_Wheels_and_Pie_Chart/code.js deleted file mode 100644 index 7895fedc02..0000000000 --- a/src/content/examples/en/01_Form/08_Trig_Wheels_and_Pie_Chart/code.js +++ /dev/null @@ -1,75 +0,0 @@ - - -function setup() { - createCanvas(400, 400); - colorMode(HSB); - angleMode(DEGREES); - - //vars for color wheel center point - let x = width / 2; - let y = height / 2 + 100; - colorWheel(x, y, 100); //slide 11 - - noStroke(); - pieChartPop(200, 100); //slide 12 -} - -//**** slide 12 pie chart trig demo -function pieChartPop(x, y) { - let [total, child, young, adult, senior, elder] = [577, 103, 69, - 122, 170, 113 - ]; - let startValue = 0; - let range = 0; - - //child slice - range = child / total; - drawSlice("blue", x, y, 200, startValue, startValue + range); - startValue += range; - //young slice - range = young / total; - drawSlice("orange", x, y, 200, startValue, startValue + range); - startValue += range; - //adult slice - range = adult / total; - drawSlice("green", x, y, 200, startValue, startValue + range); - startValue += range; - //senior slice - range = senior / total; - drawSlice("tan", x, y, 200, startValue, startValue + range); - startValue += range; - //elder slice - range = elder / total; - drawSlice("pink", x, y, 200, startValue, startValue + range); - startValue += range; - -} - -/** - * drawSlice - draw colored arc based on angle percentages. slide 13 - * Adjust angles so that 0% starts at top (actually -90). - * @param {color} fColor - fill color - * @param {number} x - center x - * @param {number} y - center y - * @param {number} d - diameter - * @param {float} percent1 - starting percentage - * @param {float} percent2 - ending percentage - */ -function drawSlice(fColor, x, y, d, percent1, percent2) { - fill(fColor); - arc(x, y, d, d, -90 + percent1 * 360, -90 + percent2 * 360); -} - -//**** slide 11 trig demo -function colorWheel(x, y, rad) { - strokeWeight(10); - strokeCap(SQUARE); - - //Iterate 360 degrees of lines, +10deg per turn - for (let a = 0; a < 360; a += 10) { - stroke(a, 150, 200); //hue based on a - //radius is 100, angle is a degrees - line(x, y, x + rad * cos(a), - y + rad * sin(a)); - } -} diff --git a/src/content/examples/en/01_Form/08_Trig_Wheels_and_Pie_Chart/description.mdx b/src/content/examples/en/01_Form/08_Trig_Wheels_and_Pie_Chart/description.mdx deleted file mode 100644 index 04ec6a7d33..0000000000 --- a/src/content/examples/en/01_Form/08_Trig_Wheels_and_Pie_Chart/description.mdx +++ /dev/null @@ -1,3 +0,0 @@ - - -undefined diff --git a/src/content/examples/en/03_Arrays/03_Walk_Over_2dArray/description.mdx b/src/content/examples/en/03_Arrays/03_Walk_Over_2dArray/description.mdx index 04ec6a7d33..45cb9988ec 100644 --- a/src/content/examples/en/03_Arrays/03_Walk_Over_2dArray/description.mdx +++ b/src/content/examples/en/03_Arrays/03_Walk_Over_2dArray/description.mdx @@ -1,3 +1,10 @@ +--- +title: Walk Over 2d Array +arialabel: >- + Several small black words arranged on a white background. +--- - -undefined +contributed by [Prof WM Harris](https://www.rit.edu/directory/wmhics-w-michelle-harris), How to display 2D array contents on the canvas using regular for and for-of loops in multiple different ways. +A function is created for the canvas, the 2D array (Friend Array) is initialized and walked over using nested loops in different ways. +Variables x and y are used to place the array item on the canvas in the form of 2D array. +The final nested loop is used to initialize 2D array (Fish Array) with random Integers (fish ages). diff --git a/src/content/examples/en/06_Image_Processing/00_ Pixel_Array/description.mdx b/src/content/examples/en/06_Image_Processing/00_ Pixel_Array/description.mdx index 93ce88389c..5e593daeac 100644 --- a/src/content/examples/en/06_Image_Processing/00_ Pixel_Array/description.mdx +++ b/src/content/examples/en/06_Image_Processing/00_ Pixel_Array/description.mdx @@ -1,8 +1,8 @@ --- title: Pixel Array +arialabel: A rectangle that changes hues as you move the mouse --- - Click and drag the mouse up and down to control the signal and press and hold any key to see the current pixel being read. This program sequentially reads the color of every pixel of an image diff --git a/src/content/examples/en/06_Image_Processing/01_ Histogram/description.mdx b/src/content/examples/en/06_Image_Processing/01_ Histogram/description.mdx index 1b7b1b2218..6ec69c3eae 100644 --- a/src/content/examples/en/06_Image_Processing/01_ Histogram/description.mdx +++ b/src/content/examples/en/06_Image_Processing/01_ Histogram/description.mdx @@ -1,8 +1,8 @@ --- title: Histogram +arialabel: A black and white image of white persons in front of a tent with a white bar histogram overlayed on the bottom. --- - Calculates the histogram of an image. A histogram is the frequency distribution of the gray levels with the number of pure black values displayed on the left and number of pure white values on the right. diff --git a/src/content/examples/en/09_Simulate/11_SmokeParticleSystem/code.js b/src/content/examples/en/09_Simulate/11_SmokeParticleSystem/code.js deleted file mode 100644 index c9395bbcd1..0000000000 --- a/src/content/examples/en/09_Simulate/11_SmokeParticleSystem/code.js +++ /dev/null @@ -1,176 +0,0 @@ - - -// texture for the particle -let particle_texture = null; - -// variable holding our particle system -let ps = null; - -function preload() { - particle_texture = loadImage("assets/particle_texture.png"); -} - -function setup() { - - //set the canvas size - createCanvas(640, 360); - - //initialize our particle system - ps = new ParticleSystem(0, createVector(width / 2, height - 60), particle_texture); -} - -function draw() { - background(0); - - let dx = map(mouseX, 0, width, -0.2, 0.2); - let wind = createVector(dx, 0); - - ps.applyForce(wind); - ps.run(); - for (let i = 0; i < 2; i++) { - ps.addParticle(); - } - - // Draw an arrow representing the wind force - drawVector(wind, createVector(width / 2, 50, 0), 500); -} - -/** - * This function draws an arrow showing the direction our "wind" is blowing. - */ -function drawVector(v, loc, scale){ - push(); - let arrowsize = 4; - translate(loc.x, loc.y); - stroke(255); - rotate(v.heading()); - - let len = v.mag() * scale; - line(0, 0, len,0); - line(len, 0, len-arrowsize, +arrowsize / 2); - line(len, 0, len-arrowsize, -arrowsize / 2); - pop(); -} -//========= PARTICLE SYSTEM =========== - -/** - * A basic particle system class - * @param num the number of particles - * @param v the origin of the particle system - * @param img_ a texture for each particle in the system - * @constructor - */ -let ParticleSystem = function(num, v, img_) { - - this.particles = []; - this.origin = v.copy(); // we make sure to copy the vector value in case we accidentally mutate the original by accident - this.img = img_ - for(let i = 0; i < num; ++i){ - this.particles.push(new Particle(this.origin, this.img)); - } -}; - -/** - * This function runs the entire particle system. - */ -ParticleSystem.prototype.run = function() { - - // cache length of the array we're going to loop into a variable - // You may see .length in a for loop, from time to time but - // we cache it here because otherwise the length is re-calculated for each iteration of a loop - let len = this.particles.length; - - //loop through and run particles - for (let i = len - 1; i >= 0; i--) { - let particle = this.particles[i]; - particle.run(); - - // if the particle is dead, we remove it. - // javascript arrays don't have a "remove" function but "splice" works just as well. - // we feed it an index to start at, then how many numbers from that point to remove. - if (particle.isDead()) { - this.particles.splice(i, 1); - } - } -} - -/** - * Method to add a force vector to all particles currently in the system - * @param dir a p5.Vector describing the direction of the force. - */ -ParticleSystem.prototype.applyForce = function(dir) { - let len = this.particles.length; - for(let i = 0; i < len; ++i){ - this.particles[i].applyForce(dir); - } -} - -/** - * Adds a new particle to the system at the origin of the system and with - * the originally set texture. - */ -ParticleSystem.prototype.addParticle = function() { - this.particles.push(new Particle(this.origin, this.img)); -} - -//========= PARTICLE =========== -/** - * A simple Particle class, renders the particle as an image - */ -let Particle = function (pos, img_) { - this.loc = pos.copy(); - - let vx = randomGaussian() * 0.3; - let vy = randomGaussian() * 0.3 - 1.0; - - this.vel = createVector(vx, vy); - this.acc = createVector(); - this.lifespan = 100.0; - this.texture = img_; -} - -/** - * Simulataneously updates and displays a particle. - */ -Particle.prototype.run = function() { - this.update(); - this.render(); -} - -/** - * A function to display a particle - */ -Particle.prototype.render = function() { - imageMode(CENTER); - tint(255, this.lifespan); - image(this.texture, this.loc.x, this.loc.y); -} - -/** - * A method to apply a force vector to a particle. - */ -Particle.prototype.applyForce = function(f) { - this.acc.add(f); -} - -/** - * This method checks to see if the particle has reached the end of it's lifespan, - * if it has, return true, otherwise return false. - */ -Particle.prototype.isDead = function () { - if (this.lifespan <= 0.0) { - return true; - } else { - return false; - } -} - -/** - * This method updates the position of the particle. - */ -Particle.prototype.update = function() { - this.vel.add(this.acc); - this.loc.add(this.vel); - this.lifespan -= 2.5; - this.acc.mult(0); -} diff --git a/src/content/examples/en/09_Simulate/11_SmokeParticleSystem/description.mdx b/src/content/examples/en/09_Simulate/11_SmokeParticleSystem/description.mdx deleted file mode 100644 index 04ec6a7d33..0000000000 --- a/src/content/examples/en/09_Simulate/11_SmokeParticleSystem/description.mdx +++ /dev/null @@ -1,3 +0,0 @@ - - -undefined diff --git a/src/content/examples/en/10_Interaction/23_snake/code.js b/src/content/examples/en/10_Interaction/23_snake/code.js deleted file mode 100644 index f95c9d8fb9..0000000000 --- a/src/content/examples/en/10_Interaction/23_snake/code.js +++ /dev/null @@ -1,166 +0,0 @@ - - -// the snake is divided into small segments, which are drawn and edited on each 'draw' call -let numSegments = 10; -let direction = 'right'; - -const xStart = 0; //starting x coordinate for snake -const yStart = 250; //starting y coordinate for snake -const diff = 10; - -let xCor = []; -let yCor = []; - -let xFruit = 0; -let yFruit = 0; -let scoreElem; - -function setup() { - scoreElem = createDiv('Score = 0'); - scoreElem.position(20, 20); - scoreElem.id = 'score'; - scoreElem.style('color', 'white'); - - createCanvas(500, 500); - frameRate(15); - stroke(255); - strokeWeight(10); - updateFruitCoordinates(); - - for (let i = 0; i < numSegments; i++) { - xCor.push(xStart + i * diff); - yCor.push(yStart); - } -} - -function draw() { - background(0); - for (let i = 0; i < numSegments - 1; i++) { - line(xCor[i], yCor[i], xCor[i + 1], yCor[i + 1]); - } - updateSnakeCoordinates(); - checkGameStatus(); - checkForFruit(); -} - -/** - The segments are updated based on the direction of the snake. - All segments from 0 to n-1 are just copied over to 1 till n, i.e. segment 0 - gets the value of segment 1, segment 1 gets the value of segment 2, and so on, - and this results in the movement of the snake. - - The last segment is added based on the direction in which the snake is going, - if it's going left or right, the last segment's x coordinate is increased by a - predefined value 'diff' than its second to last segment. And if it's going up - or down, the segment's y coordinate is affected. -*/ -function updateSnakeCoordinates() { - for (let i = 0; i < numSegments - 1; i++) { - xCor[i] = xCor[i + 1]; - yCor[i] = yCor[i + 1]; - } - switch (direction) { - case 'right': - xCor[numSegments - 1] = xCor[numSegments - 2] + diff; - yCor[numSegments - 1] = yCor[numSegments - 2]; - break; - case 'up': - xCor[numSegments - 1] = xCor[numSegments - 2]; - yCor[numSegments - 1] = yCor[numSegments - 2] - diff; - break; - case 'left': - xCor[numSegments - 1] = xCor[numSegments - 2] - diff; - yCor[numSegments - 1] = yCor[numSegments - 2]; - break; - case 'down': - xCor[numSegments - 1] = xCor[numSegments - 2]; - yCor[numSegments - 1] = yCor[numSegments - 2] + diff; - break; - } -} - -/** - I always check the snake's head position xCor[xCor.length - 1] and - yCor[yCor.length - 1] to see if it touches the game's boundaries - or if the snake hits itself. -*/ -function checkGameStatus() { - if ( - xCor[xCor.length - 1] > width || - xCor[xCor.length - 1] < 0 || - yCor[yCor.length - 1] > height || - yCor[yCor.length - 1] < 0 || - checkSnakeCollision() - ) { - noLoop(); - const scoreVal = parseInt(scoreElem.html().substring(8)); - scoreElem.html('Game ended! Your score was : ' + scoreVal); - } -} - -/** - If the snake hits itself, that means the snake head's (x,y) coordinate - has to be the same as one of its own segment's (x,y) coordinate. -*/ -function checkSnakeCollision() { - const snakeHeadX = xCor[xCor.length - 1]; - const snakeHeadY = yCor[yCor.length - 1]; - for (let i = 0; i < xCor.length - 1; i++) { - if (xCor[i] === snakeHeadX && yCor[i] === snakeHeadY) { - return true; - } - } -} - -/** - Whenever the snake consumes a fruit, I increment the number of segments, - and just insert the tail segment again at the start of the array (basically - I add the last segment again at the tail, thereby extending the tail) -*/ -function checkForFruit() { - point(xFruit, yFruit); - if (xCor[xCor.length - 1] === xFruit && yCor[yCor.length - 1] === yFruit) { - const prevScore = parseInt(scoreElem.html().substring(8)); - scoreElem.html('Score = ' + (prevScore + 1)); - xCor.unshift(xCor[0]); - yCor.unshift(yCor[0]); - numSegments++; - updateFruitCoordinates(); - } -} - -function updateFruitCoordinates() { - /** - The complex math logic is because I wanted the point to lie - in between 100 and width-100, and be rounded off to the nearest - number divisible by 10, since I move the snake in multiples of 10. - */ - - xFruit = floor(random(10, (width - 100) / 10)) * 10; - yFruit = floor(random(10, (height - 100) / 10)) * 10; -} - -function keyPressed() { - switch (keyCode) { - case 74: - if (direction !== 'right') { - direction = 'left'; - } - break; - case 76: - if (direction !== 'left') { - direction = 'right'; - } - break; - case 73: - if (direction !== 'down') { - direction = 'up'; - } - break; - case 75: - if (direction !== 'up') { - direction = 'down'; - } - break; - } -} diff --git a/src/content/examples/en/10_Interaction/23_snake/description.mdx b/src/content/examples/en/10_Interaction/23_snake/description.mdx deleted file mode 100644 index 04ec6a7d33..0000000000 --- a/src/content/examples/en/10_Interaction/23_snake/description.mdx +++ /dev/null @@ -1,3 +0,0 @@ - - -undefined diff --git a/src/pages/examples/[...slug].astro b/src/pages/examples/[...slug].astro new file mode 100644 index 0000000000..53a2229094 --- /dev/null +++ b/src/pages/examples/[...slug].astro @@ -0,0 +1,17 @@ +--- +import { getCollection } from "astro:content"; + +export async function getStaticPaths() { + const examples = await getCollection("examples"); + return examples.map((entry) => ({ + params: { slug: entry.slug }, + props: { entry }, + })); +} + +const { entry } = Astro.props; +const { Content } = await entry.render(); +--- + +

{entry.data.title}

+{JSON.stringify(entry)} diff --git a/src/pages/examples/index.astro b/src/pages/examples/index.astro new file mode 100644 index 0000000000..a22671529e --- /dev/null +++ b/src/pages/examples/index.astro @@ -0,0 +1,14 @@ +--- +import { getCollection } from "astro:content"; +const exampleEntries = await getCollection("examples"); +--- + +