@firecms/neat 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/NeatGradient.d.ts +7 -0
- package/dist/NeatGradient.js +61 -32
- package/dist/NeatGradient.js.map +1 -1
- package/dist/index.es.js +95 -75
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +34 -35
- package/dist/index.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/NeatGradient.ts +70 -32
package/src/NeatGradient.ts
CHANGED
|
@@ -34,10 +34,12 @@ export type NeatConfig = {
|
|
|
34
34
|
colorBlending?: number;
|
|
35
35
|
grainScale?: number;
|
|
36
36
|
grainIntensity?: number;
|
|
37
|
+
grainSparsity?: number;
|
|
37
38
|
grainSpeed?: number;
|
|
38
39
|
wireframe?: boolean;
|
|
39
40
|
backgroundColor?: string;
|
|
40
41
|
backgroundAlpha?: number;
|
|
42
|
+
yOffset?: number;
|
|
41
43
|
};
|
|
42
44
|
|
|
43
45
|
export type NeatColor = {
|
|
@@ -73,6 +75,7 @@ export class NeatGradient implements NeatController {
|
|
|
73
75
|
|
|
74
76
|
private _grainScale: number = -1;
|
|
75
77
|
private _grainIntensity: number = -1;
|
|
78
|
+
private _grainSparsity: number = -1;
|
|
76
79
|
private _grainSpeed: number = -1;
|
|
77
80
|
|
|
78
81
|
private _colorBlending: number = -1;
|
|
@@ -87,6 +90,8 @@ export class NeatGradient implements NeatController {
|
|
|
87
90
|
private sizeObserver: ResizeObserver;
|
|
88
91
|
private sceneState: SceneState;
|
|
89
92
|
|
|
93
|
+
private _yOffset: number = 0;
|
|
94
|
+
|
|
90
95
|
constructor(config: NeatConfig & { ref: HTMLCanvasElement, resolution?: number, seed?: number }) {
|
|
91
96
|
|
|
92
97
|
const {
|
|
@@ -105,12 +110,14 @@ export class NeatGradient implements NeatController {
|
|
|
105
110
|
colorBlending = 5,
|
|
106
111
|
grainScale = 2,
|
|
107
112
|
grainIntensity = 0.55,
|
|
113
|
+
grainSparsity = 0.0,
|
|
108
114
|
grainSpeed = 0.1,
|
|
109
115
|
wireframe = false,
|
|
110
116
|
backgroundColor = "#FFFFFF",
|
|
111
117
|
backgroundAlpha = 1.0,
|
|
112
118
|
resolution = 1,
|
|
113
|
-
seed
|
|
119
|
+
seed,
|
|
120
|
+
yOffset = 0
|
|
114
121
|
} = config;
|
|
115
122
|
|
|
116
123
|
|
|
@@ -129,6 +136,7 @@ export class NeatGradient implements NeatController {
|
|
|
129
136
|
this.colorBlending = colorBlending;
|
|
130
137
|
this.grainScale = grainScale;
|
|
131
138
|
this.grainIntensity = grainIntensity;
|
|
139
|
+
this.grainSparsity = grainSparsity;
|
|
132
140
|
this.grainSpeed = grainSpeed;
|
|
133
141
|
this.colors = colors;
|
|
134
142
|
this.shadows = shadows;
|
|
@@ -138,6 +146,7 @@ export class NeatGradient implements NeatController {
|
|
|
138
146
|
this.wireframe = wireframe;
|
|
139
147
|
this.backgroundColor = backgroundColor;
|
|
140
148
|
this.backgroundAlpha = backgroundAlpha;
|
|
149
|
+
this.yOffset = yOffset;
|
|
141
150
|
|
|
142
151
|
this.sceneState = this._initScene(resolution);
|
|
143
152
|
|
|
@@ -205,10 +214,14 @@ export class NeatGradient implements NeatController {
|
|
|
205
214
|
// @ts-ignore
|
|
206
215
|
mesh.material.uniforms.u_grain_intensity = { value: this._grainIntensity };
|
|
207
216
|
// @ts-ignore
|
|
217
|
+
mesh.material.uniforms.u_grain_sparsity = { value: this._grainSparsity };
|
|
218
|
+
// @ts-ignore
|
|
208
219
|
mesh.material.uniforms.u_grain_speed = { value: this._grainSpeed };
|
|
209
220
|
// @ts-ignore
|
|
210
221
|
mesh.material.uniforms.u_grain_scale = { value: this._grainScale };
|
|
211
222
|
// @ts-ignore
|
|
223
|
+
mesh.material.uniforms.u_y_offset = { value: this._yOffset };
|
|
224
|
+
// @ts-ignore
|
|
212
225
|
mesh.material.wireframe = this._wireframe;
|
|
213
226
|
});
|
|
214
227
|
|
|
@@ -244,6 +257,13 @@ export class NeatGradient implements NeatController {
|
|
|
244
257
|
}
|
|
245
258
|
}
|
|
246
259
|
|
|
260
|
+
downloadAsPNG(filename = "neat.png") {
|
|
261
|
+
console.log("Downloading as PNG", this._ref);
|
|
262
|
+
const dataURL = this._ref.toDataURL("image/png");
|
|
263
|
+
console.log("data", dataURL);
|
|
264
|
+
downloadURI(dataURL, filename);
|
|
265
|
+
}
|
|
266
|
+
|
|
247
267
|
set speed(speed: number) {
|
|
248
268
|
this._speed = speed / 20;
|
|
249
269
|
}
|
|
@@ -300,6 +320,10 @@ export class NeatGradient implements NeatController {
|
|
|
300
320
|
this._grainIntensity = grainIntensity;
|
|
301
321
|
}
|
|
302
322
|
|
|
323
|
+
set grainSparsity(grainSparsity: number) {
|
|
324
|
+
this._grainSparsity = grainSparsity;
|
|
325
|
+
}
|
|
326
|
+
|
|
303
327
|
set grainSpeed(grainSpeed: number) {
|
|
304
328
|
this._grainSpeed = grainSpeed;
|
|
305
329
|
}
|
|
@@ -320,6 +344,10 @@ export class NeatGradient implements NeatController {
|
|
|
320
344
|
this._backgroundAlpha = backgroundAlpha;
|
|
321
345
|
}
|
|
322
346
|
|
|
347
|
+
set yOffset(yOffset: number) {
|
|
348
|
+
this._yOffset = yOffset;
|
|
349
|
+
}
|
|
350
|
+
|
|
323
351
|
_initScene(resolution: number): SceneState {
|
|
324
352
|
|
|
325
353
|
const width = this._ref.width,
|
|
@@ -328,6 +356,7 @@ export class NeatGradient implements NeatController {
|
|
|
328
356
|
const renderer = new THREE.WebGLRenderer({
|
|
329
357
|
// antialias: true,
|
|
330
358
|
alpha: true,
|
|
359
|
+
preserveDrawingBuffer: true,
|
|
331
360
|
canvas: this._ref
|
|
332
361
|
});
|
|
333
362
|
|
|
@@ -389,6 +418,7 @@ export class NeatGradient implements NeatController {
|
|
|
389
418
|
u_shadows: { value: this._shadows },
|
|
390
419
|
u_highlights: { value: this._highlights },
|
|
391
420
|
u_grain_intensity: { value: this._grainIntensity },
|
|
421
|
+
u_grain_sparsity: { value: this._grainSparsity },
|
|
392
422
|
u_grain_scale: { value: this._grainScale },
|
|
393
423
|
u_grain_speed: { value: this._grainSpeed },
|
|
394
424
|
};
|
|
@@ -455,26 +485,31 @@ void main() {
|
|
|
455
485
|
u_wave_frequency_y * position.y + u_time,
|
|
456
486
|
u_time
|
|
457
487
|
));
|
|
458
|
-
|
|
488
|
+
|
|
459
489
|
vec3 color;
|
|
460
490
|
|
|
461
491
|
// float t = mod(u_base_color, 100.0);
|
|
462
492
|
color = u_colors[0].color;
|
|
463
|
-
|
|
493
|
+
|
|
494
|
+
// Apply y_offset to the noise coordinates
|
|
464
495
|
vec2 noise_cord = vUv * u_color_pressure;
|
|
465
|
-
|
|
496
|
+
// Apply the y-offset to shift the pattern vertically (1:1 pixel ratio)
|
|
497
|
+
// Scale the offset to match the UV coordinate space
|
|
498
|
+
float scaledOffset = u_y_offset / u_resolution.y;
|
|
499
|
+
noise_cord.y -= scaledOffset;
|
|
500
|
+
|
|
466
501
|
const float minNoise = .0;
|
|
467
502
|
const float maxNoise = .9;
|
|
468
|
-
|
|
503
|
+
|
|
469
504
|
for (int i = 1; i < u_colors_count; i++) {
|
|
470
|
-
|
|
505
|
+
|
|
471
506
|
if(u_colors[i].is_active == 1.0){
|
|
472
507
|
float noiseFlow = (1. + float(i)) / 30.;
|
|
473
508
|
float noiseSpeed = (1. + float(i)) * 0.11;
|
|
474
509
|
float noiseSeed = 13. + float(i) * 7.;
|
|
475
|
-
|
|
510
|
+
|
|
476
511
|
int reverseIndex = u_colors_count - i;
|
|
477
|
-
|
|
512
|
+
|
|
478
513
|
float noise = snoise(
|
|
479
514
|
vec3(
|
|
480
515
|
noise_cord.x * u_color_pressure.x + u_time * noiseFlow * 2.,
|
|
@@ -482,25 +517,18 @@ void main() {
|
|
|
482
517
|
u_time * noiseSpeed
|
|
483
518
|
) + noiseSeed
|
|
484
519
|
) - (.1 * float(i)) + (.5 * u_color_blending);
|
|
485
|
-
|
|
520
|
+
|
|
486
521
|
noise = clamp(minNoise, maxNoise + float(i) * 0.02, noise);
|
|
487
522
|
vec3 nextColor = u_colors[i].color;
|
|
488
523
|
color = mix(color, nextColor, smoothstep(0.0, u_color_blending, noise));
|
|
489
|
-
|
|
490
|
-
// vec3 colorOklab = oklab2rgb(color);
|
|
491
|
-
// vec3 nextColorOklab = oklab2rgb(nextColor);
|
|
492
|
-
// vec3 mixColor = mix(colorOklab, nextColorOklab, smoothstep(0.0, u_color_blending, noise));
|
|
493
|
-
// color = rgb2oklab(mixColor);
|
|
494
|
-
|
|
495
524
|
}
|
|
496
|
-
|
|
497
525
|
}
|
|
498
|
-
|
|
526
|
+
|
|
499
527
|
v_color = color;
|
|
500
|
-
|
|
528
|
+
|
|
501
529
|
vec3 newPosition = position + normal * v_displacement_amount * u_wave_amplitude;
|
|
502
|
-
gl_Position = projectionMatrix * modelViewMatrix * vec4(
|
|
503
|
-
|
|
530
|
+
gl_Position = projectionMatrix * modelViewMatrix * vec4(newPosition, 1.0);
|
|
531
|
+
|
|
504
532
|
v_new_position = gl_Position;
|
|
505
533
|
}
|
|
506
534
|
`;
|
|
@@ -516,7 +544,6 @@ float fbm(vec3 x) {
|
|
|
516
544
|
float value = 0.0;
|
|
517
545
|
float amplitude = 0.5;
|
|
518
546
|
float frequency = 1.0;
|
|
519
|
-
|
|
520
547
|
for (int i = 0; i < 4; i++) {
|
|
521
548
|
value += amplitude * snoise(x * frequency);
|
|
522
549
|
frequency *= 2.0;
|
|
@@ -524,35 +551,34 @@ float fbm(vec3 x) {
|
|
|
524
551
|
}
|
|
525
552
|
return value;
|
|
526
553
|
}
|
|
527
|
-
|
|
528
|
-
void main(){
|
|
554
|
+
|
|
555
|
+
void main() {
|
|
529
556
|
vec3 color = v_color;
|
|
530
|
-
|
|
531
557
|
color += pow(v_displacement_amount, 1.0) * u_highlights;
|
|
532
558
|
color -= pow(1.0 - v_displacement_amount, 2.0) * u_shadows;
|
|
533
559
|
color = saturation(color, 1.0 + u_saturation);
|
|
534
560
|
color = color * u_brightness;
|
|
535
|
-
|
|
561
|
+
|
|
536
562
|
// Generate grain using fbm
|
|
537
563
|
vec2 noiseCoords = gl_FragCoord.xy / u_grain_scale;
|
|
538
|
-
|
|
539
|
-
float grain = (u_grain_speed != 0.0)
|
|
540
|
-
? fbm(vec3(noiseCoords, u_time * u_grain_speed))
|
|
541
|
-
: fbm(vec3(noiseCoords, 0.0));
|
|
564
|
+
float grain = (u_grain_speed != 0.0) ? fbm(vec3(noiseCoords, u_time * u_grain_speed)) : fbm(vec3(noiseCoords, 0.0));
|
|
542
565
|
|
|
543
566
|
// Center the grain around zero
|
|
544
567
|
grain = grain * 0.5 + 0.5;
|
|
545
568
|
grain -= 0.5;
|
|
546
569
|
|
|
570
|
+
// Add sparsity control
|
|
571
|
+
grain = (grain > u_grain_sparsity) ? grain : 0.0;
|
|
572
|
+
|
|
547
573
|
// Apply grain intensity
|
|
548
574
|
grain *= u_grain_intensity;
|
|
549
575
|
|
|
550
576
|
// Add grain to color
|
|
551
577
|
color += vec3(grain);
|
|
552
|
-
|
|
553
|
-
gl_FragColor = vec4(color,1.0);
|
|
578
|
+
|
|
579
|
+
gl_FragColor = vec4(color, 1.0);
|
|
554
580
|
}
|
|
555
|
-
`;
|
|
581
|
+
`;
|
|
556
582
|
}
|
|
557
583
|
|
|
558
584
|
const buildUniforms = () => `
|
|
@@ -565,6 +591,7 @@ struct Color {
|
|
|
565
591
|
};
|
|
566
592
|
|
|
567
593
|
uniform float u_grain_intensity;
|
|
594
|
+
uniform float u_grain_sparsity;
|
|
568
595
|
uniform float u_grain_scale;
|
|
569
596
|
uniform float u_grain_speed;
|
|
570
597
|
uniform float u_time;
|
|
@@ -589,6 +616,8 @@ uniform int u_colors_count;
|
|
|
589
616
|
uniform Color u_colors[5];
|
|
590
617
|
uniform vec2 u_resolution;
|
|
591
618
|
|
|
619
|
+
uniform float u_y_offset;
|
|
620
|
+
|
|
592
621
|
varying vec2 vUv;
|
|
593
622
|
varying vec4 v_new_position;
|
|
594
623
|
varying vec3 v_color;
|
|
@@ -904,3 +933,12 @@ function generateRandomString(length: number = 6): string {
|
|
|
904
933
|
}
|
|
905
934
|
return result;
|
|
906
935
|
}
|
|
936
|
+
|
|
937
|
+
function downloadURI(uri: string, name: string) {
|
|
938
|
+
const link = document.createElement("a");
|
|
939
|
+
link.download = name;
|
|
940
|
+
link.href = uri;
|
|
941
|
+
document.body.appendChild(link);
|
|
942
|
+
link.click();
|
|
943
|
+
document.body.removeChild(link);
|
|
944
|
+
}
|