@johnfmorton/some-shade 0.1.2-beta → 1.0.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/README.md +100 -19
- package/dist/some-shade.cjs.js +40 -13
- package/dist/some-shade.es.js +177 -144
- package/dist/some-shade.umd.js +41 -14
- package/package.json +1 -1
- package/dist/index.d.ts +0 -78
package/README.md
CHANGED
|
@@ -27,9 +27,9 @@ npm install @johnfmorton/some-shade
|
|
|
27
27
|
|
|
28
28
|
## Effects
|
|
29
29
|
|
|
30
|
-
### CMYK Halftone
|
|
30
|
+
### CMYK Halftone (`halftone-cmyk`)
|
|
31
31
|
|
|
32
|
-
Simulates a CMYK halftone print screen with per-channel angle control.
|
|
32
|
+
Simulates a CMYK halftone print screen with per-channel angle control, visibility toggles, and black channel intensity.
|
|
33
33
|
|
|
34
34
|
```html
|
|
35
35
|
<some-shade-image
|
|
@@ -41,10 +41,15 @@ Simulates a CMYK halftone print screen with per-channel angle control.
|
|
|
41
41
|
angle-m="75"
|
|
42
42
|
angle-y="0"
|
|
43
43
|
angle-k="45"
|
|
44
|
+
show-c="1"
|
|
45
|
+
show-m="1"
|
|
46
|
+
show-y="1"
|
|
47
|
+
show-k="1"
|
|
48
|
+
intensity-k="1"
|
|
44
49
|
></some-shade-image>
|
|
45
50
|
```
|
|
46
51
|
|
|
47
|
-
### Duotone Halftone
|
|
52
|
+
### Duotone Halftone (`halftone-duotone`)
|
|
48
53
|
|
|
49
54
|
Halftone effect using a single custom color.
|
|
50
55
|
|
|
@@ -59,7 +64,7 @@ Halftone effect using a single custom color.
|
|
|
59
64
|
></some-shade-image>
|
|
60
65
|
```
|
|
61
66
|
|
|
62
|
-
### Dot Grid
|
|
67
|
+
### Dot Grid (`dot-grid`)
|
|
63
68
|
|
|
64
69
|
Renders the image as a grid of dots with a customizable background.
|
|
65
70
|
|
|
@@ -72,26 +77,102 @@ Renders the image as a grid of dots with a customizable background.
|
|
|
72
77
|
dot-offset-x="0.5"
|
|
73
78
|
dot-offset-y="0.5"
|
|
74
79
|
bg-color="#ffffff"
|
|
80
|
+
angle="0"
|
|
81
|
+
></some-shade-image>
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### 2-Strip Technicolor (`technicolor-2strip`)
|
|
85
|
+
|
|
86
|
+
Simulates the early two-strip Technicolor film process with warm and cool dye channels plus a black (K) channel for detail. Choose between three blend modes for different color mixing behavior.
|
|
87
|
+
|
|
88
|
+
```html
|
|
89
|
+
<some-shade-image
|
|
90
|
+
src="photo.jpg"
|
|
91
|
+
effect="technicolor-2strip"
|
|
92
|
+
dot-radius="7"
|
|
93
|
+
grid-size="10"
|
|
94
|
+
angle-warm="15"
|
|
95
|
+
angle-cool="75"
|
|
96
|
+
angle-k="45"
|
|
97
|
+
show-warm="1"
|
|
98
|
+
show-cool="1"
|
|
99
|
+
show-k="1"
|
|
100
|
+
warm-color="#d94010"
|
|
101
|
+
cool-color="#0da699"
|
|
102
|
+
blend-mode="1"
|
|
103
|
+
intensity-k="1"
|
|
75
104
|
></some-shade-image>
|
|
76
105
|
```
|
|
77
106
|
|
|
107
|
+
**Blend modes:** `0` = Subtractive (dye overlap darkens), `1` = Additive (light overlap brightens), `2` = Screen (soft additive clamping).
|
|
108
|
+
|
|
78
109
|
## Attributes Reference
|
|
79
110
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
|
83
|
-
|
|
84
|
-
| `
|
|
85
|
-
| `
|
|
86
|
-
| `
|
|
87
|
-
| `
|
|
88
|
-
| `
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
|
93
|
-
|
|
94
|
-
| `
|
|
111
|
+
### Universal
|
|
112
|
+
|
|
113
|
+
| Attribute | Type | Default | Description |
|
|
114
|
+
|-----------|------|---------|-------------|
|
|
115
|
+
| `src` | string | `""` | Image source URL |
|
|
116
|
+
| `effect` | string | `"halftone-cmyk"` | Active effect name |
|
|
117
|
+
| `dot-radius` | number | `4` | Dot radius in pixels |
|
|
118
|
+
| `grid-size` | number | `8` | Grid cell size in pixels |
|
|
119
|
+
| `loading-blur` | number | `0` | Blur (px) applied to the source image while the effect renders |
|
|
120
|
+
|
|
121
|
+
### CMYK Halftone
|
|
122
|
+
|
|
123
|
+
| Attribute | Type | Default | Description |
|
|
124
|
+
|-----------|------|---------|-------------|
|
|
125
|
+
| `angle-c` | number | `15` | Cyan channel angle (degrees) |
|
|
126
|
+
| `angle-m` | number | `75` | Magenta channel angle (degrees) |
|
|
127
|
+
| `angle-y` | number | `0` | Yellow channel angle (degrees) |
|
|
128
|
+
| `angle-k` | number | `45` | Black channel angle (degrees) |
|
|
129
|
+
| `show-c` | number | `1` | Show cyan channel (0 or 1) |
|
|
130
|
+
| `show-m` | number | `1` | Show magenta channel (0 or 1) |
|
|
131
|
+
| `show-y` | number | `1` | Show yellow channel (0 or 1) |
|
|
132
|
+
| `show-k` | number | `1` | Show black channel (0 or 1) |
|
|
133
|
+
| `intensity-k` | number | `1` | Black channel intensity multiplier (0–2) |
|
|
134
|
+
|
|
135
|
+
### Duotone Halftone
|
|
136
|
+
|
|
137
|
+
| Attribute | Type | Default | Description |
|
|
138
|
+
|-----------|------|---------|-------------|
|
|
139
|
+
| `duotone-color` | string | `"#0099cc"` | Highlight color (hex) |
|
|
140
|
+
| `angle` | number | `0` | Grid angle (degrees) |
|
|
141
|
+
|
|
142
|
+
### Dot Grid
|
|
143
|
+
|
|
144
|
+
| Attribute | Type | Default | Description |
|
|
145
|
+
|-----------|------|---------|-------------|
|
|
146
|
+
| `dot-offset-x` | number | `0.5` | Horizontal dot offset (0–1) |
|
|
147
|
+
| `dot-offset-y` | number | `0.5` | Vertical dot offset (0–1) |
|
|
148
|
+
| `bg-color` | string | `"#ffffff"` | Background color (hex) |
|
|
149
|
+
| `angle` | number | `0` | Grid angle (degrees) |
|
|
150
|
+
|
|
151
|
+
### 2-Strip Technicolor
|
|
152
|
+
|
|
153
|
+
| Attribute | Type | Default | Description |
|
|
154
|
+
|-----------|------|---------|-------------|
|
|
155
|
+
| `angle-warm` | number | `15` | Warm channel angle (degrees) |
|
|
156
|
+
| `angle-cool` | number | `75` | Cool channel angle (degrees) |
|
|
157
|
+
| `angle-k` | number | `45` | Black channel angle (degrees) |
|
|
158
|
+
| `show-warm` | number | `1` | Show warm channel (0 or 1) |
|
|
159
|
+
| `show-cool` | number | `1` | Show cool channel (0 or 1) |
|
|
160
|
+
| `show-k` | number | `1` | Show black channel (0 or 1) |
|
|
161
|
+
| `warm-color` | string | `"#d94010"` | Warm dye color (hex) |
|
|
162
|
+
| `cool-color` | string | `"#0da699"` | Cool dye color (hex) |
|
|
163
|
+
| `blend-mode` | number | `1` | Blend mode: 0 = Subtractive, 1 = Additive, 2 = Screen |
|
|
164
|
+
| `intensity-k` | number | `1` | Black channel intensity multiplier (0–2) |
|
|
165
|
+
|
|
166
|
+
## Methods
|
|
167
|
+
|
|
168
|
+
### `replayTransition(delay?: number)`
|
|
169
|
+
|
|
170
|
+
Hides the rendered snapshot and fades it back in after a delay. Useful for previewing the loading blur transition.
|
|
171
|
+
|
|
172
|
+
```js
|
|
173
|
+
const el = document.querySelector('some-shade-image');
|
|
174
|
+
el.replayTransition(500);
|
|
175
|
+
```
|
|
95
176
|
|
|
96
177
|
## Framework Usage
|
|
97
178
|
|
package/dist/some-shade.cjs.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const _=require("lit"),l=require("lit/decorators.js");function k(t){return t.getContext("webgl",{alpha:!0,premultipliedAlpha:!1,preserveDrawingBuffer:!0})}function E(t,o,r){const i=t.createShader(o);if(!i)throw new Error("Failed to create shader");if(t.shaderSource(i,r),t.compileShader(i),!t.getShaderParameter(i,t.COMPILE_STATUS)){const e=t.getShaderInfoLog(i);throw t.deleteShader(i),new Error(`Shader compile error: ${e}`)}return i}function
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const _=require("lit"),l=require("lit/decorators.js");function k(t){return t.getContext("webgl",{alpha:!0,premultipliedAlpha:!1,preserveDrawingBuffer:!0})}function E(t,o,r){const i=t.createShader(o);if(!i)throw new Error("Failed to create shader");if(t.shaderSource(i,r),t.compileShader(i),!t.getShaderParameter(i,t.COMPILE_STATUS)){const e=t.getShaderInfoLog(i);throw t.deleteShader(i),new Error(`Shader compile error: ${e}`)}return i}function D(t,o,r){const i=E(t,t.VERTEX_SHADER,o),e=E(t,t.FRAGMENT_SHADER,r),n=t.createProgram();if(!n)throw new Error("Failed to create program");if(t.attachShader(n,i),t.attachShader(n,e),t.linkProgram(n),!t.getProgramParameter(n,t.LINK_STATUS)){const d=t.getProgramInfoLog(n);throw t.deleteProgram(n),new Error(`Program link error: ${d}`)}t.deleteShader(i),t.deleteShader(e);const c=new Map,h=t.getProgramParameter(n,t.ACTIVE_ATTRIBUTES);for(let d=0;d<h;d++){const f=t.getActiveAttrib(n,d);f&&c.set(f.name,t.getAttribLocation(n,f.name))}const s=new Map,g=t.getProgramParameter(n,t.ACTIVE_UNIFORMS);for(let d=0;d<g;d++){const f=t.getActiveUniform(n,d);if(f){const m=t.getUniformLocation(n,f.name);m&&s.set(f.name,m)}}return{program:n,attribLocations:c,uniformLocations:s}}function L(t,o,r){for(const[i,e]of Object.entries(r)){const n=o.uniformLocations.get(i);if(n){if(typeof e=="number")t.uniform1f(n,e);else if(Array.isArray(e))switch(e.length){case 2:t.uniform2fv(n,e);break;case 3:t.uniform3fv(n,e);break;case 4:t.uniform4fv(n,e);break}}}}function z(t,o){const r=t.createTexture();if(!r)throw new Error("Failed to create texture");return t.bindTexture(t.TEXTURE_2D,r),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,t.RGBA,t.UNSIGNED_BYTE,o),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.LINEAR),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.LINEAR),{texture:r,width:o.naturalWidth,height:o.naturalHeight}}function M(t,o){const r=new Float32Array([-1,-1,0,1,1,-1,1,1,-1,1,0,0,1,1,1,0]),i=t.createBuffer();if(!i)throw new Error("Failed to create buffer");t.bindBuffer(t.ARRAY_BUFFER,i),t.bufferData(t.ARRAY_BUFFER,r,t.STATIC_DRAW);const e=4*Float32Array.BYTES_PER_ELEMENT,n=o.attribLocations.get("a_position");n!==void 0&&n!==-1&&(t.enableVertexAttribArray(n),t.vertexAttribPointer(n,2,t.FLOAT,!1,e,0));const c=o.attribLocations.get("a_texCoord");return c!==void 0&&c!==-1&&(t.enableVertexAttribArray(c),t.vertexAttribPointer(c,2,t.FLOAT,!1,e,2*Float32Array.BYTES_PER_ELEMENT)),i}function P(t){t.drawArrays(t.TRIANGLE_STRIP,0,4)}const O=`precision mediump float;
|
|
2
2
|
|
|
3
3
|
varying vec2 v_texCoord;
|
|
4
4
|
|
|
@@ -92,7 +92,7 @@ void main() {
|
|
|
92
92
|
gl_Position = vec4(a_position, 0.0, 1.0);
|
|
93
93
|
v_texCoord = a_texCoord;
|
|
94
94
|
}
|
|
95
|
-
`,
|
|
95
|
+
`,I={name:"halftone-cmyk",fragmentShader:O,vertexShader:y,uniforms:[{name:"u_dotRadius",type:"float",default:4,attribute:"dot-radius"},{name:"u_gridSize",type:"float",default:8,attribute:"grid-size"},{name:"u_angleC",type:"float",default:15,attribute:"angle-c"},{name:"u_angleM",type:"float",default:75,attribute:"angle-m"},{name:"u_angleY",type:"float",default:0,attribute:"angle-y"},{name:"u_angleK",type:"float",default:45,attribute:"angle-k"},{name:"u_showC",type:"float",default:1,attribute:"show-c"},{name:"u_showM",type:"float",default:1,attribute:"show-m"},{name:"u_showY",type:"float",default:1,attribute:"show-y"},{name:"u_showK",type:"float",default:1,attribute:"show-k"},{name:"u_intensityK",type:"float",default:1,attribute:"intensity-k"}]},V=`precision mediump float;
|
|
96
96
|
|
|
97
97
|
varying vec2 v_texCoord;
|
|
98
98
|
|
|
@@ -134,7 +134,7 @@ void main() {
|
|
|
134
134
|
|
|
135
135
|
gl_FragColor = vec4(result, color.a);
|
|
136
136
|
}
|
|
137
|
-
`,
|
|
137
|
+
`,W={name:"halftone-duotone",fragmentShader:V,vertexShader:y,uniforms:[{name:"u_dotRadius",type:"float",default:4,attribute:"dot-radius"},{name:"u_gridSize",type:"float",default:8,attribute:"grid-size"},{name:"u_duotoneColor",type:"vec3",default:[0,.6,.8],attribute:"duotone-color"},{name:"u_angle",type:"float",default:0,attribute:"angle"}]},N=`precision mediump float;
|
|
138
138
|
|
|
139
139
|
varying vec2 v_texCoord;
|
|
140
140
|
|
|
@@ -190,7 +190,7 @@ void main() {
|
|
|
190
190
|
|
|
191
191
|
gl_FragColor = vec4(result, 1.0);
|
|
192
192
|
}
|
|
193
|
-
`,F={name:"dot-grid",fragmentShader:
|
|
193
|
+
`,F={name:"dot-grid",fragmentShader:N,vertexShader:y,uniforms:[{name:"u_dotRadius",type:"float",default:4,attribute:"dot-radius"},{name:"u_gridSize",type:"float",default:8,attribute:"grid-size"},{name:"u_dotOffset",type:"vec2",default:[.5,.5],attribute:"dot-offset"},{name:"u_bgColor",type:"vec3",default:[1,1,1],attribute:"bg-color"},{name:"u_angle",type:"float",default:0,attribute:"angle"}]},B=`precision mediump float;
|
|
194
194
|
|
|
195
195
|
varying vec2 v_texCoord;
|
|
196
196
|
|
|
@@ -206,6 +206,8 @@ uniform float u_showCool;
|
|
|
206
206
|
uniform float u_showK;
|
|
207
207
|
uniform vec3 u_warmColor;
|
|
208
208
|
uniform vec3 u_coolColor;
|
|
209
|
+
uniform float u_blendMode;
|
|
210
|
+
uniform float u_intensityK;
|
|
209
211
|
|
|
210
212
|
float halftone(vec2 uv, float angle, float channelValue, float gridSize, float dotRadius) {
|
|
211
213
|
float rad = radians(angle);
|
|
@@ -232,28 +234,53 @@ void main() {
|
|
|
232
234
|
|
|
233
235
|
// Black channel: derived from overall darkness
|
|
234
236
|
float k = 1.0 - max(warmSep, coolSep);
|
|
237
|
+
k = clamp(k * u_intensityK, 0.0, 1.0);
|
|
235
238
|
|
|
236
239
|
// Halftone dots for each channel
|
|
237
240
|
float warmDot = halftone(uv, u_angleWarm, warmSep, u_gridSize, u_dotRadius) * u_showWarm;
|
|
238
241
|
float coolDot = halftone(uv, u_angleCool, coolSep, u_gridSize, u_dotRadius) * u_showCool;
|
|
239
242
|
float kDot = halftone(uv, u_angleK, k, u_gridSize, u_dotRadius) * u_showK;
|
|
240
243
|
|
|
241
|
-
//
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
244
|
+
// Blend modes affect how warm and cool dots combine where they overlap.
|
|
245
|
+
// All modes use white paper; individual dots look the same.
|
|
246
|
+
// Only the overlap regions differ between modes.
|
|
247
|
+
vec3 overlap;
|
|
248
|
+
if (u_blendMode < 0.5) {
|
|
249
|
+
// Subtractive: dye overlap absorbs more light (darker)
|
|
250
|
+
overlap = u_warmColor + u_coolColor - vec3(1.0);
|
|
251
|
+
} else if (u_blendMode < 1.5) {
|
|
252
|
+
// Additive: light overlap adds up (brighter)
|
|
253
|
+
overlap = u_warmColor + u_coolColor;
|
|
254
|
+
} else {
|
|
255
|
+
// Screen: soft additive overlap with natural clamping
|
|
256
|
+
overlap = vec3(1.0) - (vec3(1.0) - u_warmColor) * (vec3(1.0) - u_coolColor);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// Decompose into four halftone regions
|
|
260
|
+
float onlyWarm = warmDot * (1.0 - coolDot);
|
|
261
|
+
float onlyCool = coolDot * (1.0 - warmDot);
|
|
262
|
+
float both = warmDot * coolDot;
|
|
263
|
+
float neither = (1.0 - warmDot) * (1.0 - coolDot);
|
|
264
|
+
|
|
265
|
+
// Composite: white paper base, colored dots, blend-mode-dependent overlap
|
|
266
|
+
vec3 result = neither * vec3(1.0)
|
|
267
|
+
+ onlyWarm * u_warmColor
|
|
268
|
+
+ onlyCool * u_coolColor
|
|
269
|
+
+ both * overlap;
|
|
270
|
+
|
|
271
|
+
// K channel darkening with intensity control
|
|
272
|
+
result *= (1.0 - kDot);
|
|
246
273
|
|
|
247
|
-
gl_FragColor = vec4(clamp(
|
|
274
|
+
gl_FragColor = vec4(clamp(result, 0.0, 1.0), color.a);
|
|
248
275
|
}
|
|
249
|
-
`,
|
|
276
|
+
`,Y={name:"technicolor-2strip",fragmentShader:B,vertexShader:y,uniforms:[{name:"u_dotRadius",type:"float",default:7,attribute:"dot-radius"},{name:"u_gridSize",type:"float",default:10,attribute:"grid-size"},{name:"u_angleWarm",type:"float",default:15,attribute:"angle-warm"},{name:"u_angleCool",type:"float",default:75,attribute:"angle-cool"},{name:"u_angleK",type:"float",default:45,attribute:"angle-k"},{name:"u_showWarm",type:"float",default:1,attribute:"show-warm"},{name:"u_showCool",type:"float",default:1,attribute:"show-cool"},{name:"u_showK",type:"float",default:1,attribute:"show-k"},{name:"u_warmColor",type:"vec3",default:[.85,.25,.06],attribute:"warm-color"},{name:"u_coolColor",type:"vec3",default:[.05,.65,.6],attribute:"cool-color"},{name:"u_blendMode",type:"float",default:1,attribute:"blend-mode"},{name:"u_intensityK",type:"float",default:1,attribute:"intensity-k"}]},w=new Map;function p(t){w.set(t.name,t)}function U(t){return w.get(t)}function X(){return Array.from(w.keys())}p(I);p(W);p(F);p(Y);var $=Object.defineProperty,u=(t,o,r,i)=>{for(var e=void 0,n=t.length-1,c;n>=0;n--)(c=t[n])&&(e=c(o,r,e)||e);return e&&$(o,r,e),e};const G=2;let T=Promise.resolve();function A(t){const o=T.then(t,t);return T=o,o}const H=new Set(["effect","dotRadius","gridSize","angleC","angleM","angleY","angleK","showC","showM","showY","showK","intensityK","duotoneColor","angle","dotOffsetX","dotOffsetY","bgColor","angleWarm","angleCool","showWarm","showCool","warmColor","coolColor","blendMode"]),C=class C extends _.LitElement{constructor(){super(...arguments),this.src="",this.effect="halftone-cmyk",this.dotRadius=4,this.gridSize=8,this.angleC=15,this.angleM=75,this.angleY=0,this.angleK=45,this.showC=1,this.showM=1,this.showY=1,this.showK=1,this.intensityK=1,this.duotoneColor="#0099cc",this.angle=0,this.dotOffsetX=.5,this.dotOffsetY=.5,this.bgColor="#ffffff",this.angleWarm=15,this.angleCool=75,this.showWarm=1,this.showCool=1,this.warmColor="#d94010",this.coolColor="#0da699",this.blendMode=1,this.loadingBlur=0,this._webglAvailable=!0,this._snapshotUrl="",this._snapshotLoaded=!1,this._image=null,this._observer=null,this._resizeObserver=null,this._lastClientWidth=0,this._visible=!1,this._needsRender=!1}render(){if(!this._webglAvailable)return _.html`<img src=${this.src} alt="" />`;const o=this.loadingBlur>0?`filter: blur(${this.loadingBlur}px)`:"";return _.html`
|
|
250
277
|
<img src=${this.src} alt="" style=${o} />
|
|
251
278
|
${this._snapshotUrl?_.html`<img
|
|
252
279
|
class="snapshot${this._snapshotLoaded?" loaded":""}"
|
|
253
280
|
src=${this._snapshotUrl}
|
|
254
281
|
@load=${this._onSnapshotLoad}
|
|
255
282
|
alt="" />`:""}
|
|
256
|
-
`}connectedCallback(){super.connectedCallback(),this._observer=new IntersectionObserver(o=>{var i;const r=this._visible;this._visible=((i=o[0])==null?void 0:i.isIntersecting)??!1,this._visible&&!r&&this._needsRender&&(this._needsRender=!1,A(()=>this._renderEffect()))},{rootMargin:"200px"}),this._observer.observe(this),this._resizeObserver=new ResizeObserver(()=>{if(!this._image)return;const o=this.clientWidth;o>0&&o!==this._lastClientWidth&&(this._lastClientWidth=o,this._scheduleRender())}),this._resizeObserver.observe(this)}updated(o){if(o.has("src")&&this.src){this._loadImage(this.src);return}if(!this._image)return;[...o.keys()].some(i=>H.has(i))&&this._scheduleRender()}disconnectedCallback(){var o,r;super.disconnectedCallback(),(o=this._observer)==null||o.disconnect(),(r=this._resizeObserver)==null||r.disconnect(),this._revokeSnapshot()}_loadImage(o){const r=new Image;r.crossOrigin="anonymous",r.onload=()=>{this._image=r,this._scheduleRender()},r.onerror=()=>{console.warn(`[some-shade] Failed to load image: ${o}`)},r.src=o}_scheduleRender(){this._visible?A(()=>this._renderEffect()):this._needsRender=!0}async _renderEffect(){var g;if(!this._image)return;const o=U(this.effect);if(!o){console.warn(`[some-shade] Unknown effect: ${this.effect}`);return}const r=Math.min(window.devicePixelRatio||1,G),i=this._image.naturalWidth,e=this._image.naturalHeight,n=this.clientWidth||i,
|
|
283
|
+
`}connectedCallback(){super.connectedCallback(),this._observer=new IntersectionObserver(o=>{var i;const r=this._visible;this._visible=((i=o[0])==null?void 0:i.isIntersecting)??!1,this._visible&&!r&&this._needsRender&&(this._needsRender=!1,A(()=>this._renderEffect()))},{rootMargin:"200px"}),this._observer.observe(this),this._resizeObserver=new ResizeObserver(()=>{if(!this._image)return;const o=this.clientWidth;o>0&&o!==this._lastClientWidth&&(this._lastClientWidth=o,this._scheduleRender())}),this._resizeObserver.observe(this)}updated(o){if(o.has("src")&&this.src){this._loadImage(this.src);return}if(!this._image)return;[...o.keys()].some(i=>H.has(i))&&this._scheduleRender()}disconnectedCallback(){var o,r;super.disconnectedCallback(),(o=this._observer)==null||o.disconnect(),(r=this._resizeObserver)==null||r.disconnect(),this._revokeSnapshot()}_loadImage(o){const r=new Image;r.crossOrigin="anonymous",r.onload=()=>{this._image=r,this._scheduleRender()},r.onerror=()=>{console.warn(`[some-shade] Failed to load image: ${o}`)},r.src=o}_scheduleRender(){this._visible?A(()=>this._renderEffect()):this._needsRender=!0}async _renderEffect(){var g;if(!this._image)return;const o=U(this.effect);if(!o){console.warn(`[some-shade] Unknown effect: ${this.effect}`);return}const r=Math.min(window.devicePixelRatio||1,G),i=this._image.naturalWidth,e=this._image.naturalHeight,n=this.clientWidth||i,c=Math.max(1,i/n);this._lastClientWidth=this.clientWidth;const h=document.createElement("canvas");h.width=i*r,h.height=e*r;const s=k(h);if(!s){this._webglAvailable=!1;return}try{const d=D(s,o.vertexShader,o.fragmentShader);s.useProgram(d.program);const f=z(s,this._image),m=M(s,d);s.viewport(0,0,h.width,h.height),s.clearColor(0,0,0,0),s.clear(s.COLOR_BUFFER_BIT),s.activeTexture(s.TEXTURE0),s.bindTexture(s.TEXTURE_2D,f.texture);const R=d.uniformLocations.get("u_image");R&&s.uniform1i(R,0),L(s,d,this._getUniformValues(f,r,c)),s.bindBuffer(s.ARRAY_BUFFER,m);const S=4*Float32Array.BYTES_PER_ELEMENT,b=d.attribLocations.get("a_position");b!==void 0&&b!==-1&&(s.enableVertexAttribArray(b),s.vertexAttribPointer(b,2,s.FLOAT,!1,S,0));const v=d.attribLocations.get("a_texCoord");v!==void 0&&v!==-1&&(s.enableVertexAttribArray(v),s.vertexAttribPointer(v,2,s.FLOAT,!1,S,2*Float32Array.BYTES_PER_ELEMENT)),P(s);const x=await new Promise(K=>h.toBlob(K));s.deleteTexture(f.texture),s.deleteProgram(d.program),s.deleteBuffer(m),x&&(this._snapshotLoaded=!1,this._revokeSnapshot(),this._snapshotUrl=URL.createObjectURL(x))}finally{(g=s.getExtension("WEBGL_lose_context"))==null||g.loseContext()}}_onSnapshotLoad(){this._snapshotLoaded=!0}replayTransition(o=500){this._snapshotUrl&&(this._snapshotLoaded=!1,this.updateComplete.then(()=>{setTimeout(()=>{this._snapshotLoaded=!0},o)}))}_revokeSnapshot(){this._snapshotUrl&&(URL.revokeObjectURL(this._snapshotUrl),this._snapshotUrl="")}_getUniformValues(o,r,i){const e={};return e.u_resolution=[o.width*r,o.height*r],e.u_dotRadius=this.dotRadius*i,e.u_gridSize=this.gridSize*i,this.effect==="halftone-cmyk"?(e.u_angleC=this.angleC,e.u_angleM=this.angleM,e.u_angleY=this.angleY,e.u_angleK=this.angleK,e.u_showC=this.showC,e.u_showM=this.showM,e.u_showY=this.showY,e.u_showK=this.showK,e.u_intensityK=this.intensityK):this.effect==="halftone-duotone"?(e.u_duotoneColor=this._parseHexColor(this.duotoneColor),e.u_angle=this.angle):this.effect==="dot-grid"?(e.u_dotOffset=[this.dotOffsetX,this.dotOffsetY],e.u_bgColor=this._parseHexColor(this.bgColor),e.u_angle=this.angle):this.effect==="technicolor-2strip"&&(e.u_angleWarm=this.angleWarm,e.u_angleCool=this.angleCool,e.u_angleK=this.angleK,e.u_showWarm=this.showWarm,e.u_showCool=this.showCool,e.u_showK=this.showK,e.u_warmColor=this._parseHexColor(this.warmColor),e.u_coolColor=this._parseHexColor(this.coolColor),e.u_blendMode=this.blendMode,e.u_intensityK=this.intensityK),e}_parseHexColor(o){const r=o.replace("#",""),i=parseInt(r.substring(0,2),16)/255,e=parseInt(r.substring(2,4),16)/255,n=parseInt(r.substring(4,6),16)/255;return[i,e,n]}};C.styles=_.css`
|
|
257
284
|
:host {
|
|
258
285
|
display: block;
|
|
259
286
|
position: relative;
|
|
@@ -276,4 +303,4 @@ void main() {
|
|
|
276
303
|
img.snapshot.loaded {
|
|
277
304
|
opacity: 1;
|
|
278
305
|
}
|
|
279
|
-
`;let a=C;u([l.property()],a.prototype,"src");u([l.property()],a.prototype,"effect");u([l.property({type:Number,attribute:"dot-radius"})],a.prototype,"dotRadius");u([l.property({type:Number,attribute:"grid-size"})],a.prototype,"gridSize");u([l.property({type:Number,attribute:"angle-c"})],a.prototype,"angleC");u([l.property({type:Number,attribute:"angle-m"})],a.prototype,"angleM");u([l.property({type:Number,attribute:"angle-y"})],a.prototype,"angleY");u([l.property({type:Number,attribute:"angle-k"})],a.prototype,"angleK");u([l.property({type:Number,attribute:"show-c"})],a.prototype,"showC");u([l.property({type:Number,attribute:"show-m"})],a.prototype,"showM");u([l.property({type:Number,attribute:"show-y"})],a.prototype,"showY");u([l.property({type:Number,attribute:"show-k"})],a.prototype,"showK");u([l.property({type:Number,attribute:"intensity-k"})],a.prototype,"intensityK");u([l.property({attribute:"duotone-color"})],a.prototype,"duotoneColor");u([l.property({type:Number})],a.prototype,"angle");u([l.property({type:Number,attribute:"dot-offset-x"})],a.prototype,"dotOffsetX");u([l.property({type:Number,attribute:"dot-offset-y"})],a.prototype,"dotOffsetY");u([l.property({attribute:"bg-color"})],a.prototype,"bgColor");u([l.property({type:Number,attribute:"angle-warm"})],a.prototype,"angleWarm");u([l.property({type:Number,attribute:"angle-cool"})],a.prototype,"angleCool");u([l.property({type:Number,attribute:"show-warm"})],a.prototype,"showWarm");u([l.property({type:Number,attribute:"show-cool"})],a.prototype,"showCool");u([l.property({attribute:"warm-color"})],a.prototype,"warmColor");u([l.property({attribute:"cool-color"})],a.prototype,"coolColor");u([l.property({type:Number,attribute:"loading-blur"})],a.prototype,"loadingBlur");u([l.state()],a.prototype,"_webglAvailable");u([l.state()],a.prototype,"_snapshotUrl");u([l.state()],a.prototype,"_snapshotLoaded");customElements.get("some-shade-image")||customElements.define("some-shade-image",a);exports.SomeShadeImage=a;exports.get=U;exports.list=X;exports.register=p;
|
|
306
|
+
`;let a=C;u([l.property()],a.prototype,"src");u([l.property()],a.prototype,"effect");u([l.property({type:Number,attribute:"dot-radius"})],a.prototype,"dotRadius");u([l.property({type:Number,attribute:"grid-size"})],a.prototype,"gridSize");u([l.property({type:Number,attribute:"angle-c"})],a.prototype,"angleC");u([l.property({type:Number,attribute:"angle-m"})],a.prototype,"angleM");u([l.property({type:Number,attribute:"angle-y"})],a.prototype,"angleY");u([l.property({type:Number,attribute:"angle-k"})],a.prototype,"angleK");u([l.property({type:Number,attribute:"show-c"})],a.prototype,"showC");u([l.property({type:Number,attribute:"show-m"})],a.prototype,"showM");u([l.property({type:Number,attribute:"show-y"})],a.prototype,"showY");u([l.property({type:Number,attribute:"show-k"})],a.prototype,"showK");u([l.property({type:Number,attribute:"intensity-k"})],a.prototype,"intensityK");u([l.property({attribute:"duotone-color"})],a.prototype,"duotoneColor");u([l.property({type:Number})],a.prototype,"angle");u([l.property({type:Number,attribute:"dot-offset-x"})],a.prototype,"dotOffsetX");u([l.property({type:Number,attribute:"dot-offset-y"})],a.prototype,"dotOffsetY");u([l.property({attribute:"bg-color"})],a.prototype,"bgColor");u([l.property({type:Number,attribute:"angle-warm"})],a.prototype,"angleWarm");u([l.property({type:Number,attribute:"angle-cool"})],a.prototype,"angleCool");u([l.property({type:Number,attribute:"show-warm"})],a.prototype,"showWarm");u([l.property({type:Number,attribute:"show-cool"})],a.prototype,"showCool");u([l.property({attribute:"warm-color"})],a.prototype,"warmColor");u([l.property({attribute:"cool-color"})],a.prototype,"coolColor");u([l.property({type:Number,attribute:"blend-mode"})],a.prototype,"blendMode");u([l.property({type:Number,attribute:"loading-blur"})],a.prototype,"loadingBlur");u([l.state()],a.prototype,"_webglAvailable");u([l.state()],a.prototype,"_snapshotUrl");u([l.state()],a.prototype,"_snapshotLoaded");customElements.get("some-shade-image")||customElements.define("some-shade-image",a);exports.SomeShadeImage=a;exports.get=U;exports.list=X;exports.register=p;
|
package/dist/some-shade.es.js
CHANGED
|
@@ -1,72 +1,72 @@
|
|
|
1
|
-
import { LitElement as k, css as
|
|
1
|
+
import { LitElement as k, css as D, html as y } from "lit";
|
|
2
2
|
import { property as u, state as w } from "lit/decorators.js";
|
|
3
|
-
function
|
|
3
|
+
function L(t) {
|
|
4
4
|
return t.getContext("webgl", {
|
|
5
5
|
alpha: !0,
|
|
6
6
|
premultipliedAlpha: !1,
|
|
7
7
|
preserveDrawingBuffer: !0
|
|
8
8
|
});
|
|
9
9
|
}
|
|
10
|
-
function T(t, o,
|
|
11
|
-
const
|
|
12
|
-
if (!
|
|
13
|
-
if (t.shaderSource(
|
|
14
|
-
const e = t.getShaderInfoLog(
|
|
15
|
-
throw t.deleteShader(
|
|
10
|
+
function T(t, o, n) {
|
|
11
|
+
const i = t.createShader(o);
|
|
12
|
+
if (!i) throw new Error("Failed to create shader");
|
|
13
|
+
if (t.shaderSource(i, n), t.compileShader(i), !t.getShaderParameter(i, t.COMPILE_STATUS)) {
|
|
14
|
+
const e = t.getShaderInfoLog(i);
|
|
15
|
+
throw t.deleteShader(i), new Error(`Shader compile error: ${e}`);
|
|
16
16
|
}
|
|
17
|
-
return
|
|
17
|
+
return i;
|
|
18
18
|
}
|
|
19
|
-
function z(t, o,
|
|
20
|
-
const
|
|
21
|
-
if (!
|
|
22
|
-
if (t.attachShader(
|
|
23
|
-
const d = t.getProgramInfoLog(
|
|
24
|
-
throw t.deleteProgram(
|
|
19
|
+
function z(t, o, n) {
|
|
20
|
+
const i = T(t, t.VERTEX_SHADER, o), e = T(t, t.FRAGMENT_SHADER, n), r = t.createProgram();
|
|
21
|
+
if (!r) throw new Error("Failed to create program");
|
|
22
|
+
if (t.attachShader(r, i), t.attachShader(r, e), t.linkProgram(r), !t.getProgramParameter(r, t.LINK_STATUS)) {
|
|
23
|
+
const d = t.getProgramInfoLog(r);
|
|
24
|
+
throw t.deleteProgram(r), new Error(`Program link error: ${d}`);
|
|
25
25
|
}
|
|
26
|
-
t.deleteShader(
|
|
27
|
-
const c = /* @__PURE__ */ new Map(), h = t.getProgramParameter(
|
|
26
|
+
t.deleteShader(i), t.deleteShader(e);
|
|
27
|
+
const c = /* @__PURE__ */ new Map(), h = t.getProgramParameter(r, t.ACTIVE_ATTRIBUTES);
|
|
28
28
|
for (let d = 0; d < h; d++) {
|
|
29
|
-
const f = t.getActiveAttrib(
|
|
30
|
-
f && c.set(f.name, t.getAttribLocation(
|
|
29
|
+
const f = t.getActiveAttrib(r, d);
|
|
30
|
+
f && c.set(f.name, t.getAttribLocation(r, f.name));
|
|
31
31
|
}
|
|
32
|
-
const
|
|
32
|
+
const s = /* @__PURE__ */ new Map(), _ = t.getProgramParameter(r, t.ACTIVE_UNIFORMS);
|
|
33
33
|
for (let d = 0; d < _; d++) {
|
|
34
|
-
const f = t.getActiveUniform(
|
|
34
|
+
const f = t.getActiveUniform(r, d);
|
|
35
35
|
if (f) {
|
|
36
|
-
const m = t.getUniformLocation(
|
|
37
|
-
m &&
|
|
36
|
+
const m = t.getUniformLocation(r, f.name);
|
|
37
|
+
m && s.set(f.name, m);
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
|
-
return { program:
|
|
40
|
+
return { program: r, attribLocations: c, uniformLocations: s };
|
|
41
41
|
}
|
|
42
|
-
function
|
|
43
|
-
for (const [
|
|
44
|
-
const
|
|
45
|
-
if (
|
|
42
|
+
function M(t, o, n) {
|
|
43
|
+
for (const [i, e] of Object.entries(n)) {
|
|
44
|
+
const r = o.uniformLocations.get(i);
|
|
45
|
+
if (r) {
|
|
46
46
|
if (typeof e == "number")
|
|
47
|
-
t.uniform1f(
|
|
47
|
+
t.uniform1f(r, e);
|
|
48
48
|
else if (Array.isArray(e))
|
|
49
49
|
switch (e.length) {
|
|
50
50
|
case 2:
|
|
51
|
-
t.uniform2fv(
|
|
51
|
+
t.uniform2fv(r, e);
|
|
52
52
|
break;
|
|
53
53
|
case 3:
|
|
54
|
-
t.uniform3fv(
|
|
54
|
+
t.uniform3fv(r, e);
|
|
55
55
|
break;
|
|
56
56
|
case 4:
|
|
57
|
-
t.uniform4fv(
|
|
57
|
+
t.uniform4fv(r, e);
|
|
58
58
|
break;
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
|
-
function
|
|
64
|
-
const
|
|
65
|
-
if (!
|
|
66
|
-
return t.bindTexture(t.TEXTURE_2D,
|
|
63
|
+
function P(t, o) {
|
|
64
|
+
const n = t.createTexture();
|
|
65
|
+
if (!n) throw new Error("Failed to create texture");
|
|
66
|
+
return t.bindTexture(t.TEXTURE_2D, n), t.texImage2D(t.TEXTURE_2D, 0, t.RGBA, t.RGBA, t.UNSIGNED_BYTE, o), t.texParameteri(t.TEXTURE_2D, t.TEXTURE_WRAP_S, t.CLAMP_TO_EDGE), t.texParameteri(t.TEXTURE_2D, t.TEXTURE_WRAP_T, t.CLAMP_TO_EDGE), t.texParameteri(t.TEXTURE_2D, t.TEXTURE_MIN_FILTER, t.LINEAR), t.texParameteri(t.TEXTURE_2D, t.TEXTURE_MAG_FILTER, t.LINEAR), { texture: n, width: o.naturalWidth, height: o.naturalHeight };
|
|
67
67
|
}
|
|
68
|
-
function
|
|
69
|
-
const
|
|
68
|
+
function O(t, o) {
|
|
69
|
+
const n = new Float32Array([
|
|
70
70
|
// pos.x pos.y tex.s tex.t
|
|
71
71
|
-1,
|
|
72
72
|
-1,
|
|
@@ -84,15 +84,15 @@ function I(t, o) {
|
|
|
84
84
|
1,
|
|
85
85
|
1,
|
|
86
86
|
0
|
|
87
|
-
]),
|
|
88
|
-
if (!
|
|
89
|
-
t.bindBuffer(t.ARRAY_BUFFER,
|
|
90
|
-
const e = 4 * Float32Array.BYTES_PER_ELEMENT,
|
|
91
|
-
|
|
87
|
+
]), i = t.createBuffer();
|
|
88
|
+
if (!i) throw new Error("Failed to create buffer");
|
|
89
|
+
t.bindBuffer(t.ARRAY_BUFFER, i), t.bufferData(t.ARRAY_BUFFER, n, t.STATIC_DRAW);
|
|
90
|
+
const e = 4 * Float32Array.BYTES_PER_ELEMENT, r = o.attribLocations.get("a_position");
|
|
91
|
+
r !== void 0 && r !== -1 && (t.enableVertexAttribArray(r), t.vertexAttribPointer(r, 2, t.FLOAT, !1, e, 0));
|
|
92
92
|
const c = o.attribLocations.get("a_texCoord");
|
|
93
|
-
return c !== void 0 && c !== -1 && (t.enableVertexAttribArray(c), t.vertexAttribPointer(c, 2, t.FLOAT, !1, e, 2 * Float32Array.BYTES_PER_ELEMENT)),
|
|
93
|
+
return c !== void 0 && c !== -1 && (t.enableVertexAttribArray(c), t.vertexAttribPointer(c, 2, t.FLOAT, !1, e, 2 * Float32Array.BYTES_PER_ELEMENT)), i;
|
|
94
94
|
}
|
|
95
|
-
function
|
|
95
|
+
function I(t) {
|
|
96
96
|
t.drawArrays(t.TRIANGLE_STRIP, 0, 4);
|
|
97
97
|
}
|
|
98
98
|
const V = `precision mediump float;
|
|
@@ -181,7 +181,7 @@ void main() {
|
|
|
181
181
|
|
|
182
182
|
gl_FragColor = vec4(outR, outG, outB, texture2D(u_image, v_texCoord).a);
|
|
183
183
|
}
|
|
184
|
-
`,
|
|
184
|
+
`, b = `attribute vec2 a_position;
|
|
185
185
|
attribute vec2 a_texCoord;
|
|
186
186
|
varying vec2 v_texCoord;
|
|
187
187
|
|
|
@@ -189,10 +189,10 @@ void main() {
|
|
|
189
189
|
gl_Position = vec4(a_position, 0.0, 1.0);
|
|
190
190
|
v_texCoord = a_texCoord;
|
|
191
191
|
}
|
|
192
|
-
`,
|
|
192
|
+
`, W = {
|
|
193
193
|
name: "halftone-cmyk",
|
|
194
194
|
fragmentShader: V,
|
|
195
|
-
vertexShader:
|
|
195
|
+
vertexShader: b,
|
|
196
196
|
uniforms: [
|
|
197
197
|
{ name: "u_dotRadius", type: "float", default: 4, attribute: "dot-radius" },
|
|
198
198
|
{ name: "u_gridSize", type: "float", default: 8, attribute: "grid-size" },
|
|
@@ -206,7 +206,7 @@ void main() {
|
|
|
206
206
|
{ name: "u_showK", type: "float", default: 1, attribute: "show-k" },
|
|
207
207
|
{ name: "u_intensityK", type: "float", default: 1, attribute: "intensity-k" }
|
|
208
208
|
]
|
|
209
|
-
},
|
|
209
|
+
}, N = `precision mediump float;
|
|
210
210
|
|
|
211
211
|
varying vec2 v_texCoord;
|
|
212
212
|
|
|
@@ -250,15 +250,15 @@ void main() {
|
|
|
250
250
|
}
|
|
251
251
|
`, F = {
|
|
252
252
|
name: "halftone-duotone",
|
|
253
|
-
fragmentShader:
|
|
254
|
-
vertexShader:
|
|
253
|
+
fragmentShader: N,
|
|
254
|
+
vertexShader: b,
|
|
255
255
|
uniforms: [
|
|
256
256
|
{ name: "u_dotRadius", type: "float", default: 4, attribute: "dot-radius" },
|
|
257
257
|
{ name: "u_gridSize", type: "float", default: 8, attribute: "grid-size" },
|
|
258
258
|
{ name: "u_duotoneColor", type: "vec3", default: [0, 0.6, 0.8], attribute: "duotone-color" },
|
|
259
259
|
{ name: "u_angle", type: "float", default: 0, attribute: "angle" }
|
|
260
260
|
]
|
|
261
|
-
},
|
|
261
|
+
}, B = `precision mediump float;
|
|
262
262
|
|
|
263
263
|
varying vec2 v_texCoord;
|
|
264
264
|
|
|
@@ -314,10 +314,10 @@ void main() {
|
|
|
314
314
|
|
|
315
315
|
gl_FragColor = vec4(result, 1.0);
|
|
316
316
|
}
|
|
317
|
-
`,
|
|
317
|
+
`, Y = {
|
|
318
318
|
name: "dot-grid",
|
|
319
|
-
fragmentShader:
|
|
320
|
-
vertexShader:
|
|
319
|
+
fragmentShader: B,
|
|
320
|
+
vertexShader: b,
|
|
321
321
|
uniforms: [
|
|
322
322
|
{ name: "u_dotRadius", type: "float", default: 4, attribute: "dot-radius" },
|
|
323
323
|
{ name: "u_gridSize", type: "float", default: 8, attribute: "grid-size" },
|
|
@@ -341,6 +341,8 @@ uniform float u_showCool;
|
|
|
341
341
|
uniform float u_showK;
|
|
342
342
|
uniform vec3 u_warmColor;
|
|
343
343
|
uniform vec3 u_coolColor;
|
|
344
|
+
uniform float u_blendMode;
|
|
345
|
+
uniform float u_intensityK;
|
|
344
346
|
|
|
345
347
|
float halftone(vec2 uv, float angle, float channelValue, float gridSize, float dotRadius) {
|
|
346
348
|
float rad = radians(angle);
|
|
@@ -367,27 +369,52 @@ void main() {
|
|
|
367
369
|
|
|
368
370
|
// Black channel: derived from overall darkness
|
|
369
371
|
float k = 1.0 - max(warmSep, coolSep);
|
|
372
|
+
k = clamp(k * u_intensityK, 0.0, 1.0);
|
|
370
373
|
|
|
371
374
|
// Halftone dots for each channel
|
|
372
375
|
float warmDot = halftone(uv, u_angleWarm, warmSep, u_gridSize, u_dotRadius) * u_showWarm;
|
|
373
376
|
float coolDot = halftone(uv, u_angleCool, coolSep, u_gridSize, u_dotRadius) * u_showCool;
|
|
374
377
|
float kDot = halftone(uv, u_angleK, k, u_gridSize, u_dotRadius) * u_showK;
|
|
375
378
|
|
|
376
|
-
//
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
379
|
+
// Blend modes affect how warm and cool dots combine where they overlap.
|
|
380
|
+
// All modes use white paper; individual dots look the same.
|
|
381
|
+
// Only the overlap regions differ between modes.
|
|
382
|
+
vec3 overlap;
|
|
383
|
+
if (u_blendMode < 0.5) {
|
|
384
|
+
// Subtractive: dye overlap absorbs more light (darker)
|
|
385
|
+
overlap = u_warmColor + u_coolColor - vec3(1.0);
|
|
386
|
+
} else if (u_blendMode < 1.5) {
|
|
387
|
+
// Additive: light overlap adds up (brighter)
|
|
388
|
+
overlap = u_warmColor + u_coolColor;
|
|
389
|
+
} else {
|
|
390
|
+
// Screen: soft additive overlap with natural clamping
|
|
391
|
+
overlap = vec3(1.0) - (vec3(1.0) - u_warmColor) * (vec3(1.0) - u_coolColor);
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
// Decompose into four halftone regions
|
|
395
|
+
float onlyWarm = warmDot * (1.0 - coolDot);
|
|
396
|
+
float onlyCool = coolDot * (1.0 - warmDot);
|
|
397
|
+
float both = warmDot * coolDot;
|
|
398
|
+
float neither = (1.0 - warmDot) * (1.0 - coolDot);
|
|
381
399
|
|
|
382
|
-
|
|
400
|
+
// Composite: white paper base, colored dots, blend-mode-dependent overlap
|
|
401
|
+
vec3 result = neither * vec3(1.0)
|
|
402
|
+
+ onlyWarm * u_warmColor
|
|
403
|
+
+ onlyCool * u_coolColor
|
|
404
|
+
+ both * overlap;
|
|
405
|
+
|
|
406
|
+
// K channel darkening with intensity control
|
|
407
|
+
result *= (1.0 - kDot);
|
|
408
|
+
|
|
409
|
+
gl_FragColor = vec4(clamp(result, 0.0, 1.0), color.a);
|
|
383
410
|
}
|
|
384
411
|
`, $ = {
|
|
385
412
|
name: "technicolor-2strip",
|
|
386
413
|
fragmentShader: X,
|
|
387
|
-
vertexShader:
|
|
414
|
+
vertexShader: b,
|
|
388
415
|
uniforms: [
|
|
389
|
-
{ name: "u_dotRadius", type: "float", default:
|
|
390
|
-
{ name: "u_gridSize", type: "float", default:
|
|
416
|
+
{ name: "u_dotRadius", type: "float", default: 7, attribute: "dot-radius" },
|
|
417
|
+
{ name: "u_gridSize", type: "float", default: 10, attribute: "grid-size" },
|
|
391
418
|
{ name: "u_angleWarm", type: "float", default: 15, attribute: "angle-warm" },
|
|
392
419
|
{ name: "u_angleCool", type: "float", default: 75, attribute: "angle-cool" },
|
|
393
420
|
{ name: "u_angleK", type: "float", default: 45, attribute: "angle-k" },
|
|
@@ -395,10 +422,12 @@ void main() {
|
|
|
395
422
|
{ name: "u_showCool", type: "float", default: 1, attribute: "show-cool" },
|
|
396
423
|
{ name: "u_showK", type: "float", default: 1, attribute: "show-k" },
|
|
397
424
|
{ name: "u_warmColor", type: "vec3", default: [0.85, 0.25, 0.06], attribute: "warm-color" },
|
|
398
|
-
{ name: "u_coolColor", type: "vec3", default: [0.05, 0.65, 0.6], attribute: "cool-color" }
|
|
425
|
+
{ name: "u_coolColor", type: "vec3", default: [0.05, 0.65, 0.6], attribute: "cool-color" },
|
|
426
|
+
{ name: "u_blendMode", type: "float", default: 1, attribute: "blend-mode" },
|
|
427
|
+
{ name: "u_intensityK", type: "float", default: 1, attribute: "intensity-k" }
|
|
399
428
|
]
|
|
400
429
|
}, C = /* @__PURE__ */ new Map();
|
|
401
|
-
function
|
|
430
|
+
function v(t) {
|
|
402
431
|
C.set(t.name, t);
|
|
403
432
|
}
|
|
404
433
|
function G(t) {
|
|
@@ -407,14 +436,14 @@ function G(t) {
|
|
|
407
436
|
function Z() {
|
|
408
437
|
return Array.from(C.keys());
|
|
409
438
|
}
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
var H = Object.defineProperty, l = (t, o,
|
|
415
|
-
for (var e = void 0,
|
|
416
|
-
(c = t[
|
|
417
|
-
return e && H(o,
|
|
439
|
+
v(W);
|
|
440
|
+
v(F);
|
|
441
|
+
v(Y);
|
|
442
|
+
v($);
|
|
443
|
+
var H = Object.defineProperty, l = (t, o, n, i) => {
|
|
444
|
+
for (var e = void 0, r = t.length - 1, c; r >= 0; r--)
|
|
445
|
+
(c = t[r]) && (e = c(o, n, e) || e);
|
|
446
|
+
return e && H(o, n, e), e;
|
|
418
447
|
};
|
|
419
448
|
const q = 2;
|
|
420
449
|
let A = Promise.resolve();
|
|
@@ -445,10 +474,11 @@ const j = /* @__PURE__ */ new Set([
|
|
|
445
474
|
"showWarm",
|
|
446
475
|
"showCool",
|
|
447
476
|
"warmColor",
|
|
448
|
-
"coolColor"
|
|
477
|
+
"coolColor",
|
|
478
|
+
"blendMode"
|
|
449
479
|
]), R = class R extends k {
|
|
450
480
|
constructor() {
|
|
451
|
-
super(...arguments), this.src = "", this.effect = "halftone-cmyk", this.dotRadius = 4, this.gridSize = 8, this.angleC = 15, this.angleM = 75, this.angleY = 0, this.angleK = 45, this.showC = 1, this.showM = 1, this.showY = 1, this.showK = 1, this.intensityK = 1, this.duotoneColor = "#0099cc", this.angle = 0, this.dotOffsetX = 0.5, this.dotOffsetY = 0.5, this.bgColor = "#ffffff", this.angleWarm = 15, this.angleCool = 75, this.showWarm = 1, this.showCool = 1, this.warmColor = "#d94010", this.coolColor = "#0da699", this.loadingBlur = 0, this._webglAvailable = !0, this._snapshotUrl = "", this._snapshotLoaded = !1, this._image = null, this._observer = null, this._resizeObserver = null, this._lastClientWidth = 0, this._visible = !1, this._needsRender = !1;
|
|
481
|
+
super(...arguments), this.src = "", this.effect = "halftone-cmyk", this.dotRadius = 4, this.gridSize = 8, this.angleC = 15, this.angleM = 75, this.angleY = 0, this.angleK = 45, this.showC = 1, this.showM = 1, this.showY = 1, this.showK = 1, this.intensityK = 1, this.duotoneColor = "#0099cc", this.angle = 0, this.dotOffsetX = 0.5, this.dotOffsetY = 0.5, this.bgColor = "#ffffff", this.angleWarm = 15, this.angleCool = 75, this.showWarm = 1, this.showCool = 1, this.warmColor = "#d94010", this.coolColor = "#0da699", this.blendMode = 1, this.loadingBlur = 0, this._webglAvailable = !0, this._snapshotUrl = "", this._snapshotLoaded = !1, this._image = null, this._observer = null, this._resizeObserver = null, this._lastClientWidth = 0, this._visible = !1, this._needsRender = !1;
|
|
452
482
|
}
|
|
453
483
|
render() {
|
|
454
484
|
if (!this._webglAvailable)
|
|
@@ -466,9 +496,9 @@ const j = /* @__PURE__ */ new Set([
|
|
|
466
496
|
connectedCallback() {
|
|
467
497
|
super.connectedCallback(), this._observer = new IntersectionObserver(
|
|
468
498
|
(o) => {
|
|
469
|
-
var
|
|
470
|
-
const
|
|
471
|
-
this._visible = ((
|
|
499
|
+
var i;
|
|
500
|
+
const n = this._visible;
|
|
501
|
+
this._visible = ((i = o[0]) == null ? void 0 : i.isIntersecting) ?? !1, this._visible && !n && this._needsRender && (this._needsRender = !1, U(() => this._renderEffect()));
|
|
472
502
|
},
|
|
473
503
|
// Start rendering slightly before the element scrolls into view.
|
|
474
504
|
{ rootMargin: "200px" }
|
|
@@ -485,23 +515,23 @@ const j = /* @__PURE__ */ new Set([
|
|
|
485
515
|
}
|
|
486
516
|
if (!this._image) return;
|
|
487
517
|
[...o.keys()].some(
|
|
488
|
-
(
|
|
518
|
+
(i) => j.has(i)
|
|
489
519
|
) && this._scheduleRender();
|
|
490
520
|
}
|
|
491
521
|
disconnectedCallback() {
|
|
492
|
-
var o,
|
|
493
|
-
super.disconnectedCallback(), (o = this._observer) == null || o.disconnect(), (
|
|
522
|
+
var o, n;
|
|
523
|
+
super.disconnectedCallback(), (o = this._observer) == null || o.disconnect(), (n = this._resizeObserver) == null || n.disconnect(), this._revokeSnapshot();
|
|
494
524
|
}
|
|
495
525
|
// ---------------------------------------------------------------------------
|
|
496
526
|
// Image loading
|
|
497
527
|
// ---------------------------------------------------------------------------
|
|
498
528
|
_loadImage(o) {
|
|
499
|
-
const
|
|
500
|
-
|
|
501
|
-
this._image =
|
|
502
|
-
},
|
|
529
|
+
const n = new Image();
|
|
530
|
+
n.crossOrigin = "anonymous", n.onload = () => {
|
|
531
|
+
this._image = n, this._scheduleRender();
|
|
532
|
+
}, n.onerror = () => {
|
|
503
533
|
console.warn(`[some-shade] Failed to load image: ${o}`);
|
|
504
|
-
},
|
|
534
|
+
}, n.src = o;
|
|
505
535
|
}
|
|
506
536
|
// ---------------------------------------------------------------------------
|
|
507
537
|
// Render scheduling
|
|
@@ -520,47 +550,47 @@ const j = /* @__PURE__ */ new Set([
|
|
|
520
550
|
console.warn(`[some-shade] Unknown effect: ${this.effect}`);
|
|
521
551
|
return;
|
|
522
552
|
}
|
|
523
|
-
const
|
|
553
|
+
const n = Math.min(window.devicePixelRatio || 1, q), i = this._image.naturalWidth, e = this._image.naturalHeight, r = this.clientWidth || i, c = Math.max(1, i / r);
|
|
524
554
|
this._lastClientWidth = this.clientWidth;
|
|
525
555
|
const h = document.createElement("canvas");
|
|
526
|
-
h.width =
|
|
527
|
-
const
|
|
528
|
-
if (!
|
|
556
|
+
h.width = i * n, h.height = e * n;
|
|
557
|
+
const s = L(h);
|
|
558
|
+
if (!s) {
|
|
529
559
|
this._webglAvailable = !1;
|
|
530
560
|
return;
|
|
531
561
|
}
|
|
532
562
|
try {
|
|
533
563
|
const d = z(
|
|
534
|
-
|
|
564
|
+
s,
|
|
535
565
|
o.vertexShader,
|
|
536
566
|
o.fragmentShader
|
|
537
567
|
);
|
|
538
|
-
|
|
539
|
-
const f =
|
|
540
|
-
|
|
568
|
+
s.useProgram(d.program);
|
|
569
|
+
const f = P(s, this._image), m = O(s, d);
|
|
570
|
+
s.viewport(0, 0, h.width, h.height), s.clearColor(0, 0, 0, 0), s.clear(s.COLOR_BUFFER_BIT), s.activeTexture(s.TEXTURE0), s.bindTexture(s.TEXTURE_2D, f.texture);
|
|
541
571
|
const S = d.uniformLocations.get("u_image");
|
|
542
|
-
S &&
|
|
543
|
-
|
|
572
|
+
S && s.uniform1i(S, 0), M(
|
|
573
|
+
s,
|
|
544
574
|
d,
|
|
545
|
-
this._getUniformValues(f,
|
|
546
|
-
),
|
|
575
|
+
this._getUniformValues(f, n, c)
|
|
576
|
+
), s.bindBuffer(s.ARRAY_BUFFER, m);
|
|
547
577
|
const x = 4 * Float32Array.BYTES_PER_ELEMENT, g = d.attribLocations.get("a_position");
|
|
548
|
-
g !== void 0 && g !== -1 && (
|
|
578
|
+
g !== void 0 && g !== -1 && (s.enableVertexAttribArray(g), s.vertexAttribPointer(g, 2, s.FLOAT, !1, x, 0));
|
|
549
579
|
const p = d.attribLocations.get("a_texCoord");
|
|
550
|
-
p !== void 0 && p !== -1 && (
|
|
580
|
+
p !== void 0 && p !== -1 && (s.enableVertexAttribArray(p), s.vertexAttribPointer(
|
|
551
581
|
p,
|
|
552
582
|
2,
|
|
553
|
-
|
|
583
|
+
s.FLOAT,
|
|
554
584
|
!1,
|
|
555
585
|
x,
|
|
556
586
|
2 * Float32Array.BYTES_PER_ELEMENT
|
|
557
|
-
)),
|
|
587
|
+
)), I(s);
|
|
558
588
|
const E = await new Promise(
|
|
559
589
|
(K) => h.toBlob(K)
|
|
560
590
|
);
|
|
561
|
-
|
|
591
|
+
s.deleteTexture(f.texture), s.deleteProgram(d.program), s.deleteBuffer(m), E && (this._snapshotLoaded = !1, this._revokeSnapshot(), this._snapshotUrl = URL.createObjectURL(E));
|
|
562
592
|
} finally {
|
|
563
|
-
(_ =
|
|
593
|
+
(_ = s.getExtension("WEBGL_lose_context")) == null || _.loseContext();
|
|
564
594
|
}
|
|
565
595
|
}
|
|
566
596
|
// ---------------------------------------------------------------------------
|
|
@@ -581,19 +611,19 @@ const j = /* @__PURE__ */ new Set([
|
|
|
581
611
|
_revokeSnapshot() {
|
|
582
612
|
this._snapshotUrl && (URL.revokeObjectURL(this._snapshotUrl), this._snapshotUrl = "");
|
|
583
613
|
}
|
|
584
|
-
_getUniformValues(o,
|
|
614
|
+
_getUniformValues(o, n, i) {
|
|
585
615
|
const e = {};
|
|
586
616
|
return e.u_resolution = [
|
|
587
|
-
o.width *
|
|
588
|
-
o.height *
|
|
589
|
-
], e.u_dotRadius = this.dotRadius *
|
|
617
|
+
o.width * n,
|
|
618
|
+
o.height * n
|
|
619
|
+
], e.u_dotRadius = this.dotRadius * i, e.u_gridSize = this.gridSize * i, this.effect === "halftone-cmyk" ? (e.u_angleC = this.angleC, e.u_angleM = this.angleM, e.u_angleY = this.angleY, e.u_angleK = this.angleK, e.u_showC = this.showC, e.u_showM = this.showM, e.u_showY = this.showY, e.u_showK = this.showK, e.u_intensityK = this.intensityK) : this.effect === "halftone-duotone" ? (e.u_duotoneColor = this._parseHexColor(this.duotoneColor), e.u_angle = this.angle) : this.effect === "dot-grid" ? (e.u_dotOffset = [this.dotOffsetX, this.dotOffsetY], e.u_bgColor = this._parseHexColor(this.bgColor), e.u_angle = this.angle) : this.effect === "technicolor-2strip" && (e.u_angleWarm = this.angleWarm, e.u_angleCool = this.angleCool, e.u_angleK = this.angleK, e.u_showWarm = this.showWarm, e.u_showCool = this.showCool, e.u_showK = this.showK, e.u_warmColor = this._parseHexColor(this.warmColor), e.u_coolColor = this._parseHexColor(this.coolColor), e.u_blendMode = this.blendMode, e.u_intensityK = this.intensityK), e;
|
|
590
620
|
}
|
|
591
621
|
_parseHexColor(o) {
|
|
592
|
-
const
|
|
593
|
-
return [
|
|
622
|
+
const n = o.replace("#", ""), i = parseInt(n.substring(0, 2), 16) / 255, e = parseInt(n.substring(2, 4), 16) / 255, r = parseInt(n.substring(4, 6), 16) / 255;
|
|
623
|
+
return [i, e, r];
|
|
594
624
|
}
|
|
595
625
|
};
|
|
596
|
-
R.styles =
|
|
626
|
+
R.styles = D`
|
|
597
627
|
:host {
|
|
598
628
|
display: block;
|
|
599
629
|
position: relative;
|
|
@@ -617,95 +647,98 @@ R.styles = L`
|
|
|
617
647
|
opacity: 1;
|
|
618
648
|
}
|
|
619
649
|
`;
|
|
620
|
-
let
|
|
650
|
+
let a = R;
|
|
621
651
|
l([
|
|
622
652
|
u()
|
|
623
|
-
],
|
|
653
|
+
], a.prototype, "src");
|
|
624
654
|
l([
|
|
625
655
|
u()
|
|
626
|
-
],
|
|
656
|
+
], a.prototype, "effect");
|
|
627
657
|
l([
|
|
628
658
|
u({ type: Number, attribute: "dot-radius" })
|
|
629
|
-
],
|
|
659
|
+
], a.prototype, "dotRadius");
|
|
630
660
|
l([
|
|
631
661
|
u({ type: Number, attribute: "grid-size" })
|
|
632
|
-
],
|
|
662
|
+
], a.prototype, "gridSize");
|
|
633
663
|
l([
|
|
634
664
|
u({ type: Number, attribute: "angle-c" })
|
|
635
|
-
],
|
|
665
|
+
], a.prototype, "angleC");
|
|
636
666
|
l([
|
|
637
667
|
u({ type: Number, attribute: "angle-m" })
|
|
638
|
-
],
|
|
668
|
+
], a.prototype, "angleM");
|
|
639
669
|
l([
|
|
640
670
|
u({ type: Number, attribute: "angle-y" })
|
|
641
|
-
],
|
|
671
|
+
], a.prototype, "angleY");
|
|
642
672
|
l([
|
|
643
673
|
u({ type: Number, attribute: "angle-k" })
|
|
644
|
-
],
|
|
674
|
+
], a.prototype, "angleK");
|
|
645
675
|
l([
|
|
646
676
|
u({ type: Number, attribute: "show-c" })
|
|
647
|
-
],
|
|
677
|
+
], a.prototype, "showC");
|
|
648
678
|
l([
|
|
649
679
|
u({ type: Number, attribute: "show-m" })
|
|
650
|
-
],
|
|
680
|
+
], a.prototype, "showM");
|
|
651
681
|
l([
|
|
652
682
|
u({ type: Number, attribute: "show-y" })
|
|
653
|
-
],
|
|
683
|
+
], a.prototype, "showY");
|
|
654
684
|
l([
|
|
655
685
|
u({ type: Number, attribute: "show-k" })
|
|
656
|
-
],
|
|
686
|
+
], a.prototype, "showK");
|
|
657
687
|
l([
|
|
658
688
|
u({ type: Number, attribute: "intensity-k" })
|
|
659
|
-
],
|
|
689
|
+
], a.prototype, "intensityK");
|
|
660
690
|
l([
|
|
661
691
|
u({ attribute: "duotone-color" })
|
|
662
|
-
],
|
|
692
|
+
], a.prototype, "duotoneColor");
|
|
663
693
|
l([
|
|
664
694
|
u({ type: Number })
|
|
665
|
-
],
|
|
695
|
+
], a.prototype, "angle");
|
|
666
696
|
l([
|
|
667
697
|
u({ type: Number, attribute: "dot-offset-x" })
|
|
668
|
-
],
|
|
698
|
+
], a.prototype, "dotOffsetX");
|
|
669
699
|
l([
|
|
670
700
|
u({ type: Number, attribute: "dot-offset-y" })
|
|
671
|
-
],
|
|
701
|
+
], a.prototype, "dotOffsetY");
|
|
672
702
|
l([
|
|
673
703
|
u({ attribute: "bg-color" })
|
|
674
|
-
],
|
|
704
|
+
], a.prototype, "bgColor");
|
|
675
705
|
l([
|
|
676
706
|
u({ type: Number, attribute: "angle-warm" })
|
|
677
|
-
],
|
|
707
|
+
], a.prototype, "angleWarm");
|
|
678
708
|
l([
|
|
679
709
|
u({ type: Number, attribute: "angle-cool" })
|
|
680
|
-
],
|
|
710
|
+
], a.prototype, "angleCool");
|
|
681
711
|
l([
|
|
682
712
|
u({ type: Number, attribute: "show-warm" })
|
|
683
|
-
],
|
|
713
|
+
], a.prototype, "showWarm");
|
|
684
714
|
l([
|
|
685
715
|
u({ type: Number, attribute: "show-cool" })
|
|
686
|
-
],
|
|
716
|
+
], a.prototype, "showCool");
|
|
687
717
|
l([
|
|
688
718
|
u({ attribute: "warm-color" })
|
|
689
|
-
],
|
|
719
|
+
], a.prototype, "warmColor");
|
|
690
720
|
l([
|
|
691
721
|
u({ attribute: "cool-color" })
|
|
692
|
-
],
|
|
722
|
+
], a.prototype, "coolColor");
|
|
723
|
+
l([
|
|
724
|
+
u({ type: Number, attribute: "blend-mode" })
|
|
725
|
+
], a.prototype, "blendMode");
|
|
693
726
|
l([
|
|
694
727
|
u({ type: Number, attribute: "loading-blur" })
|
|
695
|
-
],
|
|
728
|
+
], a.prototype, "loadingBlur");
|
|
696
729
|
l([
|
|
697
730
|
w()
|
|
698
|
-
],
|
|
731
|
+
], a.prototype, "_webglAvailable");
|
|
699
732
|
l([
|
|
700
733
|
w()
|
|
701
|
-
],
|
|
734
|
+
], a.prototype, "_snapshotUrl");
|
|
702
735
|
l([
|
|
703
736
|
w()
|
|
704
|
-
],
|
|
705
|
-
customElements.get("some-shade-image") || customElements.define("some-shade-image",
|
|
737
|
+
], a.prototype, "_snapshotLoaded");
|
|
738
|
+
customElements.get("some-shade-image") || customElements.define("some-shade-image", a);
|
|
706
739
|
export {
|
|
707
|
-
|
|
740
|
+
a as SomeShadeImage,
|
|
708
741
|
G as get,
|
|
709
742
|
Z as list,
|
|
710
|
-
|
|
743
|
+
v as register
|
|
711
744
|
};
|
package/dist/some-shade.umd.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(function(c,m){typeof exports=="object"&&typeof module<"u"?m(exports,require("lit"),require("lit/decorators.js")):typeof define=="function"&&define.amd?define(["exports","lit","lit/decorators.js"],m):(c=typeof globalThis<"u"?globalThis:c||self,m(c.SomeShade={},c.Lit,c.LitDecorators))})(this,(function(c,m,l){"use strict";function k(
|
|
1
|
+
(function(c,m){typeof exports=="object"&&typeof module<"u"?m(exports,require("lit"),require("lit/decorators.js")):typeof define=="function"&&define.amd?define(["exports","lit","lit/decorators.js"],m):(c=typeof globalThis<"u"?globalThis:c||self,m(c.SomeShade={},c.Lit,c.LitDecorators))})(this,(function(c,m,l){"use strict";function k(e){return e.getContext("webgl",{alpha:!0,premultipliedAlpha:!1,preserveDrawingBuffer:!0})}function S(e,o,n){const i=e.createShader(o);if(!i)throw new Error("Failed to create shader");if(e.shaderSource(i,n),e.compileShader(i),!e.getShaderParameter(i,e.COMPILE_STATUS)){const t=e.getShaderInfoLog(i);throw e.deleteShader(i),new Error(`Shader compile error: ${t}`)}return i}function D(e,o,n){const i=S(e,e.VERTEX_SHADER,o),t=S(e,e.FRAGMENT_SHADER,n),a=e.createProgram();if(!a)throw new Error("Failed to create program");if(e.attachShader(a,i),e.attachShader(a,t),e.linkProgram(a),!e.getProgramParameter(a,e.LINK_STATUS)){const d=e.getProgramInfoLog(a);throw e.deleteProgram(a),new Error(`Program link error: ${d}`)}e.deleteShader(i),e.deleteShader(t);const f=new Map,p=e.getProgramParameter(a,e.ACTIVE_ATTRIBUTES);for(let d=0;d<p;d++){const h=e.getActiveAttrib(a,d);h&&f.set(h.name,e.getAttribLocation(a,h.name))}const s=new Map,v=e.getProgramParameter(a,e.ACTIVE_UNIFORMS);for(let d=0;d<v;d++){const h=e.getActiveUniform(a,d);if(h){const g=e.getUniformLocation(a,h.name);g&&s.set(h.name,g)}}return{program:a,attribLocations:f,uniformLocations:s}}function L(e,o,n){for(const[i,t]of Object.entries(n)){const a=o.uniformLocations.get(i);if(a){if(typeof t=="number")e.uniform1f(a,t);else if(Array.isArray(t))switch(t.length){case 2:e.uniform2fv(a,t);break;case 3:e.uniform3fv(a,t);break;case 4:e.uniform4fv(a,t);break}}}}function z(e,o){const n=e.createTexture();if(!n)throw new Error("Failed to create texture");return e.bindTexture(e.TEXTURE_2D,n),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,e.RGBA,e.UNSIGNED_BYTE,o),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR),{texture:n,width:o.naturalWidth,height:o.naturalHeight}}function M(e,o){const n=new Float32Array([-1,-1,0,1,1,-1,1,1,-1,1,0,0,1,1,1,0]),i=e.createBuffer();if(!i)throw new Error("Failed to create buffer");e.bindBuffer(e.ARRAY_BUFFER,i),e.bufferData(e.ARRAY_BUFFER,n,e.STATIC_DRAW);const t=4*Float32Array.BYTES_PER_ELEMENT,a=o.attribLocations.get("a_position");a!==void 0&&a!==-1&&(e.enableVertexAttribArray(a),e.vertexAttribPointer(a,2,e.FLOAT,!1,t,0));const f=o.attribLocations.get("a_texCoord");return f!==void 0&&f!==-1&&(e.enableVertexAttribArray(f),e.vertexAttribPointer(f,2,e.FLOAT,!1,t,2*Float32Array.BYTES_PER_ELEMENT)),i}function P(e){e.drawArrays(e.TRIANGLE_STRIP,0,4)}const O=`precision mediump float;
|
|
2
2
|
|
|
3
3
|
varying vec2 v_texCoord;
|
|
4
4
|
|
|
@@ -84,7 +84,7 @@ void main() {
|
|
|
84
84
|
|
|
85
85
|
gl_FragColor = vec4(outR, outG, outB, texture2D(u_image, v_texCoord).a);
|
|
86
86
|
}
|
|
87
|
-
`,
|
|
87
|
+
`,b=`attribute vec2 a_position;
|
|
88
88
|
attribute vec2 a_texCoord;
|
|
89
89
|
varying vec2 v_texCoord;
|
|
90
90
|
|
|
@@ -92,7 +92,7 @@ void main() {
|
|
|
92
92
|
gl_Position = vec4(a_position, 0.0, 1.0);
|
|
93
93
|
v_texCoord = a_texCoord;
|
|
94
94
|
}
|
|
95
|
-
`,
|
|
95
|
+
`,I={name:"halftone-cmyk",fragmentShader:O,vertexShader:b,uniforms:[{name:"u_dotRadius",type:"float",default:4,attribute:"dot-radius"},{name:"u_gridSize",type:"float",default:8,attribute:"grid-size"},{name:"u_angleC",type:"float",default:15,attribute:"angle-c"},{name:"u_angleM",type:"float",default:75,attribute:"angle-m"},{name:"u_angleY",type:"float",default:0,attribute:"angle-y"},{name:"u_angleK",type:"float",default:45,attribute:"angle-k"},{name:"u_showC",type:"float",default:1,attribute:"show-c"},{name:"u_showM",type:"float",default:1,attribute:"show-m"},{name:"u_showY",type:"float",default:1,attribute:"show-y"},{name:"u_showK",type:"float",default:1,attribute:"show-k"},{name:"u_intensityK",type:"float",default:1,attribute:"intensity-k"}]},V={name:"halftone-duotone",fragmentShader:`precision mediump float;
|
|
96
96
|
|
|
97
97
|
varying vec2 v_texCoord;
|
|
98
98
|
|
|
@@ -134,7 +134,7 @@ void main() {
|
|
|
134
134
|
|
|
135
135
|
gl_FragColor = vec4(result, color.a);
|
|
136
136
|
}
|
|
137
|
-
`,vertexShader:
|
|
137
|
+
`,vertexShader:b,uniforms:[{name:"u_dotRadius",type:"float",default:4,attribute:"dot-radius"},{name:"u_gridSize",type:"float",default:8,attribute:"grid-size"},{name:"u_duotoneColor",type:"vec3",default:[0,.6,.8],attribute:"duotone-color"},{name:"u_angle",type:"float",default:0,attribute:"angle"}]},W={name:"dot-grid",fragmentShader:`precision mediump float;
|
|
138
138
|
|
|
139
139
|
varying vec2 v_texCoord;
|
|
140
140
|
|
|
@@ -190,7 +190,7 @@ void main() {
|
|
|
190
190
|
|
|
191
191
|
gl_FragColor = vec4(result, 1.0);
|
|
192
192
|
}
|
|
193
|
-
`,vertexShader:
|
|
193
|
+
`,vertexShader:b,uniforms:[{name:"u_dotRadius",type:"float",default:4,attribute:"dot-radius"},{name:"u_gridSize",type:"float",default:8,attribute:"grid-size"},{name:"u_dotOffset",type:"vec2",default:[.5,.5],attribute:"dot-offset"},{name:"u_bgColor",type:"vec3",default:[1,1,1],attribute:"bg-color"},{name:"u_angle",type:"float",default:0,attribute:"angle"}]},N={name:"technicolor-2strip",fragmentShader:`precision mediump float;
|
|
194
194
|
|
|
195
195
|
varying vec2 v_texCoord;
|
|
196
196
|
|
|
@@ -206,6 +206,8 @@ uniform float u_showCool;
|
|
|
206
206
|
uniform float u_showK;
|
|
207
207
|
uniform vec3 u_warmColor;
|
|
208
208
|
uniform vec3 u_coolColor;
|
|
209
|
+
uniform float u_blendMode;
|
|
210
|
+
uniform float u_intensityK;
|
|
209
211
|
|
|
210
212
|
float halftone(vec2 uv, float angle, float channelValue, float gridSize, float dotRadius) {
|
|
211
213
|
float rad = radians(angle);
|
|
@@ -232,28 +234,53 @@ void main() {
|
|
|
232
234
|
|
|
233
235
|
// Black channel: derived from overall darkness
|
|
234
236
|
float k = 1.0 - max(warmSep, coolSep);
|
|
237
|
+
k = clamp(k * u_intensityK, 0.0, 1.0);
|
|
235
238
|
|
|
236
239
|
// Halftone dots for each channel
|
|
237
240
|
float warmDot = halftone(uv, u_angleWarm, warmSep, u_gridSize, u_dotRadius) * u_showWarm;
|
|
238
241
|
float coolDot = halftone(uv, u_angleCool, coolSep, u_gridSize, u_dotRadius) * u_showCool;
|
|
239
242
|
float kDot = halftone(uv, u_angleK, k, u_gridSize, u_dotRadius) * u_showK;
|
|
240
243
|
|
|
241
|
-
//
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
244
|
+
// Blend modes affect how warm and cool dots combine where they overlap.
|
|
245
|
+
// All modes use white paper; individual dots look the same.
|
|
246
|
+
// Only the overlap regions differ between modes.
|
|
247
|
+
vec3 overlap;
|
|
248
|
+
if (u_blendMode < 0.5) {
|
|
249
|
+
// Subtractive: dye overlap absorbs more light (darker)
|
|
250
|
+
overlap = u_warmColor + u_coolColor - vec3(1.0);
|
|
251
|
+
} else if (u_blendMode < 1.5) {
|
|
252
|
+
// Additive: light overlap adds up (brighter)
|
|
253
|
+
overlap = u_warmColor + u_coolColor;
|
|
254
|
+
} else {
|
|
255
|
+
// Screen: soft additive overlap with natural clamping
|
|
256
|
+
overlap = vec3(1.0) - (vec3(1.0) - u_warmColor) * (vec3(1.0) - u_coolColor);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// Decompose into four halftone regions
|
|
260
|
+
float onlyWarm = warmDot * (1.0 - coolDot);
|
|
261
|
+
float onlyCool = coolDot * (1.0 - warmDot);
|
|
262
|
+
float both = warmDot * coolDot;
|
|
263
|
+
float neither = (1.0 - warmDot) * (1.0 - coolDot);
|
|
264
|
+
|
|
265
|
+
// Composite: white paper base, colored dots, blend-mode-dependent overlap
|
|
266
|
+
vec3 result = neither * vec3(1.0)
|
|
267
|
+
+ onlyWarm * u_warmColor
|
|
268
|
+
+ onlyCool * u_coolColor
|
|
269
|
+
+ both * overlap;
|
|
270
|
+
|
|
271
|
+
// K channel darkening with intensity control
|
|
272
|
+
result *= (1.0 - kDot);
|
|
246
273
|
|
|
247
|
-
gl_FragColor = vec4(clamp(
|
|
274
|
+
gl_FragColor = vec4(clamp(result, 0.0, 1.0), color.a);
|
|
248
275
|
}
|
|
249
|
-
`,vertexShader:
|
|
276
|
+
`,vertexShader:b,uniforms:[{name:"u_dotRadius",type:"float",default:7,attribute:"dot-radius"},{name:"u_gridSize",type:"float",default:10,attribute:"grid-size"},{name:"u_angleWarm",type:"float",default:15,attribute:"angle-warm"},{name:"u_angleCool",type:"float",default:75,attribute:"angle-cool"},{name:"u_angleK",type:"float",default:45,attribute:"angle-k"},{name:"u_showWarm",type:"float",default:1,attribute:"show-warm"},{name:"u_showCool",type:"float",default:1,attribute:"show-cool"},{name:"u_showK",type:"float",default:1,attribute:"show-k"},{name:"u_warmColor",type:"vec3",default:[.85,.25,.06],attribute:"warm-color"},{name:"u_coolColor",type:"vec3",default:[.05,.65,.6],attribute:"cool-color"},{name:"u_blendMode",type:"float",default:1,attribute:"blend-mode"},{name:"u_intensityK",type:"float",default:1,attribute:"intensity-k"}]},C=new Map;function _(e){C.set(e.name,e)}function x(e){return C.get(e)}function F(){return Array.from(C.keys())}_(I),_(V),_(W),_(N);var B=Object.defineProperty,u=(e,o,n,i)=>{for(var t=void 0,a=e.length-1,f;a>=0;a--)(f=e[a])&&(t=f(o,n,t)||t);return t&&B(o,n,t),t};const Y=2;let E=Promise.resolve();function T(e){const o=E.then(e,e);return E=o,o}const X=new Set(["effect","dotRadius","gridSize","angleC","angleM","angleY","angleK","showC","showM","showY","showK","intensityK","duotoneColor","angle","dotOffsetX","dotOffsetY","bgColor","angleWarm","angleCool","showWarm","showCool","warmColor","coolColor","blendMode"]),R=class R extends m.LitElement{constructor(){super(...arguments),this.src="",this.effect="halftone-cmyk",this.dotRadius=4,this.gridSize=8,this.angleC=15,this.angleM=75,this.angleY=0,this.angleK=45,this.showC=1,this.showM=1,this.showY=1,this.showK=1,this.intensityK=1,this.duotoneColor="#0099cc",this.angle=0,this.dotOffsetX=.5,this.dotOffsetY=.5,this.bgColor="#ffffff",this.angleWarm=15,this.angleCool=75,this.showWarm=1,this.showCool=1,this.warmColor="#d94010",this.coolColor="#0da699",this.blendMode=1,this.loadingBlur=0,this._webglAvailable=!0,this._snapshotUrl="",this._snapshotLoaded=!1,this._image=null,this._observer=null,this._resizeObserver=null,this._lastClientWidth=0,this._visible=!1,this._needsRender=!1}render(){if(!this._webglAvailable)return m.html`<img src=${this.src} alt="" />`;const o=this.loadingBlur>0?`filter: blur(${this.loadingBlur}px)`:"";return m.html`
|
|
250
277
|
<img src=${this.src} alt="" style=${o} />
|
|
251
278
|
${this._snapshotUrl?m.html`<img
|
|
252
279
|
class="snapshot${this._snapshotLoaded?" loaded":""}"
|
|
253
280
|
src=${this._snapshotUrl}
|
|
254
281
|
@load=${this._onSnapshotLoad}
|
|
255
282
|
alt="" />`:""}
|
|
256
|
-
`}connectedCallback(){super.connectedCallback(),this._observer=new IntersectionObserver(o=>{var i;const n=this._visible;this._visible=((i=o[0])==null?void 0:i.isIntersecting)??!1,this._visible&&!n&&this._needsRender&&(this._needsRender=!1,T(()=>this._renderEffect()))},{rootMargin:"200px"}),this._observer.observe(this),this._resizeObserver=new ResizeObserver(()=>{if(!this._image)return;const o=this.clientWidth;o>0&&o!==this._lastClientWidth&&(this._lastClientWidth=o,this._scheduleRender())}),this._resizeObserver.observe(this)}updated(o){if(o.has("src")&&this.src){this._loadImage(this.src);return}if(!this._image)return;[...o.keys()].some(i=>X.has(i))&&this._scheduleRender()}disconnectedCallback(){var o,n;super.disconnectedCallback(),(o=this._observer)==null||o.disconnect(),(n=this._resizeObserver)==null||n.disconnect(),this._revokeSnapshot()}_loadImage(o){const n=new Image;n.crossOrigin="anonymous",n.onload=()=>{this._image=n,this._scheduleRender()},n.onerror=()=>{console.warn(`[some-shade] Failed to load image: ${o}`)},n.src=o}_scheduleRender(){this._visible?T(()=>this._renderEffect()):this._needsRender=!0}async _renderEffect(){var
|
|
283
|
+
`}connectedCallback(){super.connectedCallback(),this._observer=new IntersectionObserver(o=>{var i;const n=this._visible;this._visible=((i=o[0])==null?void 0:i.isIntersecting)??!1,this._visible&&!n&&this._needsRender&&(this._needsRender=!1,T(()=>this._renderEffect()))},{rootMargin:"200px"}),this._observer.observe(this),this._resizeObserver=new ResizeObserver(()=>{if(!this._image)return;const o=this.clientWidth;o>0&&o!==this._lastClientWidth&&(this._lastClientWidth=o,this._scheduleRender())}),this._resizeObserver.observe(this)}updated(o){if(o.has("src")&&this.src){this._loadImage(this.src);return}if(!this._image)return;[...o.keys()].some(i=>X.has(i))&&this._scheduleRender()}disconnectedCallback(){var o,n;super.disconnectedCallback(),(o=this._observer)==null||o.disconnect(),(n=this._resizeObserver)==null||n.disconnect(),this._revokeSnapshot()}_loadImage(o){const n=new Image;n.crossOrigin="anonymous",n.onload=()=>{this._image=n,this._scheduleRender()},n.onerror=()=>{console.warn(`[some-shade] Failed to load image: ${o}`)},n.src=o}_scheduleRender(){this._visible?T(()=>this._renderEffect()):this._needsRender=!0}async _renderEffect(){var v;if(!this._image)return;const o=x(this.effect);if(!o){console.warn(`[some-shade] Unknown effect: ${this.effect}`);return}const n=Math.min(window.devicePixelRatio||1,Y),i=this._image.naturalWidth,t=this._image.naturalHeight,a=this.clientWidth||i,f=Math.max(1,i/a);this._lastClientWidth=this.clientWidth;const p=document.createElement("canvas");p.width=i*n,p.height=t*n;const s=k(p);if(!s){this._webglAvailable=!1;return}try{const d=D(s,o.vertexShader,o.fragmentShader);s.useProgram(d.program);const h=z(s,this._image),g=M(s,d);s.viewport(0,0,p.width,p.height),s.clearColor(0,0,0,0),s.clear(s.COLOR_BUFFER_BIT),s.activeTexture(s.TEXTURE0),s.bindTexture(s.TEXTURE_2D,h.texture);const A=d.uniformLocations.get("u_image");A&&s.uniform1i(A,0),L(s,d,this._getUniformValues(h,n,f)),s.bindBuffer(s.ARRAY_BUFFER,g);const U=4*Float32Array.BYTES_PER_ELEMENT,y=d.attribLocations.get("a_position");y!==void 0&&y!==-1&&(s.enableVertexAttribArray(y),s.vertexAttribPointer(y,2,s.FLOAT,!1,U,0));const w=d.attribLocations.get("a_texCoord");w!==void 0&&w!==-1&&(s.enableVertexAttribArray(w),s.vertexAttribPointer(w,2,s.FLOAT,!1,U,2*Float32Array.BYTES_PER_ELEMENT)),P(s);const K=await new Promise($=>p.toBlob($));s.deleteTexture(h.texture),s.deleteProgram(d.program),s.deleteBuffer(g),K&&(this._snapshotLoaded=!1,this._revokeSnapshot(),this._snapshotUrl=URL.createObjectURL(K))}finally{(v=s.getExtension("WEBGL_lose_context"))==null||v.loseContext()}}_onSnapshotLoad(){this._snapshotLoaded=!0}replayTransition(o=500){this._snapshotUrl&&(this._snapshotLoaded=!1,this.updateComplete.then(()=>{setTimeout(()=>{this._snapshotLoaded=!0},o)}))}_revokeSnapshot(){this._snapshotUrl&&(URL.revokeObjectURL(this._snapshotUrl),this._snapshotUrl="")}_getUniformValues(o,n,i){const t={};return t.u_resolution=[o.width*n,o.height*n],t.u_dotRadius=this.dotRadius*i,t.u_gridSize=this.gridSize*i,this.effect==="halftone-cmyk"?(t.u_angleC=this.angleC,t.u_angleM=this.angleM,t.u_angleY=this.angleY,t.u_angleK=this.angleK,t.u_showC=this.showC,t.u_showM=this.showM,t.u_showY=this.showY,t.u_showK=this.showK,t.u_intensityK=this.intensityK):this.effect==="halftone-duotone"?(t.u_duotoneColor=this._parseHexColor(this.duotoneColor),t.u_angle=this.angle):this.effect==="dot-grid"?(t.u_dotOffset=[this.dotOffsetX,this.dotOffsetY],t.u_bgColor=this._parseHexColor(this.bgColor),t.u_angle=this.angle):this.effect==="technicolor-2strip"&&(t.u_angleWarm=this.angleWarm,t.u_angleCool=this.angleCool,t.u_angleK=this.angleK,t.u_showWarm=this.showWarm,t.u_showCool=this.showCool,t.u_showK=this.showK,t.u_warmColor=this._parseHexColor(this.warmColor),t.u_coolColor=this._parseHexColor(this.coolColor),t.u_blendMode=this.blendMode,t.u_intensityK=this.intensityK),t}_parseHexColor(o){const n=o.replace("#",""),i=parseInt(n.substring(0,2),16)/255,t=parseInt(n.substring(2,4),16)/255,a=parseInt(n.substring(4,6),16)/255;return[i,t,a]}};R.styles=m.css`
|
|
257
284
|
:host {
|
|
258
285
|
display: block;
|
|
259
286
|
position: relative;
|
|
@@ -276,4 +303,4 @@ void main() {
|
|
|
276
303
|
img.snapshot.loaded {
|
|
277
304
|
opacity: 1;
|
|
278
305
|
}
|
|
279
|
-
`;let
|
|
306
|
+
`;let r=R;u([l.property()],r.prototype,"src"),u([l.property()],r.prototype,"effect"),u([l.property({type:Number,attribute:"dot-radius"})],r.prototype,"dotRadius"),u([l.property({type:Number,attribute:"grid-size"})],r.prototype,"gridSize"),u([l.property({type:Number,attribute:"angle-c"})],r.prototype,"angleC"),u([l.property({type:Number,attribute:"angle-m"})],r.prototype,"angleM"),u([l.property({type:Number,attribute:"angle-y"})],r.prototype,"angleY"),u([l.property({type:Number,attribute:"angle-k"})],r.prototype,"angleK"),u([l.property({type:Number,attribute:"show-c"})],r.prototype,"showC"),u([l.property({type:Number,attribute:"show-m"})],r.prototype,"showM"),u([l.property({type:Number,attribute:"show-y"})],r.prototype,"showY"),u([l.property({type:Number,attribute:"show-k"})],r.prototype,"showK"),u([l.property({type:Number,attribute:"intensity-k"})],r.prototype,"intensityK"),u([l.property({attribute:"duotone-color"})],r.prototype,"duotoneColor"),u([l.property({type:Number})],r.prototype,"angle"),u([l.property({type:Number,attribute:"dot-offset-x"})],r.prototype,"dotOffsetX"),u([l.property({type:Number,attribute:"dot-offset-y"})],r.prototype,"dotOffsetY"),u([l.property({attribute:"bg-color"})],r.prototype,"bgColor"),u([l.property({type:Number,attribute:"angle-warm"})],r.prototype,"angleWarm"),u([l.property({type:Number,attribute:"angle-cool"})],r.prototype,"angleCool"),u([l.property({type:Number,attribute:"show-warm"})],r.prototype,"showWarm"),u([l.property({type:Number,attribute:"show-cool"})],r.prototype,"showCool"),u([l.property({attribute:"warm-color"})],r.prototype,"warmColor"),u([l.property({attribute:"cool-color"})],r.prototype,"coolColor"),u([l.property({type:Number,attribute:"blend-mode"})],r.prototype,"blendMode"),u([l.property({type:Number,attribute:"loading-blur"})],r.prototype,"loadingBlur"),u([l.state()],r.prototype,"_webglAvailable"),u([l.state()],r.prototype,"_snapshotUrl"),u([l.state()],r.prototype,"_snapshotLoaded"),customElements.get("some-shade-image")||customElements.define("some-shade-image",r),c.SomeShadeImage=r,c.get=x,c.list=F,c.register=_,Object.defineProperty(c,Symbol.toStringTag,{value:"Module"})}));
|
package/package.json
CHANGED
package/dist/index.d.ts
DELETED
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import { CSSResult } from 'lit';
|
|
2
|
-
import { LitElement } from 'lit';
|
|
3
|
-
import { PropertyValues } from 'lit';
|
|
4
|
-
import { TemplateResult } from 'lit';
|
|
5
|
-
|
|
6
|
-
export declare interface EffectDefinition {
|
|
7
|
-
name: string;
|
|
8
|
-
fragmentShader: string;
|
|
9
|
-
vertexShader: string;
|
|
10
|
-
uniforms: UniformDefinition[];
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export declare function get(name: string): EffectDefinition | undefined;
|
|
14
|
-
|
|
15
|
-
export declare function list(): string[];
|
|
16
|
-
|
|
17
|
-
export declare function register(effect: EffectDefinition): void;
|
|
18
|
-
|
|
19
|
-
export declare class SomeShadeImage extends LitElement {
|
|
20
|
-
static styles: CSSResult;
|
|
21
|
-
src: string;
|
|
22
|
-
effect: string;
|
|
23
|
-
dotRadius: number;
|
|
24
|
-
gridSize: number;
|
|
25
|
-
angleC: number;
|
|
26
|
-
angleM: number;
|
|
27
|
-
angleY: number;
|
|
28
|
-
angleK: number;
|
|
29
|
-
showC: number;
|
|
30
|
-
showM: number;
|
|
31
|
-
showY: number;
|
|
32
|
-
showK: number;
|
|
33
|
-
intensityK: number;
|
|
34
|
-
duotoneColor: string;
|
|
35
|
-
angle: number;
|
|
36
|
-
dotOffsetX: number;
|
|
37
|
-
dotOffsetY: number;
|
|
38
|
-
bgColor: string;
|
|
39
|
-
angleWarm: number;
|
|
40
|
-
angleCool: number;
|
|
41
|
-
showWarm: number;
|
|
42
|
-
showCool: number;
|
|
43
|
-
warmColor: string;
|
|
44
|
-
coolColor: string;
|
|
45
|
-
loadingBlur: number;
|
|
46
|
-
private _webglAvailable;
|
|
47
|
-
private _snapshotUrl;
|
|
48
|
-
private _snapshotLoaded;
|
|
49
|
-
private _image;
|
|
50
|
-
private _observer;
|
|
51
|
-
private _resizeObserver;
|
|
52
|
-
private _lastClientWidth;
|
|
53
|
-
private _visible;
|
|
54
|
-
private _needsRender;
|
|
55
|
-
render(): TemplateResult<1>;
|
|
56
|
-
connectedCallback(): void;
|
|
57
|
-
updated(changed: PropertyValues): void;
|
|
58
|
-
disconnectedCallback(): void;
|
|
59
|
-
private _loadImage;
|
|
60
|
-
private _scheduleRender;
|
|
61
|
-
private _renderEffect;
|
|
62
|
-
private _onSnapshotLoad;
|
|
63
|
-
/** Hide the rendered snapshot momentarily, then fade it back in.
|
|
64
|
-
* Useful for previewing the loading-blur transition. */
|
|
65
|
-
replayTransition(delay?: number): void;
|
|
66
|
-
private _revokeSnapshot;
|
|
67
|
-
private _getUniformValues;
|
|
68
|
-
private _parseHexColor;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
export declare interface UniformDefinition {
|
|
72
|
-
name: string;
|
|
73
|
-
type: 'float' | 'vec2' | 'vec3' | 'vec4';
|
|
74
|
-
default: number | number[];
|
|
75
|
-
attribute?: string;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
export { }
|