memoscan
← all memos

Memo 0xd7b9efe7…95da60 on Ethereum

gardenconst baseGridDensity = 60; const baseWeaveSteps = 10; const baseWeaveSpeed = 1.0; const baseStrokeWidth = 1.0; let angleNoiseScale = 0.015; let sizeNoiseScale = 0.06; let recursionDepth = 3; let recursionFactor = 0.4; let grainAmount = 25; const gardenPalettes = { original: [ { h: [330, 360], s: [70, 90], b: [60, 80] }, { h: [190, 230], s: [80, 100], b: [70, 90] }, { h: [40, 60], s: [60, 80], b: [30, 50] }, { h: [260, 290], s: [70, 90], b: [40, 60] }, ], 'original-rose': [ { h: [330, 360], s: [70, 90], b: [60, 80] }, { h: [4, 22], s: [76, 94], b: [68, 94] }, { h: [34, 52], s: [66, 88], b: [56, 86] }, { h: [92, 124], s: [56, 78], b: [30, 62] }, { h: [260, 290], s: [50, 72], b: [48, 78] }, { h: [330, 360], s: [4, 14], b: [5, 20] }, ], 'original-water': [ { h: [190, 230], s: [80, 100], b: [70, 90] }, { h: [166, 194], s: [68, 90], b: [48, 80] }, { h: [92, 124], s: [54, 76], b: [30, 62] }, { h: [328, 350], s: [54, 76], b: [58, 88] }, { h: [38, 56], s: [64, 86], b: [54, 84] }, { h: [194, 230], s: [4, 14], b: [5, 20] }, ], 'original-gold': [ { h: [40, 60], s: [60, 80], b: [30, 50] }, ], 'original-violet': [ { h: [260, 290], s: [70, 90], b: [40, 60] }, ], 'night-bloom': [ { h: [285, 320], s: [70, 90], b: [60, 80] }, { h: [215, 245], s: [80, 100], b: [70, 90] }, { h: [165, 190], s: [60, 80], b: [30, 50] }, { h: [325, 350], s: [70, 90], b: [40, 60] }, ], 'sunlit-earth': [ { h: [5, 25], s: [70, 90], b: [60, 80] }, { h: [28, 48], s: [80, 100], b: [70, 90] }, { h: [50, 72], s: [60, 80], b: [30, 50] }, { h: [338, 358], s: [70, 90], b: [40, 60] }, ], 'pond-glass': [ { h: [145, 175], s: [70, 90], b: [60, 80] }, { h: [178, 205], s: [80, 100], b: [70, 90] }, { h: [205, 225], s: [60, 80], b: [30, 50] }, { h: [95, 125], s: [70, 90], b: [40, 60] }, ], 'orchard-dusk': [ { h: [345, 360], s: [70, 90], b: [60, 80] }, { h: [0, 18], s: [80, 100], b: [70, 90] }, { h: [72, 100], s: [60, 80], b: [30, 50] }, { h: [275, 305], s: [70, 90], b: [40, 60] }, ], 'spring-border': [ { h: [328, 350], s: [70, 90], b: [60, 80] }, { h: [42, 62], s: [80, 100], b: [70, 90] }, { h: [92, 126], s: [60, 80], b: [30, 50] }, { h: [182, 208], s: [70, 90], b: [40, 60] }, ], 'wildflower-meadow': [ { h: [0, 18], s: [70, 90], b: [60, 80] }, { h: [202, 232], s: [80, 100], b: [70, 90] }, { h: [42, 58], s: [60, 80], b: [30, 50] }, { h: [262, 294], s: [70, 90], b: [40, 60] }, ], 'herb-garden': [ { h: [92, 118], s: [70, 90], b: [60, 80] }, { h: [70, 96], s: [80, 100], b: [70, 90] }, { h: [154, 184], s: [60, 80], b: [30, 50] }, { h: [242, 270], s: [70, 90], b: [40, 60] }, ], 'kitchen-garden': [ { h: [0, 14], s: [70, 90], b: [60, 80] }, { h: [104, 136], s: [80, 100], b: [70, 90] }, { h: [42, 60], s: [60, 80], b: [30, 50] }, { h: [274, 302], s: [70, 90], b: [40, 60] }, ], 'water-garden': [ { h: [328, 350], s: [70, 90], b: [60, 80] }, { h: [180, 210], s: [80, 100], b: [70, 90] }, { h: [72, 104], s: [60, 80], b: [30, 50] }, { h: [246, 276], s: [70, 90], b: [40, 60] }, ], 'rose-arbor': [ { h: [342, 360], s: [70, 90], b: [60, 80] }, { h: [8, 28], s: [80, 100], b: [70, 90] }, { h: [304, 332], s: [60, 80], b: [30, 50] }, { h: [88, 120], s: [70, 90], b: [40, 60] }, ], 'blush-garden': [ { h: [342, 358], s: [22, 38], b: [80, 96] }, { h: [12, 28], s: [24, 42], b: [82, 98] }, { h: [88, 112], s: [18, 34], b: [72, 90] }, { h: [252, 276], s: [20, 38], b: [76, 94] }, { h: [110, 134], s: [58, 78], b: [28, 52] }, { h: [330, 360], s: [5, 16], b: [6, 24] }, ], 'morning-border': [ { h: [44, 58], s: [20, 36], b: [84, 98] }, { h: [194, 212], s: [18, 34], b: [80, 96] }, { h: [132, 154], s: [16, 32], b: [76, 92] }, { h: [326, 344], s: [20, 38], b: [82, 97] }, { h: [126, 150], s: [60, 80], b: [26, 50] }, { h: [198, 222], s: [6, 18], b: [6, 22] }, ], 'hydrangea-mist': [ { h: [218, 238], s: [24, 42], b: [78, 94] }, { h: [268, 290], s: [20, 38], b: [80, 96] }, { h: [194, 214], s: [18, 34], b: [82, 98] }, { h: [316, 338], s: [20, 36], b: [78, 95] }, { h: [98, 126], s: [56, 76], b: [26, 50] }, { h: [242, 270], s: [8, 20], b: [6, 22] }, ], 'cottage-pastel': [ { h: [4, 18], s: [28, 46], b: [80, 96] }, { h: [44, 58], s: [22, 40], b: [82, 98] }, { h: [90, 114], s: [18, 34], b: [72, 90] }, { h: [204, 226], s: [24, 42], b: [76, 94] }, { h: [88, 118], s: [58, 78], b: [28, 52] }, { h: [0, 20], s: [5, 16], b: [6, 22] }, ], 'pressed-flowers': [ { h: [336, 352], s: [24, 42], b: [66, 84] }, { h: [36, 52], s: [28, 46], b: [70, 88] }, { h: [80, 104], s: [18, 34], b: [62, 80] }, { h: [262, 284], s: [22, 40], b: [66, 84] }, { h: [68, 94], s: [46, 66], b: [24, 46] }, { h: [248, 280], s: [4, 14], b: [5, 20] }, ], 'glasshouse-light': [ { h: [124, 150], s: [18, 34], b: [78, 94] }, { h: [174, 196], s: [18, 32], b: [82, 98] }, { h: [14, 30], s: [22, 40], b: [82, 98] }, { h: [254, 278], s: [20, 36], b: [78, 95] }, { h: [142, 166], s: [62, 82], b: [24, 48] }, { h: [178, 210], s: [5, 16], b: [5, 21] }, ], }; const gardenPaletteNames = Object.keys(gardenPalettes); const softGardenPaletteNames = new Set([ 'blush-garden', 'morning-border', 'hydrangea-mist', 'cottage-pastel', 'pressed-flowers', 'glasshouse-light', ]); const mixedGardenPaletteNames = new Set([ 'original-rose', 'original-water', ]); let colorPalette; let paletteName; let softPaletteActive = false; let mixedPaletteActive = false; let lightVector; let seed; const FALLBACK_SEED = 949032; const MAX_SEED = 999999; const DEFAULT_SIZE = 1000; const RENDER_PIXEL_DENSITY = 2; let WIDTH = window.innerWidth; let HEIGHT = window.innerHeight; let DIM = Math.min(WIDTH, HEIGHT); let M = DIM / DEFAULT_SIZE; function readArtworkSeed() { const raw = window.ARTSCRIPT_SEED ?? window.__TOKEN_STUDIO_SEED ?? new URLSearchParams(window.location.search).get('seed'); if (raw === undefined || raw === null || !/^[0-9]+$/.test(String(raw).trim())) { return FALLBACK_SEED; } return Number(BigInt(String(raw).trim()) % BigInt(MAX_SEED + 1)); } function selectPaletteName(nextSeed) { const requestedName = new URLSearchParams(window.location.search).get('palette'); if (requestedName && Object.hasOwn(gardenPalettes, requestedName)) { return requestedName; } return gardenPaletteNames[nextSeed % gardenPaletteNames.length]; } function setup() { document.body.style.margin = '0'; document.body.style.padding = '0'; document.body.style.overflow = 'hidden'; document.body.style.backgroundColor = '#111'; document.body.style.display = 'flex'; document.body.style.justifyContent = 'center'; document.body.style.alignItems = 'center'; document.body.style.height = '100vh'; DIM = Math.min(WIDTH, HEIGHT); const canvasSize = Math.max(1, Math.floor(DIM)); createCanvas(canvasSize, canvasSize); pixelDensity(RENDER_PIXEL_DENSITY); colorMode(HSB, 360, 100, 100, 100); angleMode(RADIANS); startGeneration(readArtworkSeed()); noLoop(); } function startGeneration(nextSeed) { seed = Number.isInteger(nextSeed) ? constrain(nextSeed, 0, MAX_SEED) : floor(random(1000000)); randomSeed(seed); noiseSeed(seed); if (width <= 0 || height <= 0) return; const gridStep = (DIM / baseGridDensity); const weaveSteps = baseWeaveSteps; const weaveSpeed = baseWeaveSpeed * M; const scaledBaseStrokeWidth = baseStrokeWidth * M; lightVector = p5.Vector.fromAngle(random(TWO_PI)); lightVector.normalize(); paletteName = selectPaletteName(seed); colorPalette = gardenPalettes[paletteName]; softPaletteActive = softGardenPaletteNames.has(paletteName); mixedPaletteActive = mixedGardenPaletteNames.has(paletteName); document.body.dataset.artSeed = String(seed); document.body.dataset.palette = paletteName; document.body.dataset.colorStyle = softPaletteActive ? 'soft' : mixedPaletteActive ? 'mixed' : 'legacy'; if (softPaletteActive) { background(100, 12, 13); } else if (mixedPaletteActive) { background(100, 24, 9); } else { background(100, 40, 10); } for (let y = 0; y < height; y += gridStep) { for (let x = 0; x < width; x += gridStep) { let currentPos = createVector(x, y); for (let i = 0; i < weaveSteps; i++) { let virtualX = currentPos.x / M; let virtualY = currentPos.y / M; let angle = noise(virtualX * angleNoiseScale, virtualY * angleNoiseScale) * TWO_PI * 3; let sizeFactor = noise(virtualX * sizeNoiseScale, virtualY * sizeNoiseScale); let shapeSize = map(sizeFactor, 0, 1, 2 * M, gridStep * 2.5); drawRecursiveShape(currentPos.x, currentPos.y, shapeSize, angle, recursionDepth, scaledBaseStrokeWidth); currentPos.x += cos(angle) * weaveSpeed; currentPos.y += sin(angle) * weaveSpeed; } } } applyGrain(); const infoDiv = document.querySelector('.info'); if (infoDiv) { infoDiv.innerHTML = `Seed: ${seed} | Palette: ${paletteName} | Press 's' to save.`; } notifyRendered(); } function notifyRendered() { if (typeof window.__TOKEN_STUDIO_NOTIFY !== 'function') return; window.requestAnimationFrame(() => { window.__TOKEN_STUDIO_NOTIFY('token-art:rendered'); }); } function drawRecursiveShape(x, y, size, angle, level, scaledStrokeWidth) { if (level <= 0 || size < 0.5 * M) return; push(); translate(x, y); rotate(angle); let normalVector = p5.Vector.fromAngle(angle); let lightDot = normalVector.dot(lightVector); let paletteIndex = floor(map(angle % TWO_PI, 0, TWO_PI, 0, colorPalette.length)); paletteIndex = constrain(paletteIndex, 0, colorPalette.length - 1); let selectedPalette = colorPalette[paletteIndex]; let hue = map(x, 0, width, selectedPalette.h[0], selectedPalette.h[1]); let hueShift = softPaletteActive ? map(lightDot, -1, 1, -8, 8) : mixedPaletteActive ? map(lightDot, -1, 1, -12, 12) : map(lightDot, -1, 1, -20, 20); hue = (hue + hueShift + 360) % 360; let saturation = 95; let brightness = map(lightDot, -1, 1, 40, 100); if (softPaletteActive || mixedPaletteActive) { saturation = map(x, 0, width, selectedPalette.s[0], selectedPalette.s[1]); brightness = map(lightDot, -1, 1, selectedPalette.b[0], selectedPalette.b[1]); } let sw = map(level, recursionDepth, 1, scaledStrokeWidth, scaledStrokeWidth * 0.1); strokeWeight(sw); let alpha = softPaletteActive ? map(lightDot, -1, 1, 22, 58) : mixedPaletteActive ? map(lightDot, -1, 1, 26, 68) : map(lightDot, -1, 1, 25, 70); stroke(hue, saturation, brightness, alpha); noFill(); rectMode(CENTER); rect(0, 0, size * 1.8, size, size * 0.3); let newSize = size * recursionFactor; let angleOffset = map(sin(angle), -1, 1, -QUARTER_PI, QUARTER_PI); let newAngle = angle + angleOffset; drawRecursiveShape(0, 0, newSize, newAngle, level - 1, scaledStrokeWidth); pop(); } function applyGrain() { loadPixels(); for (let i = 0; i < pixels.length; i += 4) { let grain = random(-grainAmount, grainAmount); pixels[i] = pixels[i] + grain; pixels[i + 1] = pixels[i + 1] + grain; pixels[i + 2] = pixels[i + 2] + grain; } updatePixels(); } function keyPressed() { if (key === 's' || key === 'S') { saveCanvas('In the Garden - ' + seed, 'png'); } } function windowResized() { WIDTH = window.innerWidth; HEIGHT = window.innerHeight; DIM = Math.min(WIDTH, HEIGHT); M = DIM / DEFAULT_SIZE; const canvasSize = Math.max(1, Math.floor(DIM)); resizeCanvas(canvasSize, canvasSize); startGeneration(seed); }