{ "format": "trakodag.web.presets", "version": 1, "name": "trakodag — artistic presets", "description": "Pamiątkowy zestaw efektów. Załaduj plik przez 'Load project' i wybierz preset z listy.", "presets": [ { "name": "Sepia Vintage", "description": "Ciepły sepia look + delikatna winieta — klasyczna pocztówka.", "layers": [ { "name": "sepia", "visible": true, "opacity": 1.0, "code": "// klasyczna macierz sepia\nforEach((x, y, p) => {\n const r = p.r * 0.393 + p.g * 0.769 + p.b * 0.189;\n const g = p.r * 0.349 + p.g * 0.686 + p.b * 0.168;\n const b = p.r * 0.272 + p.g * 0.534 + p.b * 0.131;\n p.r = clamp(r);\n p.g = clamp(g);\n p.b = clamp(b);\n});\n" }, { "name": "vignette", "visible": true, "opacity": 1.0, "code": "// ściemnienie krawędzi (radialne)\nconst cx = width / 2, cy = height / 2;\nconst maxD = hypot(cx, cy);\nforEach((x, y, p) => {\n const d = hypot(x - cx, y - cy) / maxD;\n const k = 1 - pow(d, 1.6) * 0.75;\n p.r = clamp(p.r * k);\n p.g = clamp(p.g * k);\n p.b = clamp(p.b * k);\n});\n" }, { "name": "grain", "visible": true, "opacity": 0.5, "code": "// drobne ziarno filmu\nforEach((x, y, p) => {\n const n = randomInt(-15, 15);\n p.r = clamp(p.r + n);\n p.g = clamp(p.g + n);\n p.b = clamp(p.b + n);\n});\n" } ] }, { "name": "CRT Scanlines", "description": "Stary monitor / TV — boost kolorów + poziome linie skanowania + lekkie cieplejsze tony.", "layers": [ { "name": "boost", "visible": true, "opacity": 1.0, "code": "// nasycenie i jasność jak na nasyconym CRT\nforEach((x, y, p) => {\n p.r = clamp(p.r * 1.12 + 4);\n p.g = clamp(p.g * 1.06 + 2);\n p.b = clamp(p.b * 1.10 + 4);\n});\n" }, { "name": "scanlines", "visible": true, "opacity": 1.0, "code": "// co druga linia ciemniejsza\nforEach((x, y, p) => {\n if (y % 2 === 0) {\n p.r = (p.r * 0.55) | 0;\n p.g = (p.g * 0.55) | 0;\n p.b = (p.b * 0.55) | 0;\n }\n});\n" }, { "name": "rgb mask", "visible": true, "opacity": 0.6, "code": "// maska RGB co 3 piksele w poziomie (jak fosfory)\nforEach((x, y, p) => {\n const m = x % 3;\n if (m === 0) { p.g = (p.g * 0.7) | 0; p.b = (p.b * 0.7) | 0; }\n else if (m === 1) { p.r = (p.r * 0.7) | 0; p.b = (p.b * 0.7) | 0; }\n else { p.r = (p.r * 0.7) | 0; p.g = (p.g * 0.7) | 0; }\n});\n" } ] }, { "name": "Cyberpunk Glitch", "description": "Losowe poziome przesunięcia + chromatyczna aberracja + neonowe ziarno.", "layers": [ { "name": "rgb split", "visible": true, "opacity": 1.0, "code": "// chromatic aberration — R w lewo, B w prawo\nconst shift = 6;\nforEach((x, y, p) => {\n const r = prev.getPixel(x - shift, y).r;\n const b = prev.getPixel(x + shift, y).b;\n p.r = r;\n p.b = b;\n});\n" }, { "name": "glitch slices", "visible": true, "opacity": 1.0, "code": "// losowe paski przesunięte w poziomie\nconst sliceCount = 30;\nfor (let s = 0; s < sliceCount; s++) {\n const yStart = randomInt(0, height - 1);\n const yEnd = min(height, yStart + randomInt(2, 14));\n const shift = randomInt(-40, 40);\n for (let y = yStart; y < yEnd; y++) {\n for (let x = 0; x < width; x++) {\n const sx = (x - shift + width) % width;\n const q = prev.getPixel(sx, y);\n setPixel(x, y, q.r, q.g, q.b, q.a);\n }\n }\n}\n" }, { "name": "neon tint", "visible": true, "opacity": 0.4, "code": "// fioletowo-cyjanowe przesunięcie kolorów\nforEach((x, y, p) => {\n p.r = clamp(p.r + 25);\n p.b = clamp(p.b + 35);\n});\n" } ] }, { "name": "Pixel Mosaic", "description": "Pikselizacja blokowa — z każdego bloku bierzemy kolor środka.", "layers": [ { "name": "mosaic", "visible": true, "opacity": 1.0, "code": "// rozmiar bloku w pikselach\nconst block = 14;\nfor (let y = 0; y < height; y += block) {\n for (let x = 0; x < width; x += block) {\n const c = prev.getPixel(x + (block >> 1), y + (block >> 1));\n for (let by = 0; by < block; by++) {\n for (let bx = 0; bx < block; bx++) {\n setPixel(x + bx, y + by, c.r, c.g, c.b, c.a);\n }\n }\n }\n}\n" } ] }, { "name": "Neon Edges", "description": "Wyciągnięcie krawędzi przez różnicę sąsiadów + mocne kolory na czarnym tle.", "layers": [ { "name": "edges", "visible": true, "opacity": 1.0, "code": "// |sąsiad - piksel| dla każdego kanału\nforEach((x, y, p) => {\n const a = prev.getPixel(x, y);\n const b = prev.getPixel(x + 1, y);\n const c = prev.getPixel(x, y + 1);\n p.r = clamp((abs(a.r - b.r) + abs(a.r - c.r)) * 3);\n p.g = clamp((abs(a.g - b.g) + abs(a.g - c.g)) * 3);\n p.b = clamp((abs(a.b - b.b) + abs(a.b - c.b)) * 3);\n});\n" }, { "name": "neon boost", "visible": true, "opacity": 1.0, "code": "// gdziekolwiek jest jakaś krawędź — pompuj nasycenie\nforEach((x, y, p) => {\n const m = max(p.r, max(p.g, p.b));\n if (m > 30) {\n p.r = clamp(p.r * 1.6);\n p.g = clamp(p.g * 1.6);\n p.b = clamp(p.b * 1.6);\n }\n});\n" } ] }, { "name": "Dream Wave", "description": "Sinusoidalne falowanie + pastelowe rozmycie — łagodny, oniryczny look.", "layers": [ { "name": "wave", "visible": true, "opacity": 1.0, "code": "// poziome i pionowe falowanie\nfor (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n const dx = floor(sin(y * 0.04) * 10);\n const dy = floor(cos(x * 0.04) * 6);\n const p = prev.getPixel((x + dx + width) % width, (y + dy + height) % height);\n setPixel(x, y, p.r, p.g, p.b, p.a);\n }\n}\n" }, { "name": "soft glow", "visible": true, "opacity": 0.55, "code": "// fake-blur: średnia z 4 losowych sąsiadów (tanie i działa)\nforEach((x, y, p) => {\n let r = 0, g = 0, b = 0;\n for (let i = 0; i < 4; i++) {\n const q = prev.getPixel(x + randomInt(-3, 3), y + randomInt(-3, 3));\n r += q.r; g += q.g; b += q.b;\n }\n p.r = (r >> 2);\n p.g = (g >> 2);\n p.b = (b >> 2);\n});\n" }, { "name": "pastel lift", "visible": true, "opacity": 0.6, "code": "// dodaj odrobinę bieli, żeby wybielić cienie\nforEach((x, y, p) => {\n p.r = clamp(p.r + 30);\n p.g = clamp(p.g + 35);\n p.b = clamp(p.b + 40);\n});\n" } ] }, { "name": "Posterize Pop", "description": "Redukcja palety (5 poziomów na kanał) + boost nasycenia — pop-art.", "layers": [ { "name": "posterize", "visible": true, "opacity": 1.0, "code": "// kwantyzacja kolorów\nconst levels = 5;\nconst step = 255 / (levels - 1);\nforEach((x, y, p) => {\n p.r = round(p.r / step) * step;\n p.g = round(p.g / step) * step;\n p.b = round(p.b / step) * step;\n});\n" }, { "name": "saturate", "visible": true, "opacity": 1.0, "code": "// proste wzmocnienie nasycenia względem szarości\nforEach((x, y, p) => {\n const gray = (p.r + p.g + p.b) / 3;\n p.r = clamp(gray + (p.r - gray) * 1.6);\n p.g = clamp(gray + (p.g - gray) * 1.6);\n p.b = clamp(gray + (p.b - gray) * 1.6);\n});\n" } ] }, { "name": "Film Noir", "description": "Twarda czerń i biel z mocnym kontrastem + ziarno.", "layers": [ { "name": "grayscale", "visible": true, "opacity": 1.0, "code": "// luminancja BT.601\nforEach((x, y, p) => {\n const g = (p.r * 0.299 + p.g * 0.587 + p.b * 0.114) | 0;\n p.r = p.g = p.b = g;\n});\n" }, { "name": "contrast", "visible": true, "opacity": 1.0, "code": "// rozciągnięcie kontrastu wokół 128\nforEach((x, y, p) => {\n const v = clamp((p.r - 128) * 1.7 + 128);\n p.r = p.g = p.b = v;\n});\n" }, { "name": "grain", "visible": true, "opacity": 0.7, "code": "// mocniejsze ziarno niż w sepii\nforEach((x, y, p) => {\n const n = randomInt(-25, 25);\n p.r = clamp(p.r + n);\n p.g = clamp(p.g + n);\n p.b = clamp(p.b + n);\n});\n" } ] }, { "name": "Static Storm", "description": "Burza statyki — losowe punkty białego/czarnego szumu rozsypane po obrazie.", "layers": [ { "name": "noise sprinkle", "visible": true, "opacity": 1.0, "code": "// 8% pikseli — biały szum, 4% czarny\nforEach((x, y, p) => {\n const r = random1();\n if (r < 0.08) {\n const v = random256();\n p.r = p.g = p.b = v;\n } else if (r < 0.12) {\n p.r = p.g = p.b = 0;\n }\n});\n" }, { "name": "horizontal lines", "visible": true, "opacity": 0.6, "code": "// losowe całe linie do bieli\nfor (let i = 0; i < 6; i++) {\n const y = randomInt(0, height - 1);\n for (let x = 0; x < width; x++) {\n setPixel(x, y, 220, 220, 220, 255);\n }\n}\n" } ] }, { "name": "Mirror Kaleidoscope", "description": "Pionowe lustro + przesunięcie sinusoidalne — efekt kalejdoskopu.", "layers": [ { "name": "mirror", "visible": true, "opacity": 1.0, "code": "// odbijamy lewą połówkę na prawą\nfor (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n const sx = x < width / 2 ? x : (width - 1 - x);\n const q = prev.getPixel(sx, y);\n setPixel(x, y, q.r, q.g, q.b, q.a);\n }\n}\n" }, { "name": "sine flow", "visible": true, "opacity": 1.0, "code": "// powolny przepływ\nfor (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n const dx = floor(sin(y * 0.08) * 18);\n const q = prev.getPixel((x + dx + width) % width, y);\n setPixel(x, y, q.r, q.g, q.b, q.a);\n }\n}\n" } ] } ] }