Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"dependencies": {
"@anthropic-ai/sdk": "^0.25.2",
"@ejfox/gpt-browser": "^2.0.0",
"@iconify-json/ei": "^1.1.9",
"@nuxt/content": "^2.13.2",
"@nuxt/ui": "^2.18.4",
"@nuxtjs/google-fonts": "^3.2.0",
Expand All @@ -37,10 +38,13 @@
"d3-voronoi": "^1.1.4",
"date-fns": "^3.6.0",
"eslint-config-prettier": "^9.1.0",
"fast-simplex-noise": "^4.0.0",
"front-matter": "^4.0.2",
"inquirer": "^10.1.8",
"js-md5": "^0.8.3",
"nuxt-gtag": "^2.1.0",
"p-limit": "^6.1.0",
"p5": "^1.10.0",
"rehype-external-links": "^3.0.0",
"remark-emoji": "^5.0.1",
"remark-external-links": "^9.0.1",
Expand All @@ -50,6 +54,7 @@
"remark-unwrap-images": "^4.0.0",
"remark-wiki-link": "^2.0.1",
"rss": "^1.2.2",
"simplex-noise": "^4.0.3",
"unicode-string": "^2.1.0",
"unicodechar-string": "^1.0.0",
"uuid": "^10.0.0",
Expand Down
180 changes: 176 additions & 4 deletions pages/playground/001.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,183 @@
<template>
<div class="min-h-screen flex flex-col items-center justify-center bg-gray-900">
<h1>Playground</h1>
<div class="min-h-screen flex flex-col items-center justify-center bg-gray-900 p-4">
<h1 class="text-white text-2xl mb-4">Conceptual Basins</h1>
<ClientOnly>
<div ref="p5Container"></div>
<div class="mt-4 grid grid-cols-2 lg:grid-cols-2 gap-4">
<div class="flex flex-col">
<label class="text-white">Grid Size</label>
<UInput v-model="gridSize" type="number" :max="maxGridSize" />
</div>
<div class="flex flex-col">
<label class="text-white">Noise Scale</label>
<UInput v-model="noiseScale" type="number" step="0.01" />
</div>
<div class="flex flex-col">
<label class="text-white">Terrain Height</label>
<UInput v-model="terrainHeight" type="number" />
</div>
<div class="flex flex-col">
<label class="text-white">Rotation Speed</label>
<URange v-model="rotationSpeed" type="number" step="0.001" />
</div>
<div class="flex flex-col">
<label class="text-white">Terrain Zoom</label>
<URange v-model="terrainZoom" type="number" step="0.1" min="0.1" />
</div>
</div>
</ClientOnly>
</div>
</template>

<script setup>
import { useWindowSize } from '@vueuse/core';

</script>
const { width, height } = useWindowSize()
const p5Container = ref(null);
let p5Instance = null;

<style scoped></style>
console.log(width.value, height.value);

// Interactive controls
const gridSize = ref(72);
const noiseScale = ref(0.05);
const terrainHeight = ref(140);
const rotationSpeed = ref(0.005);
const maxGridSize = ref(Math.floor(Math.min(width.value, height.value) / 20));

const terrainZoom = ref(0.9)

// Other variables
const canvasWidth = width.value;
const canvasHeight = height.value;
let terrain = [];
let peakPoint = { x: 0, y: 0, z: 0 };
let valleyPoint = { x: 0, y: 0, z: 0 };
let midPoint = { x: 0, y: 0, z: 0 };
let angle = 0;
let font;

onMounted(async () => {
if (process.client) {
const p5 = await import('p5');

const sketch = (p) => {
p.preload = () => {
font = p.loadFont('https://cdnjs.cloudflare.com/ajax/libs/ink/3.1.10/fonts/Roboto/roboto-medium-webfont.ttf');
};

p.setup = () => {
p.createCanvas(canvasWidth, canvasHeight, p.WEBGL);
p.textFont(font);
p.textSize(16);
p.textAlign(p.CENTER, p.CENTER);
generateTerrain();
};

p.draw = () => {
p.background(0);
p.stroke(255, 50);
p.noFill();

p.rotateX(p.PI / 3);
p.rotateZ(angle);
angle += rotationSpeed.value;

drawTerrain();
drawPeakValleyConnection();
drawLabel(peakPoint, "SPLIFF", [255, 0, 0]);
drawLabel(valleyPoint, "JAVASCRIPT", [0, 0, 255]);
drawLabel(midPoint, "OPTIMUM CREATIVITY", [0, 255, 0]);
};

function generateTerrain() {
terrain = [];
peakPoint = { x: 0, y: 0, z: -Infinity };
valleyPoint = { x: 0, y: 0, z: Infinity };

for (let y = 0; y < gridSize.value; y++) {
terrain[y] = [];
for (let x = 0; x < gridSize.value; x++) {
let noiseVal = p.noise(x * noiseScale.value, y * noiseScale.value);
let z = p.map(noiseVal, 0, 1, -terrainHeight.value / 2, terrainHeight.value / 2);
terrain[y][x] = z;

if (z > peakPoint.z) {
peakPoint = { x, y, z };
}
if (z < valleyPoint.z) {
valleyPoint = { x, y, z };
}
}
}

midPoint = {
x: (peakPoint.x + valleyPoint.x) / 2,
y: (peakPoint.y + valleyPoint.y) / 2,
z: (peakPoint.z + valleyPoint.z) / 2
};
}

function drawTerrain() {
let s = canvasWidth / gridSize.value;
p.beginShape(p.LINES);
for (let y = 0; y < gridSize.value - 1; y++) {
for (let x = 0; x < gridSize.value; x++) {
p.vertex(x * s * terrainZoom.value - canvasWidth / 2, y * s * terrainZoom.value - canvasHeight / 2, terrain[y][x]);
p.vertex(x * s * terrainZoom.value - canvasWidth / 2, (y + 1) * s * terrainZoom.value - canvasHeight / 2, terrain[y + 1][x]);
if (x < gridSize.value - 1) {
p.vertex(x * s * terrainZoom.value - canvasWidth / 2, y * s * terrainZoom.value - canvasHeight / 2, terrain[y][x]);
p.vertex((x + 1) * s * terrainZoom.value - canvasWidth / 2, y * s * terrainZoom.value - canvasHeight / 2, terrain[y][x + 1]);
}
}
}
p.endShape();
}

function drawPeakValleyConnection() {
let s = canvasWidth / gridSize.value;
p.stroke(255, 255, 0);
p.strokeWeight(2);
p.line(
peakPoint.x * s * terrainZoom.value - canvasWidth / 2, peakPoint.y * s * terrainZoom.value - canvasHeight / 2, peakPoint.z,
valleyPoint.x * s * terrainZoom.value - canvasWidth / 2, valleyPoint.y * s * terrainZoom.value - canvasHeight / 2, valleyPoint.z
);
p.strokeWeight(1);
}

function drawLabel(point, text, color) {
let s = canvasWidth / gridSize.value;
p.push();
p.translate(point.x * s * terrainZoom.value - canvasWidth / 2, point.y * s * terrainZoom.value - canvasHeight / 2, point.z);
p.fill(color);
p.noStroke();
p.sphere(5);
p.translate(0, -20, 0);

p.rotateZ(-angle);
p.rotateX(-p.PI / 3);

p.fill(255);
p.text(text, 0, 0);
p.pop();
}
};

p5Instance = new p5.default(sketch, p5Container.value);
}
});

watch([gridSize, noiseScale, terrainHeight, terrainZoom], generateTerrain);

function generateTerrain() {
if (p5Instance) {
p5Instance.generateTerrain();
}
}

onUnmounted(() => {
if (process.client && p5Instance) {
p5Instance.remove();
}
});
</script>
22 changes: 22 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -816,6 +816,13 @@
dependencies:
"@tanstack/vue-virtual" "^3.0.0-beta.60"

"@iconify-json/ei@^1.1.9":
version "1.1.9"
resolved "https://registry.yarnpkg.com/@iconify-json/ei/-/ei-1.1.9.tgz#c70199aa0edb7bbaf28088dbf5ada7bbf904ccc8"
integrity sha512-I1Ea4rQZ0QPa44+iYpQoAdtUiHvdw07VvZgJmPZ7WfsicTyF85yA/Gj9me2tHaQwaQ/zS6HCH+lkEWH6A1XHJA==
dependencies:
"@iconify/types" "*"

"@iconify-json/heroicons@^1.1.23":
version "1.1.24"
resolved "https://registry.yarnpkg.com/@iconify-json/heroicons/-/heroicons-1.1.24.tgz#91b8e1a1f6fffdc5104c5fa4e7195164d5234c2e"
Expand Down Expand Up @@ -6146,6 +6153,11 @@ fast-npm-meta@^0.1.1:
resolved "https://registry.yarnpkg.com/fast-npm-meta/-/fast-npm-meta-0.1.1.tgz#2fb1e111595aec787ec523c06901ccb1d44a9422"
integrity sha512-uS9DjGncI/9XZ6HJFrci0WzSi++N8Jskbb2uB7+9SQlrgA3VaLhXhV9Gl5HwIGESHkayYYZFGnVNhJwRDKCWIA==

fast-simplex-noise@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/fast-simplex-noise/-/fast-simplex-noise-4.0.0.tgz#aeec71d2f4deebab310c088dc465bbc875c2a1b7"
integrity sha512-2zRCJkPdMnPyXNEeI5IYgH555Nbd/j9nC8YVoOm5dmFDjqxuLD888nEAGB8cSUIyxLlNHCZVlZ7AO27Fm3boJA==

fastq@^1.6.0:
version "1.17.1"
resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.17.1.tgz#2a523f07a4e7b1e81a42b91b8bf2254107753b47"
Expand Down Expand Up @@ -9193,6 +9205,11 @@ p-try@^2.0.0:
resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"
integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==

p5@^1.10.0:
version "1.10.0"
resolved "https://registry.yarnpkg.com/p5/-/p5-1.10.0.tgz#91dd95e7266d943718e565119106cbb419d49e66"
integrity sha512-6cWYBFhnZz7jNC6p1VWvlt3QReMqrRSmO90bgECQIKB9oko2w/sKrOAVMyei5tjIzSYcSY0JHy+BRtSAWq24jQ==

pac-proxy-agent@^7.0.0:
version "7.0.2"
resolved "https://registry.yarnpkg.com/pac-proxy-agent/-/pac-proxy-agent-7.0.2.tgz#0fb02496bd9fb8ae7eb11cfd98386daaac442f58"
Expand Down Expand Up @@ -10516,6 +10533,11 @@ simple-swizzle@^0.2.2:
dependencies:
is-arrayish "^0.3.1"

simplex-noise@^4.0.3:
version "4.0.3"
resolved "https://registry.yarnpkg.com/simplex-noise/-/simplex-noise-4.0.3.tgz#e60b840ecfb9ac972870c8c7979bd867a5b4032f"
integrity sha512-qSE2I4AngLQG7BXqoZj51jokT4WUXe8mOBrvfOXpci8+6Yu44+/dD5zqDpOx3Ux792eamTd2lLcI8jqFntk/lg==

sirv@^2.0.4:
version "2.0.4"
resolved "https://registry.yarnpkg.com/sirv/-/sirv-2.0.4.tgz#5dd9a725c578e34e449f332703eb2a74e46a29b0"
Expand Down