@johnfmorton/some-shade 0.1.0-beta.7 → 0.1.0-beta.8
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/CHANGELOG.md +12 -0
- package/dist/index.d.ts +8 -14
- package/dist/some-shade.cjs.js +8 -8
- package/dist/some-shade.es.js +269 -212
- package/dist/some-shade.umd.js +8 -8
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.0-beta.8
|
|
4
|
+
|
|
5
|
+
- Fix mobile crashes when using multiple instances on one page
|
|
6
|
+
- Render-then-snapshot architecture: WebGL context is created, used, and torn down per render instead of held persistently
|
|
7
|
+
- Cap devicePixelRatio at 2 to reduce canvas memory on 3×+ mobile screens
|
|
8
|
+
- Global render queue serialises WebGL across all instances (at most one context at a time)
|
|
9
|
+
- IntersectionObserver defers rendering for off-screen instances until they scroll into view
|
|
10
|
+
|
|
11
|
+
## 0.1.0-beta.7
|
|
12
|
+
|
|
13
|
+
- Guard custom element registration against double-define
|
|
14
|
+
|
|
3
15
|
## 0.1.0-beta.6
|
|
4
16
|
|
|
5
17
|
- Publish as `latest` dist-tag to fix missing sidebar links (Repository, Homepage, Issues) on npmjs.com
|
package/dist/index.d.ts
CHANGED
|
@@ -35,27 +35,21 @@ export declare class SomeShadeImage extends LitElement {
|
|
|
35
35
|
dotOffsetY: number;
|
|
36
36
|
bgColor: string;
|
|
37
37
|
private _webglAvailable;
|
|
38
|
-
private
|
|
39
|
-
private _gl;
|
|
40
|
-
private _programInfo;
|
|
41
|
-
private _textureInfo;
|
|
42
|
-
private _quadBuffer;
|
|
43
|
-
private _currentEffect;
|
|
38
|
+
private _snapshotUrl;
|
|
44
39
|
private _image;
|
|
45
|
-
private
|
|
40
|
+
private _observer;
|
|
41
|
+
private _visible;
|
|
42
|
+
private _needsRender;
|
|
46
43
|
render(): TemplateResult<1>;
|
|
47
|
-
|
|
44
|
+
connectedCallback(): void;
|
|
48
45
|
updated(changed: PropertyValues): void;
|
|
49
46
|
disconnectedCallback(): void;
|
|
50
47
|
private _loadImage;
|
|
51
|
-
private
|
|
52
|
-
private
|
|
53
|
-
private
|
|
54
|
-
private _setupProgram;
|
|
48
|
+
private _scheduleRender;
|
|
49
|
+
private _renderEffect;
|
|
50
|
+
private _revokeSnapshot;
|
|
55
51
|
private _getUniformValues;
|
|
56
52
|
private _parseHexColor;
|
|
57
|
-
private _renderFrame;
|
|
58
|
-
private _cleanup;
|
|
59
53
|
}
|
|
60
54
|
|
|
61
55
|
export declare interface UniformDefinition {
|
package/dist/some-shade.cjs.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const v=require("lit"),u=require("lit/decorators.js");function k(e){return e.getContext("webgl",{alpha:!0,premultipliedAlpha:!1,preserveDrawingBuffer:!0})}function S(e,r,a){const t=e.createShader(r);if(!t)throw new Error("Failed to create shader");if(e.shaderSource(t,a),e.compileShader(t),!e.getShaderParameter(t,e.COMPILE_STATUS)){const i=e.getShaderInfoLog(t);throw e.deleteShader(t),new Error(`Shader compile error: ${i}`)}return t}function w(e,r,a){const t=S(e,e.VERTEX_SHADER,r),i=S(e,e.FRAGMENT_SHADER,a),n=e.createProgram();if(!n)throw new Error("Failed to create program");if(e.attachShader(n,t),e.attachShader(n,i),e.linkProgram(n),!e.getProgramParameter(n,e.LINK_STATUS)){const f=e.getProgramInfoLog(n);throw e.deleteProgram(n),new Error(`Program link error: ${f}`)}e.deleteShader(t),e.deleteShader(i);const o=new Map,_=e.getProgramParameter(n,e.ACTIVE_ATTRIBUTES);for(let f=0;f<_;f++){const c=e.getActiveAttrib(n,f);c&&o.set(c.name,e.getAttribLocation(n,c.name))}const d=new Map,m=e.getProgramParameter(n,e.ACTIVE_UNIFORMS);for(let f=0;f<m;f++){const c=e.getActiveUniform(n,f);if(c){const h=e.getUniformLocation(n,c.name);h&&d.set(c.name,h)}}return{program:n,attribLocations:o,uniformLocations:d}}function D(e,r,a){for(const[t,i]of Object.entries(a)){const n=r.uniformLocations.get(t);if(n){if(typeof i=="number")e.uniform1f(n,i);else if(Array.isArray(i))switch(i.length){case 2:e.uniform2fv(n,i);break;case 3:e.uniform3fv(n,i);break;case 4:e.uniform4fv(n,i);break}}}}function L(e,r){const a=e.createTexture();if(!a)throw new Error("Failed to create texture");return e.bindTexture(e.TEXTURE_2D,a),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,e.RGBA,e.UNSIGNED_BYTE,r),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:a,width:r.naturalWidth,height:r.naturalHeight}}function P(e,r){const a=new Float32Array([-1,-1,0,1,1,-1,1,1,-1,1,0,0,1,1,1,0]),t=e.createBuffer();if(!t)throw new Error("Failed to create buffer");e.bindBuffer(e.ARRAY_BUFFER,t),e.bufferData(e.ARRAY_BUFFER,a,e.STATIC_DRAW);const i=4*Float32Array.BYTES_PER_ELEMENT,n=r.attribLocations.get("a_position");n!==void 0&&n!==-1&&(e.enableVertexAttribArray(n),e.vertexAttribPointer(n,2,e.FLOAT,!1,i,0));const o=r.attribLocations.get("a_texCoord");return o!==void 0&&o!==-1&&(e.enableVertexAttribArray(o),e.vertexAttribPointer(o,2,e.FLOAT,!1,i,2*Float32Array.BYTES_PER_ELEMENT)),t}function V(e){e.drawArrays(e.TRIANGLE_STRIP,0,4)}const O=`precision mediump float;
|
|
2
2
|
|
|
3
3
|
varying vec2 v_texCoord;
|
|
4
4
|
|
|
@@ -54,7 +54,7 @@ void main() {
|
|
|
54
54
|
|
|
55
55
|
gl_FragColor = vec4(outR, outG, outB, color.a);
|
|
56
56
|
}
|
|
57
|
-
`,
|
|
57
|
+
`,y=`attribute vec2 a_position;
|
|
58
58
|
attribute vec2 a_texCoord;
|
|
59
59
|
varying vec2 v_texCoord;
|
|
60
60
|
|
|
@@ -62,7 +62,7 @@ void main() {
|
|
|
62
62
|
gl_Position = vec4(a_position, 0.0, 1.0);
|
|
63
63
|
v_texCoord = a_texCoord;
|
|
64
64
|
}
|
|
65
|
-
`,
|
|
65
|
+
`,F={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"}]},z=`precision mediump float;
|
|
66
66
|
|
|
67
67
|
varying vec2 v_texCoord;
|
|
68
68
|
|
|
@@ -97,7 +97,7 @@ void main() {
|
|
|
97
97
|
|
|
98
98
|
gl_FragColor = vec4(result, color.a);
|
|
99
99
|
}
|
|
100
|
-
`,
|
|
100
|
+
`,M={name:"halftone-duotone",fragmentShader:z,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"}]},I=`precision mediump float;
|
|
101
101
|
|
|
102
102
|
varying vec2 v_texCoord;
|
|
103
103
|
|
|
@@ -166,7 +166,7 @@ void main() {
|
|
|
166
166
|
vec2 sortedUV = spanStartUV + step * float(rank);
|
|
167
167
|
gl_FragColor = texture2D(u_image, sortedUV);
|
|
168
168
|
}
|
|
169
|
-
`,
|
|
169
|
+
`,N={name:"pixel-sort",fragmentShader:I,vertexShader:y,uniforms:[{name:"u_threshold",type:"float",default:.5,attribute:"threshold"},{name:"u_direction",type:"float",default:0,attribute:"sort-direction"},{name:"u_span",type:"float",default:64,attribute:"sort-span"}]},B=`precision mediump float;
|
|
170
170
|
|
|
171
171
|
varying vec2 v_texCoord;
|
|
172
172
|
|
|
@@ -211,15 +211,15 @@ void main() {
|
|
|
211
211
|
|
|
212
212
|
gl_FragColor = vec4(result, 1.0);
|
|
213
213
|
}
|
|
214
|
-
`,
|
|
214
|
+
`,Y={name:"dot-grid",fragmentShader:B,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"}]},E=new Map;function p(e){E.set(e.name,e)}function U(e){return E.get(e)}function K(){return Array.from(E.keys())}p(F);p(M);p(N);p(Y);var X=Object.defineProperty,l=(e,r,a,t)=>{for(var i=void 0,n=e.length-1,o;n>=0;n--)(o=e[n])&&(i=o(r,a,i)||i);return i&&X(r,a,i),i};const G=2;let C=Promise.resolve();function T(e){const r=C.then(e,e);return C=r,r}const W=new Set(["effect","dotRadius","gridSize","angleC","angleM","angleY","angleK","duotoneColor","angle","threshold","sortDirection","sortSpan","dotOffsetX","dotOffsetY","bgColor"]),R=class R extends v.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.duotoneColor="#0099cc",this.angle=0,this.threshold=.5,this.sortDirection=0,this.sortSpan=64,this.dotOffsetX=.5,this.dotOffsetY=.5,this.bgColor="#ffffff",this._webglAvailable=!0,this._snapshotUrl="",this._image=null,this._observer=null,this._visible=!1,this._needsRender=!1}render(){return this._webglAvailable?v.html`<img src=${this._snapshotUrl||this.src} alt="" />`:v.html`<img src=${this.src} alt="" />`}connectedCallback(){super.connectedCallback(),this._observer=new IntersectionObserver(r=>{var t;const a=this._visible;this._visible=((t=r[0])==null?void 0:t.isIntersecting)??!1,this._visible&&!a&&this._needsRender&&(this._needsRender=!1,T(()=>this._renderEffect()))},{rootMargin:"200px"}),this._observer.observe(this)}updated(r){if(r.has("src")&&this.src){this._loadImage(this.src);return}if(!this._image)return;[...r.keys()].some(t=>W.has(t))&&this._scheduleRender()}disconnectedCallback(){var r;super.disconnectedCallback(),(r=this._observer)==null||r.disconnect(),this._revokeSnapshot()}_loadImage(r){const a=new Image;a.crossOrigin="anonymous",a.onload=()=>{this._image=a,this._scheduleRender()},a.onerror=()=>{console.warn(`[some-shade] Failed to load image: ${r}`)},a.src=r}_scheduleRender(){this._visible?T(()=>this._renderEffect()):this._needsRender=!0}async _renderEffect(){var _;if(!this._image)return;const r=U(this.effect);if(!r){console.warn(`[some-shade] Unknown effect: ${this.effect}`);return}const a=Math.min(window.devicePixelRatio||1,G),t=this._image.naturalWidth,i=this._image.naturalHeight,n=document.createElement("canvas");n.width=t*a,n.height=i*a;const o=k(n);if(!o){this._webglAvailable=!1;return}try{const d=w(o,r.vertexShader,r.fragmentShader);o.useProgram(d.program);const m=L(o,this._image),f=P(o,d);o.viewport(0,0,n.width,n.height),o.clearColor(0,0,0,0),o.clear(o.COLOR_BUFFER_BIT),o.activeTexture(o.TEXTURE0),o.bindTexture(o.TEXTURE_2D,m.texture);const c=d.uniformLocations.get("u_image");c&&o.uniform1i(c,0),D(o,d,this._getUniformValues(m,a)),o.bindBuffer(o.ARRAY_BUFFER,f);const h=4*Float32Array.BYTES_PER_ELEMENT,g=d.attribLocations.get("a_position");g!==void 0&&g!==-1&&(o.enableVertexAttribArray(g),o.vertexAttribPointer(g,2,o.FLOAT,!1,h,0));const b=d.attribLocations.get("a_texCoord");b!==void 0&&b!==-1&&(o.enableVertexAttribArray(b),o.vertexAttribPointer(b,2,o.FLOAT,!1,h,2*Float32Array.BYTES_PER_ELEMENT)),V(o);const x=await new Promise(A=>n.toBlob(A));o.deleteTexture(m.texture),o.deleteProgram(d.program),o.deleteBuffer(f),x&&(this._revokeSnapshot(),this._snapshotUrl=URL.createObjectURL(x))}finally{(_=o.getExtension("WEBGL_lose_context"))==null||_.loseContext()}}_revokeSnapshot(){this._snapshotUrl&&(URL.revokeObjectURL(this._snapshotUrl),this._snapshotUrl="")}_getUniformValues(r,a){const t={};return t.u_resolution=[r.width*a,r.height*a],t.u_dotRadius=this.dotRadius,t.u_gridSize=this.gridSize,this.effect==="halftone-cmyk"?(t.u_angleC=this.angleC,t.u_angleM=this.angleM,t.u_angleY=this.angleY,t.u_angleK=this.angleK):this.effect==="halftone-duotone"?(t.u_duotoneColor=this._parseHexColor(this.duotoneColor),t.u_angle=this.angle):this.effect==="pixel-sort"?(t.u_threshold=this.threshold,t.u_direction=this.sortDirection,t.u_span=this.sortSpan):this.effect==="dot-grid"&&(t.u_dotOffset=[this.dotOffsetX,this.dotOffsetY],t.u_bgColor=this._parseHexColor(this.bgColor)),t}_parseHexColor(r){const a=r.replace("#",""),t=parseInt(a.substring(0,2),16)/255,i=parseInt(a.substring(2,4),16)/255,n=parseInt(a.substring(4,6),16)/255;return[t,i,n]}};R.styles=v.css`
|
|
215
215
|
:host {
|
|
216
216
|
display: block;
|
|
217
217
|
position: relative;
|
|
218
218
|
overflow: hidden;
|
|
219
219
|
}
|
|
220
|
-
|
|
220
|
+
img {
|
|
221
221
|
display: block;
|
|
222
222
|
width: 100%;
|
|
223
223
|
height: auto;
|
|
224
224
|
}
|
|
225
|
-
`;let
|
|
225
|
+
`;let s=R;l([u.property()],s.prototype,"src");l([u.property()],s.prototype,"effect");l([u.property({type:Number,attribute:"dot-radius"})],s.prototype,"dotRadius");l([u.property({type:Number,attribute:"grid-size"})],s.prototype,"gridSize");l([u.property({type:Number,attribute:"angle-c"})],s.prototype,"angleC");l([u.property({type:Number,attribute:"angle-m"})],s.prototype,"angleM");l([u.property({type:Number,attribute:"angle-y"})],s.prototype,"angleY");l([u.property({type:Number,attribute:"angle-k"})],s.prototype,"angleK");l([u.property({attribute:"duotone-color"})],s.prototype,"duotoneColor");l([u.property({type:Number})],s.prototype,"angle");l([u.property({type:Number})],s.prototype,"threshold");l([u.property({type:Number,attribute:"sort-direction"})],s.prototype,"sortDirection");l([u.property({type:Number,attribute:"sort-span"})],s.prototype,"sortSpan");l([u.property({type:Number,attribute:"dot-offset-x"})],s.prototype,"dotOffsetX");l([u.property({type:Number,attribute:"dot-offset-y"})],s.prototype,"dotOffsetY");l([u.property({attribute:"bg-color"})],s.prototype,"bgColor");l([u.state()],s.prototype,"_webglAvailable");l([u.state()],s.prototype,"_snapshotUrl");customElements.get("some-shade-image")||customElements.define("some-shade-image",s);exports.SomeShadeImage=s;exports.get=U;exports.list=K;exports.register=p;
|
package/dist/some-shade.es.js
CHANGED
|
@@ -1,72 +1,72 @@
|
|
|
1
|
-
import { LitElement as
|
|
2
|
-
import { property as
|
|
3
|
-
function
|
|
4
|
-
return
|
|
1
|
+
import { LitElement as k, css as w, html as x } from "lit";
|
|
2
|
+
import { property as l, state as U } from "lit/decorators.js";
|
|
3
|
+
function D(e) {
|
|
4
|
+
return e.getContext("webgl", {
|
|
5
5
|
alpha: !0,
|
|
6
6
|
premultipliedAlpha: !1,
|
|
7
7
|
preserveDrawingBuffer: !0
|
|
8
8
|
});
|
|
9
9
|
}
|
|
10
|
-
function
|
|
11
|
-
const
|
|
12
|
-
if (!
|
|
13
|
-
if (
|
|
14
|
-
const
|
|
15
|
-
throw
|
|
10
|
+
function C(e, o, a) {
|
|
11
|
+
const t = e.createShader(o);
|
|
12
|
+
if (!t) throw new Error("Failed to create shader");
|
|
13
|
+
if (e.shaderSource(t, a), e.compileShader(t), !e.getShaderParameter(t, e.COMPILE_STATUS)) {
|
|
14
|
+
const i = e.getShaderInfoLog(t);
|
|
15
|
+
throw e.deleteShader(t), new Error(`Shader compile error: ${i}`);
|
|
16
16
|
}
|
|
17
|
-
return
|
|
17
|
+
return t;
|
|
18
18
|
}
|
|
19
|
-
function
|
|
20
|
-
const
|
|
19
|
+
function L(e, o, a) {
|
|
20
|
+
const t = C(e, e.VERTEX_SHADER, o), i = C(e, e.FRAGMENT_SHADER, a), r = e.createProgram();
|
|
21
21
|
if (!r) throw new Error("Failed to create program");
|
|
22
|
-
if (
|
|
23
|
-
const
|
|
24
|
-
throw
|
|
22
|
+
if (e.attachShader(r, t), e.attachShader(r, i), e.linkProgram(r), !e.getProgramParameter(r, e.LINK_STATUS)) {
|
|
23
|
+
const f = e.getProgramInfoLog(r);
|
|
24
|
+
throw e.deleteProgram(r), new Error(`Program link error: ${f}`);
|
|
25
25
|
}
|
|
26
|
-
|
|
27
|
-
const
|
|
28
|
-
for (let
|
|
29
|
-
const
|
|
30
|
-
|
|
26
|
+
e.deleteShader(t), e.deleteShader(i);
|
|
27
|
+
const n = /* @__PURE__ */ new Map(), _ = e.getProgramParameter(r, e.ACTIVE_ATTRIBUTES);
|
|
28
|
+
for (let f = 0; f < _; f++) {
|
|
29
|
+
const c = e.getActiveAttrib(r, f);
|
|
30
|
+
c && n.set(c.name, e.getAttribLocation(r, c.name));
|
|
31
31
|
}
|
|
32
|
-
const
|
|
33
|
-
for (let
|
|
34
|
-
const
|
|
35
|
-
if (
|
|
36
|
-
const
|
|
37
|
-
|
|
32
|
+
const d = /* @__PURE__ */ new Map(), m = e.getProgramParameter(r, e.ACTIVE_UNIFORMS);
|
|
33
|
+
for (let f = 0; f < m; f++) {
|
|
34
|
+
const c = e.getActiveUniform(r, f);
|
|
35
|
+
if (c) {
|
|
36
|
+
const h = e.getUniformLocation(r, c.name);
|
|
37
|
+
h && d.set(c.name, h);
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
|
-
return { program: r, attribLocations:
|
|
40
|
+
return { program: r, attribLocations: n, uniformLocations: d };
|
|
41
41
|
}
|
|
42
|
-
function
|
|
43
|
-
for (const [
|
|
44
|
-
const r =
|
|
42
|
+
function P(e, o, a) {
|
|
43
|
+
for (const [t, i] of Object.entries(a)) {
|
|
44
|
+
const r = o.uniformLocations.get(t);
|
|
45
45
|
if (r) {
|
|
46
|
-
if (typeof
|
|
47
|
-
|
|
48
|
-
else if (Array.isArray(
|
|
49
|
-
switch (
|
|
46
|
+
if (typeof i == "number")
|
|
47
|
+
e.uniform1f(r, i);
|
|
48
|
+
else if (Array.isArray(i))
|
|
49
|
+
switch (i.length) {
|
|
50
50
|
case 2:
|
|
51
|
-
|
|
51
|
+
e.uniform2fv(r, i);
|
|
52
52
|
break;
|
|
53
53
|
case 3:
|
|
54
|
-
|
|
54
|
+
e.uniform3fv(r, i);
|
|
55
55
|
break;
|
|
56
56
|
case 4:
|
|
57
|
-
|
|
57
|
+
e.uniform4fv(r, i);
|
|
58
58
|
break;
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
|
-
function
|
|
64
|
-
const
|
|
65
|
-
if (!
|
|
66
|
-
return
|
|
63
|
+
function V(e, o) {
|
|
64
|
+
const a = e.createTexture();
|
|
65
|
+
if (!a) throw new Error("Failed to create texture");
|
|
66
|
+
return e.bindTexture(e.TEXTURE_2D, a), 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: a, width: o.naturalWidth, height: o.naturalHeight };
|
|
67
67
|
}
|
|
68
|
-
function
|
|
69
|
-
const
|
|
68
|
+
function O(e, o) {
|
|
69
|
+
const a = new Float32Array([
|
|
70
70
|
// pos.x pos.y tex.s tex.t
|
|
71
71
|
-1,
|
|
72
72
|
-1,
|
|
@@ -84,18 +84,18 @@ function I(t, e) {
|
|
|
84
84
|
1,
|
|
85
85
|
1,
|
|
86
86
|
0
|
|
87
|
-
]),
|
|
88
|
-
if (!
|
|
89
|
-
|
|
90
|
-
const
|
|
91
|
-
r !== void 0 && r !== -1 && (
|
|
92
|
-
const
|
|
93
|
-
return
|
|
87
|
+
]), t = e.createBuffer();
|
|
88
|
+
if (!t) throw new Error("Failed to create buffer");
|
|
89
|
+
e.bindBuffer(e.ARRAY_BUFFER, t), e.bufferData(e.ARRAY_BUFFER, a, e.STATIC_DRAW);
|
|
90
|
+
const i = 4 * Float32Array.BYTES_PER_ELEMENT, r = o.attribLocations.get("a_position");
|
|
91
|
+
r !== void 0 && r !== -1 && (e.enableVertexAttribArray(r), e.vertexAttribPointer(r, 2, e.FLOAT, !1, i, 0));
|
|
92
|
+
const n = o.attribLocations.get("a_texCoord");
|
|
93
|
+
return n !== void 0 && n !== -1 && (e.enableVertexAttribArray(n), e.vertexAttribPointer(n, 2, e.FLOAT, !1, i, 2 * Float32Array.BYTES_PER_ELEMENT)), t;
|
|
94
94
|
}
|
|
95
|
-
function
|
|
96
|
-
|
|
95
|
+
function F(e) {
|
|
96
|
+
e.drawArrays(e.TRIANGLE_STRIP, 0, 4);
|
|
97
97
|
}
|
|
98
|
-
const
|
|
98
|
+
const z = `precision mediump float;
|
|
99
99
|
|
|
100
100
|
varying vec2 v_texCoord;
|
|
101
101
|
|
|
@@ -151,7 +151,7 @@ void main() {
|
|
|
151
151
|
|
|
152
152
|
gl_FragColor = vec4(outR, outG, outB, color.a);
|
|
153
153
|
}
|
|
154
|
-
`,
|
|
154
|
+
`, b = `attribute vec2 a_position;
|
|
155
155
|
attribute vec2 a_texCoord;
|
|
156
156
|
varying vec2 v_texCoord;
|
|
157
157
|
|
|
@@ -159,10 +159,10 @@ void main() {
|
|
|
159
159
|
gl_Position = vec4(a_position, 0.0, 1.0);
|
|
160
160
|
v_texCoord = a_texCoord;
|
|
161
161
|
}
|
|
162
|
-
`,
|
|
162
|
+
`, M = {
|
|
163
163
|
name: "halftone-cmyk",
|
|
164
|
-
fragmentShader:
|
|
165
|
-
vertexShader:
|
|
164
|
+
fragmentShader: z,
|
|
165
|
+
vertexShader: b,
|
|
166
166
|
uniforms: [
|
|
167
167
|
{ name: "u_dotRadius", type: "float", default: 4, attribute: "dot-radius" },
|
|
168
168
|
{ name: "u_gridSize", type: "float", default: 8, attribute: "grid-size" },
|
|
@@ -171,7 +171,7 @@ void main() {
|
|
|
171
171
|
{ name: "u_angleY", type: "float", default: 0, attribute: "angle-y" },
|
|
172
172
|
{ name: "u_angleK", type: "float", default: 45, attribute: "angle-k" }
|
|
173
173
|
]
|
|
174
|
-
},
|
|
174
|
+
}, N = `precision mediump float;
|
|
175
175
|
|
|
176
176
|
varying vec2 v_texCoord;
|
|
177
177
|
|
|
@@ -206,17 +206,17 @@ void main() {
|
|
|
206
206
|
|
|
207
207
|
gl_FragColor = vec4(result, color.a);
|
|
208
208
|
}
|
|
209
|
-
`,
|
|
209
|
+
`, B = {
|
|
210
210
|
name: "halftone-duotone",
|
|
211
|
-
fragmentShader:
|
|
212
|
-
vertexShader:
|
|
211
|
+
fragmentShader: N,
|
|
212
|
+
vertexShader: b,
|
|
213
213
|
uniforms: [
|
|
214
214
|
{ name: "u_dotRadius", type: "float", default: 4, attribute: "dot-radius" },
|
|
215
215
|
{ name: "u_gridSize", type: "float", default: 8, attribute: "grid-size" },
|
|
216
216
|
{ name: "u_duotoneColor", type: "vec3", default: [0, 0.6, 0.8], attribute: "duotone-color" },
|
|
217
217
|
{ name: "u_angle", type: "float", default: 0, attribute: "angle" }
|
|
218
218
|
]
|
|
219
|
-
},
|
|
219
|
+
}, I = `precision mediump float;
|
|
220
220
|
|
|
221
221
|
varying vec2 v_texCoord;
|
|
222
222
|
|
|
@@ -285,16 +285,16 @@ void main() {
|
|
|
285
285
|
vec2 sortedUV = spanStartUV + step * float(rank);
|
|
286
286
|
gl_FragColor = texture2D(u_image, sortedUV);
|
|
287
287
|
}
|
|
288
|
-
`,
|
|
288
|
+
`, Y = {
|
|
289
289
|
name: "pixel-sort",
|
|
290
|
-
fragmentShader:
|
|
291
|
-
vertexShader:
|
|
290
|
+
fragmentShader: I,
|
|
291
|
+
vertexShader: b,
|
|
292
292
|
uniforms: [
|
|
293
293
|
{ name: "u_threshold", type: "float", default: 0.5, attribute: "threshold" },
|
|
294
294
|
{ name: "u_direction", type: "float", default: 0, attribute: "sort-direction" },
|
|
295
295
|
{ name: "u_span", type: "float", default: 64, attribute: "sort-span" }
|
|
296
296
|
]
|
|
297
|
-
},
|
|
297
|
+
}, K = `precision mediump float;
|
|
298
298
|
|
|
299
299
|
varying vec2 v_texCoord;
|
|
300
300
|
|
|
@@ -339,190 +339,247 @@ void main() {
|
|
|
339
339
|
|
|
340
340
|
gl_FragColor = vec4(result, 1.0);
|
|
341
341
|
}
|
|
342
|
-
`,
|
|
342
|
+
`, X = {
|
|
343
343
|
name: "dot-grid",
|
|
344
|
-
fragmentShader:
|
|
345
|
-
vertexShader:
|
|
344
|
+
fragmentShader: K,
|
|
345
|
+
vertexShader: b,
|
|
346
346
|
uniforms: [
|
|
347
347
|
{ name: "u_dotRadius", type: "float", default: 4, attribute: "dot-radius" },
|
|
348
348
|
{ name: "u_gridSize", type: "float", default: 8, attribute: "grid-size" },
|
|
349
349
|
{ name: "u_dotOffset", type: "vec2", default: [0.5, 0.5], attribute: "dot-offset" },
|
|
350
350
|
{ name: "u_bgColor", type: "vec3", default: [1, 1, 1], attribute: "bg-color" }
|
|
351
351
|
]
|
|
352
|
-
},
|
|
353
|
-
function
|
|
354
|
-
|
|
352
|
+
}, y = /* @__PURE__ */ new Map();
|
|
353
|
+
function v(e) {
|
|
354
|
+
y.set(e.name, e);
|
|
355
355
|
}
|
|
356
|
-
function
|
|
357
|
-
return
|
|
356
|
+
function G(e) {
|
|
357
|
+
return y.get(e);
|
|
358
358
|
}
|
|
359
|
-
function
|
|
360
|
-
return Array.from(
|
|
359
|
+
function Q() {
|
|
360
|
+
return Array.from(y.keys());
|
|
361
361
|
}
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
var
|
|
367
|
-
for (var
|
|
368
|
-
(
|
|
369
|
-
return
|
|
362
|
+
v(M);
|
|
363
|
+
v(B);
|
|
364
|
+
v(Y);
|
|
365
|
+
v(X);
|
|
366
|
+
var W = Object.defineProperty, u = (e, o, a, t) => {
|
|
367
|
+
for (var i = void 0, r = e.length - 1, n; r >= 0; r--)
|
|
368
|
+
(n = e[r]) && (i = n(o, a, i) || i);
|
|
369
|
+
return i && W(o, a, i), i;
|
|
370
370
|
};
|
|
371
|
-
const
|
|
371
|
+
const $ = 2;
|
|
372
|
+
let S = Promise.resolve();
|
|
373
|
+
function T(e) {
|
|
374
|
+
const o = S.then(e, e);
|
|
375
|
+
return S = o, o;
|
|
376
|
+
}
|
|
377
|
+
const H = /* @__PURE__ */ new Set([
|
|
378
|
+
"effect",
|
|
379
|
+
"dotRadius",
|
|
380
|
+
"gridSize",
|
|
381
|
+
"angleC",
|
|
382
|
+
"angleM",
|
|
383
|
+
"angleY",
|
|
384
|
+
"angleK",
|
|
385
|
+
"duotoneColor",
|
|
386
|
+
"angle",
|
|
387
|
+
"threshold",
|
|
388
|
+
"sortDirection",
|
|
389
|
+
"sortSpan",
|
|
390
|
+
"dotOffsetX",
|
|
391
|
+
"dotOffsetY",
|
|
392
|
+
"bgColor"
|
|
393
|
+
]), E = class E extends k {
|
|
372
394
|
constructor() {
|
|
373
|
-
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.duotoneColor = "#0099cc", this.angle = 0, this.threshold = 0.5, this.sortDirection = 0, this.sortSpan = 64, this.dotOffsetX = 0.5, this.dotOffsetY = 0.5, this.bgColor = "#ffffff", this._webglAvailable = !0, this.
|
|
395
|
+
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.duotoneColor = "#0099cc", this.angle = 0, this.threshold = 0.5, this.sortDirection = 0, this.sortSpan = 64, this.dotOffsetX = 0.5, this.dotOffsetY = 0.5, this.bgColor = "#ffffff", this._webglAvailable = !0, this._snapshotUrl = "", this._image = null, this._observer = null, this._visible = !1, this._needsRender = !1;
|
|
374
396
|
}
|
|
375
397
|
render() {
|
|
376
|
-
return this._webglAvailable ?
|
|
398
|
+
return this._webglAvailable ? x`<img src=${this._snapshotUrl || this.src} alt="" />` : x`<img src=${this.src} alt="" />`;
|
|
377
399
|
}
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
400
|
+
connectedCallback() {
|
|
401
|
+
super.connectedCallback(), this._observer = new IntersectionObserver(
|
|
402
|
+
(o) => {
|
|
403
|
+
var t;
|
|
404
|
+
const a = this._visible;
|
|
405
|
+
this._visible = ((t = o[0]) == null ? void 0 : t.isIntersecting) ?? !1, this._visible && !a && this._needsRender && (this._needsRender = !1, T(() => this._renderEffect()));
|
|
406
|
+
},
|
|
407
|
+
// Start rendering slightly before the element scrolls into view.
|
|
408
|
+
{ rootMargin: "200px" }
|
|
409
|
+
), this._observer.observe(this);
|
|
386
410
|
}
|
|
387
|
-
updated(
|
|
388
|
-
if (this.
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
return;
|
|
392
|
-
}
|
|
393
|
-
if (e.has("effect")) {
|
|
394
|
-
this._setupProgram(), this._renderFrame();
|
|
395
|
-
return;
|
|
396
|
-
}
|
|
397
|
-
this._renderFrame();
|
|
411
|
+
updated(o) {
|
|
412
|
+
if (o.has("src") && this.src) {
|
|
413
|
+
this._loadImage(this.src);
|
|
414
|
+
return;
|
|
398
415
|
}
|
|
416
|
+
if (!this._image) return;
|
|
417
|
+
[...o.keys()].some(
|
|
418
|
+
(t) => H.has(t)
|
|
419
|
+
) && this._scheduleRender();
|
|
399
420
|
}
|
|
400
421
|
disconnectedCallback() {
|
|
401
|
-
var
|
|
402
|
-
super.disconnectedCallback(), (
|
|
403
|
-
}
|
|
404
|
-
_loadImage(e) {
|
|
405
|
-
const o = new Image();
|
|
406
|
-
o.crossOrigin = "anonymous", o.onload = () => {
|
|
407
|
-
this._image = o, this._uploadTexture(), this._sizeCanvas(), this._setupProgram(), this._renderFrame();
|
|
408
|
-
}, o.onerror = () => {
|
|
409
|
-
console.warn(`[some-shade] Failed to load image: ${e}`);
|
|
410
|
-
}, o.src = e;
|
|
422
|
+
var o;
|
|
423
|
+
super.disconnectedCallback(), (o = this._observer) == null || o.disconnect(), this._revokeSnapshot();
|
|
411
424
|
}
|
|
412
|
-
|
|
413
|
-
|
|
425
|
+
// ---------------------------------------------------------------------------
|
|
426
|
+
// Image loading
|
|
427
|
+
// ---------------------------------------------------------------------------
|
|
428
|
+
_loadImage(o) {
|
|
429
|
+
const a = new Image();
|
|
430
|
+
a.crossOrigin = "anonymous", a.onload = () => {
|
|
431
|
+
this._image = a, this._scheduleRender();
|
|
432
|
+
}, a.onerror = () => {
|
|
433
|
+
console.warn(`[some-shade] Failed to load image: ${o}`);
|
|
434
|
+
}, a.src = o;
|
|
414
435
|
}
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
436
|
+
// ---------------------------------------------------------------------------
|
|
437
|
+
// Render scheduling
|
|
438
|
+
// ---------------------------------------------------------------------------
|
|
439
|
+
_scheduleRender() {
|
|
440
|
+
this._visible ? T(() => this._renderEffect()) : this._needsRender = !0;
|
|
419
441
|
}
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
442
|
+
// ---------------------------------------------------------------------------
|
|
443
|
+
// WebGL render → snapshot → tear-down
|
|
444
|
+
// ---------------------------------------------------------------------------
|
|
445
|
+
async _renderEffect() {
|
|
446
|
+
var _;
|
|
447
|
+
if (!this._image) return;
|
|
448
|
+
const o = G(this.effect);
|
|
449
|
+
if (!o) {
|
|
427
450
|
console.warn(`[some-shade] Unknown effect: ${this.effect}`);
|
|
428
451
|
return;
|
|
429
452
|
}
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
453
|
+
const a = Math.min(window.devicePixelRatio || 1, $), t = this._image.naturalWidth, i = this._image.naturalHeight, r = document.createElement("canvas");
|
|
454
|
+
r.width = t * a, r.height = i * a;
|
|
455
|
+
const n = D(r);
|
|
456
|
+
if (!n) {
|
|
457
|
+
this._webglAvailable = !1;
|
|
458
|
+
return;
|
|
459
|
+
}
|
|
460
|
+
try {
|
|
461
|
+
const d = L(
|
|
462
|
+
n,
|
|
463
|
+
o.vertexShader,
|
|
464
|
+
o.fragmentShader
|
|
465
|
+
);
|
|
466
|
+
n.useProgram(d.program);
|
|
467
|
+
const m = V(n, this._image), f = O(n, d);
|
|
468
|
+
n.viewport(0, 0, r.width, r.height), n.clearColor(0, 0, 0, 0), n.clear(n.COLOR_BUFFER_BIT), n.activeTexture(n.TEXTURE0), n.bindTexture(n.TEXTURE_2D, m.texture);
|
|
469
|
+
const c = d.uniformLocations.get("u_image");
|
|
470
|
+
c && n.uniform1i(c, 0), P(
|
|
471
|
+
n,
|
|
472
|
+
d,
|
|
473
|
+
this._getUniformValues(m, a)
|
|
474
|
+
), n.bindBuffer(n.ARRAY_BUFFER, f);
|
|
475
|
+
const h = 4 * Float32Array.BYTES_PER_ELEMENT, p = d.attribLocations.get("a_position");
|
|
476
|
+
p !== void 0 && p !== -1 && (n.enableVertexAttribArray(p), n.vertexAttribPointer(p, 2, n.FLOAT, !1, h, 0));
|
|
477
|
+
const g = d.attribLocations.get("a_texCoord");
|
|
478
|
+
g !== void 0 && g !== -1 && (n.enableVertexAttribArray(g), n.vertexAttribPointer(
|
|
479
|
+
g,
|
|
480
|
+
2,
|
|
481
|
+
n.FLOAT,
|
|
482
|
+
!1,
|
|
483
|
+
h,
|
|
484
|
+
2 * Float32Array.BYTES_PER_ELEMENT
|
|
485
|
+
)), F(n);
|
|
486
|
+
const R = await new Promise(
|
|
487
|
+
(A) => r.toBlob(A)
|
|
488
|
+
);
|
|
489
|
+
n.deleteTexture(m.texture), n.deleteProgram(d.program), n.deleteBuffer(f), R && (this._revokeSnapshot(), this._snapshotUrl = URL.createObjectURL(R));
|
|
490
|
+
} finally {
|
|
491
|
+
(_ = n.getExtension("WEBGL_lose_context")) == null || _.loseContext();
|
|
492
|
+
}
|
|
438
493
|
}
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
494
|
+
// ---------------------------------------------------------------------------
|
|
495
|
+
// Helpers
|
|
496
|
+
// ---------------------------------------------------------------------------
|
|
497
|
+
_revokeSnapshot() {
|
|
498
|
+
this._snapshotUrl && (URL.revokeObjectURL(this._snapshotUrl), this._snapshotUrl = "");
|
|
442
499
|
}
|
|
443
|
-
|
|
444
|
-
const
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
const a = 4 * Float32Array.BYTES_PER_ELEMENT, n = this._programInfo.attribLocations.get("a_position");
|
|
450
|
-
n !== void 0 && n !== -1 && (e.enableVertexAttribArray(n), e.vertexAttribPointer(n, 2, e.FLOAT, !1, a, 0));
|
|
451
|
-
const r = this._programInfo.attribLocations.get("a_texCoord");
|
|
452
|
-
r !== void 0 && r !== -1 && (e.enableVertexAttribArray(r), e.vertexAttribPointer(r, 2, e.FLOAT, !1, a, 2 * Float32Array.BYTES_PER_ELEMENT)), U(e);
|
|
500
|
+
_getUniformValues(o, a) {
|
|
501
|
+
const t = {};
|
|
502
|
+
return t.u_resolution = [
|
|
503
|
+
o.width * a,
|
|
504
|
+
o.height * a
|
|
505
|
+
], t.u_dotRadius = this.dotRadius, t.u_gridSize = this.gridSize, this.effect === "halftone-cmyk" ? (t.u_angleC = this.angleC, t.u_angleM = this.angleM, t.u_angleY = this.angleY, t.u_angleK = this.angleK) : this.effect === "halftone-duotone" ? (t.u_duotoneColor = this._parseHexColor(this.duotoneColor), t.u_angle = this.angle) : this.effect === "pixel-sort" ? (t.u_threshold = this.threshold, t.u_direction = this.sortDirection, t.u_span = this.sortSpan) : this.effect === "dot-grid" && (t.u_dotOffset = [this.dotOffsetX, this.dotOffsetY], t.u_bgColor = this._parseHexColor(this.bgColor)), t;
|
|
453
506
|
}
|
|
454
|
-
|
|
455
|
-
|
|
507
|
+
_parseHexColor(o) {
|
|
508
|
+
const a = o.replace("#", ""), t = parseInt(a.substring(0, 2), 16) / 255, i = parseInt(a.substring(2, 4), 16) / 255, r = parseInt(a.substring(4, 6), 16) / 255;
|
|
509
|
+
return [t, i, r];
|
|
456
510
|
}
|
|
457
511
|
};
|
|
458
|
-
|
|
512
|
+
E.styles = w`
|
|
459
513
|
:host {
|
|
460
514
|
display: block;
|
|
461
515
|
position: relative;
|
|
462
516
|
overflow: hidden;
|
|
463
517
|
}
|
|
464
|
-
|
|
518
|
+
img {
|
|
465
519
|
display: block;
|
|
466
520
|
width: 100%;
|
|
467
521
|
height: auto;
|
|
468
522
|
}
|
|
469
523
|
`;
|
|
470
|
-
let
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
],
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
],
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
],
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
],
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
],
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
],
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
],
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
],
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
],
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
],
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
],
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
],
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
],
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
],
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
],
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
],
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
],
|
|
522
|
-
|
|
524
|
+
let s = E;
|
|
525
|
+
u([
|
|
526
|
+
l()
|
|
527
|
+
], s.prototype, "src");
|
|
528
|
+
u([
|
|
529
|
+
l()
|
|
530
|
+
], s.prototype, "effect");
|
|
531
|
+
u([
|
|
532
|
+
l({ type: Number, attribute: "dot-radius" })
|
|
533
|
+
], s.prototype, "dotRadius");
|
|
534
|
+
u([
|
|
535
|
+
l({ type: Number, attribute: "grid-size" })
|
|
536
|
+
], s.prototype, "gridSize");
|
|
537
|
+
u([
|
|
538
|
+
l({ type: Number, attribute: "angle-c" })
|
|
539
|
+
], s.prototype, "angleC");
|
|
540
|
+
u([
|
|
541
|
+
l({ type: Number, attribute: "angle-m" })
|
|
542
|
+
], s.prototype, "angleM");
|
|
543
|
+
u([
|
|
544
|
+
l({ type: Number, attribute: "angle-y" })
|
|
545
|
+
], s.prototype, "angleY");
|
|
546
|
+
u([
|
|
547
|
+
l({ type: Number, attribute: "angle-k" })
|
|
548
|
+
], s.prototype, "angleK");
|
|
549
|
+
u([
|
|
550
|
+
l({ attribute: "duotone-color" })
|
|
551
|
+
], s.prototype, "duotoneColor");
|
|
552
|
+
u([
|
|
553
|
+
l({ type: Number })
|
|
554
|
+
], s.prototype, "angle");
|
|
555
|
+
u([
|
|
556
|
+
l({ type: Number })
|
|
557
|
+
], s.prototype, "threshold");
|
|
558
|
+
u([
|
|
559
|
+
l({ type: Number, attribute: "sort-direction" })
|
|
560
|
+
], s.prototype, "sortDirection");
|
|
561
|
+
u([
|
|
562
|
+
l({ type: Number, attribute: "sort-span" })
|
|
563
|
+
], s.prototype, "sortSpan");
|
|
564
|
+
u([
|
|
565
|
+
l({ type: Number, attribute: "dot-offset-x" })
|
|
566
|
+
], s.prototype, "dotOffsetX");
|
|
567
|
+
u([
|
|
568
|
+
l({ type: Number, attribute: "dot-offset-y" })
|
|
569
|
+
], s.prototype, "dotOffsetY");
|
|
570
|
+
u([
|
|
571
|
+
l({ attribute: "bg-color" })
|
|
572
|
+
], s.prototype, "bgColor");
|
|
573
|
+
u([
|
|
574
|
+
U()
|
|
575
|
+
], s.prototype, "_webglAvailable");
|
|
576
|
+
u([
|
|
577
|
+
U()
|
|
578
|
+
], s.prototype, "_snapshotUrl");
|
|
579
|
+
customElements.get("some-shade-image") || customElements.define("some-shade-image", s);
|
|
523
580
|
export {
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
581
|
+
s as SomeShadeImage,
|
|
582
|
+
G as get,
|
|
583
|
+
Q as list,
|
|
584
|
+
v as register
|
|
528
585
|
};
|
package/dist/some-shade.umd.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(function(
|
|
1
|
+
(function(d,h){typeof exports=="object"&&typeof module<"u"?h(exports,require("lit"),require("lit/decorators.js")):typeof define=="function"&&define.amd?define(["exports","lit","lit/decorators.js"],h):(d=typeof globalThis<"u"?globalThis:d||self,h(d.SomeShade={},d.Lit,d.LitDecorators))})(this,(function(d,h,u){"use strict";function k(e){return e.getContext("webgl",{alpha:!0,premultipliedAlpha:!1,preserveDrawingBuffer:!0})}function x(e,n,a){const t=e.createShader(n);if(!t)throw new Error("Failed to create shader");if(e.shaderSource(t,a),e.compileShader(t),!e.getShaderParameter(t,e.COMPILE_STATUS)){const i=e.getShaderInfoLog(t);throw e.deleteShader(t),new Error(`Shader compile error: ${i}`)}return t}function w(e,n,a){const t=x(e,e.VERTEX_SHADER,n),i=x(e,e.FRAGMENT_SHADER,a),o=e.createProgram();if(!o)throw new Error("Failed to create program");if(e.attachShader(o,t),e.attachShader(o,i),e.linkProgram(o),!e.getProgramParameter(o,e.LINK_STATUS)){const f=e.getProgramInfoLog(o);throw e.deleteProgram(o),new Error(`Program link error: ${f}`)}e.deleteShader(t),e.deleteShader(i);const r=new Map,v=e.getProgramParameter(o,e.ACTIVE_ATTRIBUTES);for(let f=0;f<v;f++){const m=e.getActiveAttrib(o,f);m&&r.set(m.name,e.getAttribLocation(o,m.name))}const c=new Map,_=e.getProgramParameter(o,e.ACTIVE_UNIFORMS);for(let f=0;f<_;f++){const m=e.getActiveUniform(o,f);if(m){const g=e.getUniformLocation(o,m.name);g&&c.set(m.name,g)}}return{program:o,attribLocations:r,uniformLocations:c}}function D(e,n,a){for(const[t,i]of Object.entries(a)){const o=n.uniformLocations.get(t);if(o){if(typeof i=="number")e.uniform1f(o,i);else if(Array.isArray(i))switch(i.length){case 2:e.uniform2fv(o,i);break;case 3:e.uniform3fv(o,i);break;case 4:e.uniform4fv(o,i);break}}}}function L(e,n){const a=e.createTexture();if(!a)throw new Error("Failed to create texture");return e.bindTexture(e.TEXTURE_2D,a),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,e.RGBA,e.UNSIGNED_BYTE,n),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:a,width:n.naturalWidth,height:n.naturalHeight}}function P(e,n){const a=new Float32Array([-1,-1,0,1,1,-1,1,1,-1,1,0,0,1,1,1,0]),t=e.createBuffer();if(!t)throw new Error("Failed to create buffer");e.bindBuffer(e.ARRAY_BUFFER,t),e.bufferData(e.ARRAY_BUFFER,a,e.STATIC_DRAW);const i=4*Float32Array.BYTES_PER_ELEMENT,o=n.attribLocations.get("a_position");o!==void 0&&o!==-1&&(e.enableVertexAttribArray(o),e.vertexAttribPointer(o,2,e.FLOAT,!1,i,0));const r=n.attribLocations.get("a_texCoord");return r!==void 0&&r!==-1&&(e.enableVertexAttribArray(r),e.vertexAttribPointer(r,2,e.FLOAT,!1,i,2*Float32Array.BYTES_PER_ELEMENT)),t}function V(e){e.drawArrays(e.TRIANGLE_STRIP,0,4)}const O=`precision mediump float;
|
|
2
2
|
|
|
3
3
|
varying vec2 v_texCoord;
|
|
4
4
|
|
|
@@ -54,7 +54,7 @@ void main() {
|
|
|
54
54
|
|
|
55
55
|
gl_FragColor = vec4(outR, outG, outB, color.a);
|
|
56
56
|
}
|
|
57
|
-
`,
|
|
57
|
+
`,b=`attribute vec2 a_position;
|
|
58
58
|
attribute vec2 a_texCoord;
|
|
59
59
|
varying vec2 v_texCoord;
|
|
60
60
|
|
|
@@ -62,7 +62,7 @@ void main() {
|
|
|
62
62
|
gl_Position = vec4(a_position, 0.0, 1.0);
|
|
63
63
|
v_texCoord = a_texCoord;
|
|
64
64
|
}
|
|
65
|
-
`,
|
|
65
|
+
`,F={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"}]},z={name:"halftone-duotone",fragmentShader:`precision mediump float;
|
|
66
66
|
|
|
67
67
|
varying vec2 v_texCoord;
|
|
68
68
|
|
|
@@ -97,7 +97,7 @@ void main() {
|
|
|
97
97
|
|
|
98
98
|
gl_FragColor = vec4(result, color.a);
|
|
99
99
|
}
|
|
100
|
-
`,vertexShader:
|
|
100
|
+
`,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"}]},M={name:"pixel-sort",fragmentShader:`precision mediump float;
|
|
101
101
|
|
|
102
102
|
varying vec2 v_texCoord;
|
|
103
103
|
|
|
@@ -166,7 +166,7 @@ void main() {
|
|
|
166
166
|
vec2 sortedUV = spanStartUV + step * float(rank);
|
|
167
167
|
gl_FragColor = texture2D(u_image, sortedUV);
|
|
168
168
|
}
|
|
169
|
-
`,vertexShader:
|
|
169
|
+
`,vertexShader:b,uniforms:[{name:"u_threshold",type:"float",default:.5,attribute:"threshold"},{name:"u_direction",type:"float",default:0,attribute:"sort-direction"},{name:"u_span",type:"float",default:64,attribute:"sort-span"}]},I={name:"dot-grid",fragmentShader:`precision mediump float;
|
|
170
170
|
|
|
171
171
|
varying vec2 v_texCoord;
|
|
172
172
|
|
|
@@ -211,15 +211,15 @@ void main() {
|
|
|
211
211
|
|
|
212
212
|
gl_FragColor = vec4(result, 1.0);
|
|
213
213
|
}
|
|
214
|
-
`,vertexShader:
|
|
214
|
+
`,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"}]},R=new Map;function p(e){R.set(e.name,e)}function C(e){return R.get(e)}function N(){return Array.from(R.keys())}p(F),p(z),p(M),p(I);var B=Object.defineProperty,l=(e,n,a,t)=>{for(var i=void 0,o=e.length-1,r;o>=0;o--)(r=e[o])&&(i=r(n,a,i)||i);return i&&B(n,a,i),i};const Y=2;let T=Promise.resolve();function U(e){const n=T.then(e,e);return T=n,n}const K=new Set(["effect","dotRadius","gridSize","angleC","angleM","angleY","angleK","duotoneColor","angle","threshold","sortDirection","sortSpan","dotOffsetX","dotOffsetY","bgColor"]),S=class S extends h.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.duotoneColor="#0099cc",this.angle=0,this.threshold=.5,this.sortDirection=0,this.sortSpan=64,this.dotOffsetX=.5,this.dotOffsetY=.5,this.bgColor="#ffffff",this._webglAvailable=!0,this._snapshotUrl="",this._image=null,this._observer=null,this._visible=!1,this._needsRender=!1}render(){return this._webglAvailable?h.html`<img src=${this._snapshotUrl||this.src} alt="" />`:h.html`<img src=${this.src} alt="" />`}connectedCallback(){super.connectedCallback(),this._observer=new IntersectionObserver(n=>{var t;const a=this._visible;this._visible=((t=n[0])==null?void 0:t.isIntersecting)??!1,this._visible&&!a&&this._needsRender&&(this._needsRender=!1,U(()=>this._renderEffect()))},{rootMargin:"200px"}),this._observer.observe(this)}updated(n){if(n.has("src")&&this.src){this._loadImage(this.src);return}if(!this._image)return;[...n.keys()].some(t=>K.has(t))&&this._scheduleRender()}disconnectedCallback(){var n;super.disconnectedCallback(),(n=this._observer)==null||n.disconnect(),this._revokeSnapshot()}_loadImage(n){const a=new Image;a.crossOrigin="anonymous",a.onload=()=>{this._image=a,this._scheduleRender()},a.onerror=()=>{console.warn(`[some-shade] Failed to load image: ${n}`)},a.src=n}_scheduleRender(){this._visible?U(()=>this._renderEffect()):this._needsRender=!0}async _renderEffect(){var v;if(!this._image)return;const n=C(this.effect);if(!n){console.warn(`[some-shade] Unknown effect: ${this.effect}`);return}const a=Math.min(window.devicePixelRatio||1,Y),t=this._image.naturalWidth,i=this._image.naturalHeight,o=document.createElement("canvas");o.width=t*a,o.height=i*a;const r=k(o);if(!r){this._webglAvailable=!1;return}try{const c=w(r,n.vertexShader,n.fragmentShader);r.useProgram(c.program);const _=L(r,this._image),f=P(r,c);r.viewport(0,0,o.width,o.height),r.clearColor(0,0,0,0),r.clear(r.COLOR_BUFFER_BIT),r.activeTexture(r.TEXTURE0),r.bindTexture(r.TEXTURE_2D,_.texture);const m=c.uniformLocations.get("u_image");m&&r.uniform1i(m,0),D(r,c,this._getUniformValues(_,a)),r.bindBuffer(r.ARRAY_BUFFER,f);const g=4*Float32Array.BYTES_PER_ELEMENT,y=c.attribLocations.get("a_position");y!==void 0&&y!==-1&&(r.enableVertexAttribArray(y),r.vertexAttribPointer(y,2,r.FLOAT,!1,g,0));const E=c.attribLocations.get("a_texCoord");E!==void 0&&E!==-1&&(r.enableVertexAttribArray(E),r.vertexAttribPointer(E,2,r.FLOAT,!1,g,2*Float32Array.BYTES_PER_ELEMENT)),V(r);const A=await new Promise(X=>o.toBlob(X));r.deleteTexture(_.texture),r.deleteProgram(c.program),r.deleteBuffer(f),A&&(this._revokeSnapshot(),this._snapshotUrl=URL.createObjectURL(A))}finally{(v=r.getExtension("WEBGL_lose_context"))==null||v.loseContext()}}_revokeSnapshot(){this._snapshotUrl&&(URL.revokeObjectURL(this._snapshotUrl),this._snapshotUrl="")}_getUniformValues(n,a){const t={};return t.u_resolution=[n.width*a,n.height*a],t.u_dotRadius=this.dotRadius,t.u_gridSize=this.gridSize,this.effect==="halftone-cmyk"?(t.u_angleC=this.angleC,t.u_angleM=this.angleM,t.u_angleY=this.angleY,t.u_angleK=this.angleK):this.effect==="halftone-duotone"?(t.u_duotoneColor=this._parseHexColor(this.duotoneColor),t.u_angle=this.angle):this.effect==="pixel-sort"?(t.u_threshold=this.threshold,t.u_direction=this.sortDirection,t.u_span=this.sortSpan):this.effect==="dot-grid"&&(t.u_dotOffset=[this.dotOffsetX,this.dotOffsetY],t.u_bgColor=this._parseHexColor(this.bgColor)),t}_parseHexColor(n){const a=n.replace("#",""),t=parseInt(a.substring(0,2),16)/255,i=parseInt(a.substring(2,4),16)/255,o=parseInt(a.substring(4,6),16)/255;return[t,i,o]}};S.styles=h.css`
|
|
215
215
|
:host {
|
|
216
216
|
display: block;
|
|
217
217
|
position: relative;
|
|
218
218
|
overflow: hidden;
|
|
219
219
|
}
|
|
220
|
-
|
|
220
|
+
img {
|
|
221
221
|
display: block;
|
|
222
222
|
width: 100%;
|
|
223
223
|
height: auto;
|
|
224
224
|
}
|
|
225
|
-
`;let
|
|
225
|
+
`;let s=S;l([u.property()],s.prototype,"src"),l([u.property()],s.prototype,"effect"),l([u.property({type:Number,attribute:"dot-radius"})],s.prototype,"dotRadius"),l([u.property({type:Number,attribute:"grid-size"})],s.prototype,"gridSize"),l([u.property({type:Number,attribute:"angle-c"})],s.prototype,"angleC"),l([u.property({type:Number,attribute:"angle-m"})],s.prototype,"angleM"),l([u.property({type:Number,attribute:"angle-y"})],s.prototype,"angleY"),l([u.property({type:Number,attribute:"angle-k"})],s.prototype,"angleK"),l([u.property({attribute:"duotone-color"})],s.prototype,"duotoneColor"),l([u.property({type:Number})],s.prototype,"angle"),l([u.property({type:Number})],s.prototype,"threshold"),l([u.property({type:Number,attribute:"sort-direction"})],s.prototype,"sortDirection"),l([u.property({type:Number,attribute:"sort-span"})],s.prototype,"sortSpan"),l([u.property({type:Number,attribute:"dot-offset-x"})],s.prototype,"dotOffsetX"),l([u.property({type:Number,attribute:"dot-offset-y"})],s.prototype,"dotOffsetY"),l([u.property({attribute:"bg-color"})],s.prototype,"bgColor"),l([u.state()],s.prototype,"_webglAvailable"),l([u.state()],s.prototype,"_snapshotUrl"),customElements.get("some-shade-image")||customElements.define("some-shade-image",s),d.SomeShadeImage=s,d.get=C,d.list=N,d.register=p,Object.defineProperty(d,Symbol.toStringTag,{value:"Module"})}));
|