@johnfmorton/some-shade 0.1.0-beta.1

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.
@@ -0,0 +1,68 @@
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
+ duotoneColor: string;
30
+ angle: number;
31
+ threshold: number;
32
+ sortDirection: number;
33
+ sortSpan: number;
34
+ dotOffsetX: number;
35
+ dotOffsetY: number;
36
+ bgColor: string;
37
+ private _webglAvailable;
38
+ private _canvas;
39
+ private _gl;
40
+ private _programInfo;
41
+ private _textureInfo;
42
+ private _quadBuffer;
43
+ private _currentEffect;
44
+ private _image;
45
+ private _resizeObserver;
46
+ render(): TemplateResult<1>;
47
+ firstUpdated(): void;
48
+ updated(changed: PropertyValues): void;
49
+ disconnectedCallback(): void;
50
+ private _loadImage;
51
+ private _uploadTexture;
52
+ private _sizeCanvas;
53
+ private _handleResize;
54
+ private _setupProgram;
55
+ private _getUniformValues;
56
+ private _parseHexColor;
57
+ private _renderFrame;
58
+ private _cleanup;
59
+ }
60
+
61
+ export declare interface UniformDefinition {
62
+ name: string;
63
+ type: 'float' | 'vec2' | 'vec3' | 'vec4';
64
+ default: number | number[];
65
+ attribute?: string;
66
+ }
67
+
68
+ export { }
@@ -0,0 +1,225 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=require("lit"),i=require("lit/decorators.js");function y(e){return e.getContext("webgl",{alpha:!0,premultipliedAlpha:!1,preserveDrawingBuffer:!0})}function p(e,t,o){const a=e.createShader(t);if(!a)throw new Error("Failed to create shader");if(e.shaderSource(a,o),e.compileShader(a),!e.getShaderParameter(a,e.COMPILE_STATUS)){const n=e.getShaderInfoLog(a);throw e.deleteShader(a),new Error(`Shader compile error: ${n}`)}return a}function x(e,t,o){const a=p(e,e.VERTEX_SHADER,t),n=p(e,e.FRAGMENT_SHADER,o),r=e.createProgram();if(!r)throw new Error("Failed to create program");if(e.attachShader(r,a),e.attachShader(r,n),e.linkProgram(r),!e.getProgramParameter(r,e.LINK_STATUS)){const f=e.getProgramInfoLog(r);throw e.deleteProgram(r),new Error(`Program link error: ${f}`)}e.deleteShader(a),e.deleteShader(n);const u=new Map,b=e.getProgramParameter(r,e.ACTIVE_ATTRIBUTES);for(let f=0;f<b;f++){const l=e.getActiveAttrib(r,f);l&&u.set(l.name,e.getAttribLocation(r,l.name))}const _=new Map,S=e.getProgramParameter(r,e.ACTIVE_UNIFORMS);for(let f=0;f<S;f++){const l=e.getActiveUniform(r,f);if(l){const g=e.getUniformLocation(r,l.name);g&&_.set(l.name,g)}}return{program:r,attribLocations:u,uniformLocations:_}}function E(e,t,o){for(const[a,n]of Object.entries(o)){const r=t.uniformLocations.get(a);if(r){if(typeof n=="number")e.uniform1f(r,n);else if(Array.isArray(n))switch(n.length){case 2:e.uniform2fv(r,n);break;case 3:e.uniform3fv(r,n);break;case 4:e.uniform4fv(r,n);break}}}}function C(e,t){const o=e.createTexture();if(!o)throw new Error("Failed to create texture");return e.bindTexture(e.TEXTURE_2D,o),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,e.RGBA,e.UNSIGNED_BYTE,t),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:o,width:t.naturalWidth,height:t.naturalHeight}}function I(e,t){const o=new Float32Array([-1,-1,0,1,1,-1,1,1,-1,1,0,0,1,1,1,0]),a=e.createBuffer();if(!a)throw new Error("Failed to create buffer");e.bindBuffer(e.ARRAY_BUFFER,a),e.bufferData(e.ARRAY_BUFFER,o,e.STATIC_DRAW);const n=4*Float32Array.BYTES_PER_ELEMENT,r=t.attribLocations.get("a_position");r!==void 0&&r!==-1&&(e.enableVertexAttribArray(r),e.vertexAttribPointer(r,2,e.FLOAT,!1,n,0));const u=t.attribLocations.get("a_texCoord");return u!==void 0&&u!==-1&&(e.enableVertexAttribArray(u),e.vertexAttribPointer(u,2,e.FLOAT,!1,n,2*Float32Array.BYTES_PER_ELEMENT)),a}function R(e){e.drawArrays(e.TRIANGLE_STRIP,0,4)}const T=`precision mediump float;
2
+
3
+ varying vec2 v_texCoord;
4
+
5
+ uniform sampler2D u_image;
6
+ uniform vec2 u_resolution;
7
+ uniform float u_dotRadius;
8
+ uniform float u_gridSize;
9
+ uniform float u_angleC;
10
+ uniform float u_angleM;
11
+ uniform float u_angleY;
12
+ uniform float u_angleK;
13
+
14
+ float halftone(vec2 uv, float angle, float channelValue, float gridSize, float dotRadius) {
15
+ float rad = radians(angle);
16
+ float s = sin(rad);
17
+ float c = cos(rad);
18
+ mat2 rot = mat2(c, -s, s, c);
19
+
20
+ vec2 rotUV = rot * uv;
21
+ vec2 grid = fract(rotUV / gridSize) - 0.5;
22
+
23
+ float dist = length(grid) * gridSize;
24
+ float radius = dotRadius * sqrt(channelValue);
25
+
26
+ return smoothstep(radius + 0.5, radius - 0.5, dist);
27
+ }
28
+
29
+ void main() {
30
+ vec2 uv = v_texCoord * u_resolution;
31
+ vec4 color = texture2D(u_image, v_texCoord);
32
+
33
+ float r = color.r;
34
+ float g = color.g;
35
+ float b = color.b;
36
+
37
+ // RGB to CMYK
38
+ float k = 1.0 - max(max(r, g), b);
39
+ float invK = 1.0 - k;
40
+ float cy = invK > 0.001 ? (invK - r) / invK : 0.0;
41
+ float ma = invK > 0.001 ? (invK - g) / invK : 0.0;
42
+ float ye = invK > 0.001 ? (invK - b) / invK : 0.0;
43
+
44
+ // Compute halftone dots for each channel
45
+ float cDot = halftone(uv, u_angleC, cy, u_gridSize, u_dotRadius);
46
+ float mDot = halftone(uv, u_angleM, ma, u_gridSize, u_dotRadius);
47
+ float yDot = halftone(uv, u_angleY, ye, u_gridSize, u_dotRadius);
48
+ float kDot = halftone(uv, u_angleK, k, u_gridSize, u_dotRadius);
49
+
50
+ // Subtractive color mixing on white paper
51
+ float outR = (1.0 - cDot) * (1.0 - kDot);
52
+ float outG = (1.0 - mDot) * (1.0 - kDot);
53
+ float outB = (1.0 - yDot) * (1.0 - kDot);
54
+
55
+ gl_FragColor = vec4(outR, outG, outB, color.a);
56
+ }
57
+ `,h=`attribute vec2 a_position;
58
+ attribute vec2 a_texCoord;
59
+ varying vec2 v_texCoord;
60
+
61
+ void main() {
62
+ gl_Position = vec4(a_position, 0.0, 1.0);
63
+ v_texCoord = a_texCoord;
64
+ }
65
+ `,A={name:"halftone-cmyk",fragmentShader:T,vertexShader:h,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"}]},w=`precision mediump float;
66
+
67
+ varying vec2 v_texCoord;
68
+
69
+ uniform sampler2D u_image;
70
+ uniform vec2 u_resolution;
71
+ uniform float u_dotRadius;
72
+ uniform float u_gridSize;
73
+ uniform vec3 u_duotoneColor;
74
+ uniform float u_angle;
75
+
76
+ void main() {
77
+ vec2 uv = v_texCoord * u_resolution;
78
+ vec4 color = texture2D(u_image, v_texCoord);
79
+
80
+ // Convert to luminance
81
+ float luma = dot(color.rgb, vec3(0.299, 0.587, 0.114));
82
+ float darkness = 1.0 - luma;
83
+
84
+ // Rotate grid
85
+ float rad = radians(u_angle);
86
+ float s = sin(rad);
87
+ float c = cos(rad);
88
+ vec2 rotUV = mat2(c, -s, s, c) * uv;
89
+
90
+ vec2 grid = fract(rotUV / u_gridSize) - 0.5;
91
+ float dist = length(grid) * u_gridSize;
92
+ float radius = u_dotRadius * sqrt(darkness);
93
+ float dot = smoothstep(radius + 0.5, radius - 0.5, dist);
94
+
95
+ // Mix duotone color (paper) with black (dots)
96
+ vec3 result = mix(u_duotoneColor, vec3(0.0), dot);
97
+
98
+ gl_FragColor = vec4(result, color.a);
99
+ }
100
+ `,U={name:"halftone-duotone",fragmentShader:w,vertexShader:h,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"}]},P=`precision mediump float;
101
+
102
+ varying vec2 v_texCoord;
103
+
104
+ uniform sampler2D u_image;
105
+ uniform vec2 u_resolution;
106
+ uniform float u_threshold;
107
+ uniform float u_direction;
108
+ uniform float u_span;
109
+
110
+ float brightness(vec3 c) {
111
+ return dot(c, vec3(0.299, 0.587, 0.114));
112
+ }
113
+
114
+ void main() {
115
+ vec2 uv = v_texCoord;
116
+ vec4 color = texture2D(u_image, uv);
117
+ float bri = brightness(color.rgb);
118
+
119
+ // Boundary pixel — pass through
120
+ if (bri < u_threshold) {
121
+ gl_FragColor = color;
122
+ return;
123
+ }
124
+
125
+ float rad = radians(u_direction);
126
+ vec2 dir = vec2(cos(rad), sin(rad));
127
+ vec2 step = dir / u_resolution;
128
+
129
+ int spanLen = int(u_span);
130
+
131
+ // Walk backward to find span start
132
+ int backCount = 0;
133
+ for (int i = 1; i < 256; i++) {
134
+ if (i >= spanLen) break;
135
+ vec2 sampleUV = uv - step * float(i);
136
+ if (sampleUV.x < 0.0 || sampleUV.x > 1.0 || sampleUV.y < 0.0 || sampleUV.y > 1.0) break;
137
+ float b = brightness(texture2D(u_image, sampleUV).rgb);
138
+ if (b < u_threshold) break;
139
+ backCount++;
140
+ }
141
+
142
+ // Walk forward to find span end
143
+ int fwdCount = 0;
144
+ for (int i = 1; i < 256; i++) {
145
+ if (i >= spanLen) break;
146
+ vec2 sampleUV = uv + step * float(i);
147
+ if (sampleUV.x < 0.0 || sampleUV.x > 1.0 || sampleUV.y < 0.0 || sampleUV.y > 1.0) break;
148
+ float b = brightness(texture2D(u_image, sampleUV).rgb);
149
+ if (b < u_threshold) break;
150
+ fwdCount++;
151
+ }
152
+
153
+ int totalSpan = backCount + 1 + fwdCount;
154
+ vec2 spanStartUV = uv - step * float(backCount);
155
+
156
+ // Count pixels in span that are darker than current (= rank)
157
+ int rank = 0;
158
+ for (int i = 0; i < 256; i++) {
159
+ if (i >= totalSpan) break;
160
+ vec2 sampleUV = spanStartUV + step * float(i);
161
+ float b = brightness(texture2D(u_image, sampleUV).rgb);
162
+ if (b < bri) rank++;
163
+ }
164
+
165
+ // Resample at sorted position
166
+ vec2 sortedUV = spanStartUV + step * float(rank);
167
+ gl_FragColor = texture2D(u_image, sortedUV);
168
+ }
169
+ `,D={name:"pixel-sort",fragmentShader:P,vertexShader:h,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"}]},k=`precision mediump float;
170
+
171
+ varying vec2 v_texCoord;
172
+
173
+ uniform sampler2D u_image;
174
+ uniform vec2 u_resolution;
175
+ uniform float u_dotRadius;
176
+ uniform float u_gridSize;
177
+ uniform vec2 u_dotOffset;
178
+ uniform vec3 u_bgColor;
179
+
180
+ void main() {
181
+ vec2 uv = v_texCoord * u_resolution;
182
+
183
+ // Which grid cell this fragment belongs to
184
+ vec2 cell = floor(uv / u_gridSize);
185
+
186
+ // Cell origin in pixel space
187
+ vec2 cellOrigin = cell * u_gridSize;
188
+
189
+ // Dot center within the cell, shifted by u_dotOffset (0–1 range)
190
+ vec2 dotCenter = cellOrigin + u_dotOffset * u_gridSize;
191
+
192
+ // 4×4 multi-sample average color across the cell
193
+ vec3 avg = vec3(0.0);
194
+ for (int y = 0; y < 4; y++) {
195
+ for (int x = 0; x < 4; x++) {
196
+ vec2 sampleUV = (cellOrigin + (vec2(float(x), float(y)) + 0.5) * (u_gridSize / 4.0)) / u_resolution;
197
+ avg += texture2D(u_image, sampleUV).rgb;
198
+ }
199
+ }
200
+ avg /= 16.0;
201
+
202
+ // Wrapped (toroidal) distance from fragment to dot center within the cell
203
+ vec2 d = (uv - dotCenter) / u_gridSize;
204
+ d = fract(d + 0.5) - 0.5; // wrap to [-0.5, 0.5]
205
+ float dist = length(d) * u_gridSize;
206
+
207
+ // Anti-aliased dot
208
+ float mask = smoothstep(u_dotRadius + 0.5, u_dotRadius - 0.5, dist);
209
+
210
+ vec3 result = mix(u_bgColor, avg, mask);
211
+
212
+ gl_FragColor = vec4(result, 1.0);
213
+ }
214
+ `,L={name:"dot-grid",fragmentShader:k,vertexShader:h,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"}]},m=new Map;function d(e){m.set(e.name,e)}function v(e){return m.get(e)}function z(){return Array.from(m.keys())}d(A);d(U);d(D);d(L);var F=Object.defineProperty,O=Object.getOwnPropertyDescriptor,s=(e,t,o,a)=>{for(var n=a>1?void 0:a?O(t,o):t,r=e.length-1,u;r>=0;r--)(u=e[r])&&(n=(a?u(t,o,n):u(n))||n);return a&&n&&F(t,o,n),n};exports.SomeShadeImage=class extends c.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._canvas=null,this._gl=null,this._programInfo=null,this._textureInfo=null,this._quadBuffer=null,this._currentEffect=null,this._image=null,this._resizeObserver=null}render(){return this._webglAvailable?c.html`<canvas></canvas>`:c.html`<img .src=${this.src} alt="" />`}firstUpdated(){if(this._webglAvailable&&(this._canvas=this.shadowRoot.querySelector("canvas"),!!this._canvas)){if(this._gl=y(this._canvas),!this._gl){this._webglAvailable=!1,this.classList.add("webgl-unavailable");return}this._resizeObserver=new ResizeObserver(()=>this._handleResize()),this._resizeObserver.observe(this),this.src&&this._loadImage(this.src)}}updated(t){if(this._gl){if(t.has("src")&&this.src){this._loadImage(this.src);return}if(t.has("effect")){this._setupProgram(),this._renderFrame();return}this._renderFrame()}}disconnectedCallback(){var t;super.disconnectedCallback(),(t=this._resizeObserver)==null||t.disconnect(),this._cleanup()}_loadImage(t){const o=new Image;o.crossOrigin="anonymous",o.onload=()=>{this._image=o,this._uploadTexture(),this._sizeCanvas(),this._setupProgram(),this._renderFrame()},o.onerror=()=>{console.warn(`[some-shade] Failed to load image: ${t}`)},o.src=t}_uploadTexture(){!this._gl||!this._image||(this._textureInfo&&this._gl.deleteTexture(this._textureInfo.texture),this._textureInfo=C(this._gl,this._image))}_sizeCanvas(){if(!this._canvas||!this._textureInfo)return;const t=window.devicePixelRatio||1,o=this._textureInfo.width,a=this._textureInfo.height;this._canvas.width=o*t,this._canvas.height=a*t,this._canvas.style.aspectRatio=`${o} / ${a}`}_handleResize(){this._renderFrame()}_setupProgram(){if(!this._gl)return;const t=v(this.effect);if(!t){console.warn(`[some-shade] Unknown effect: ${this.effect}`);return}this._programInfo&&this._gl.deleteProgram(this._programInfo.program),this._currentEffect=t,this._programInfo=x(this._gl,t.vertexShader,t.fragmentShader),this._quadBuffer&&this._gl.deleteBuffer(this._quadBuffer),this._gl.useProgram(this._programInfo.program),this._quadBuffer=I(this._gl,this._programInfo)}_getUniformValues(){const t={};return this._textureInfo&&(t.u_resolution=[this._textureInfo.width*(window.devicePixelRatio||1),this._textureInfo.height*(window.devicePixelRatio||1)],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(t){const o=t.replace("#",""),a=parseInt(o.substring(0,2),16)/255,n=parseInt(o.substring(2,4),16)/255,r=parseInt(o.substring(4,6),16)/255;return[a,n,r]}_renderFrame(){const t=this._gl;if(!t||!this._programInfo||!this._textureInfo||!this._canvas)return;t.viewport(0,0,this._canvas.width,this._canvas.height),t.clearColor(0,0,0,0),t.clear(t.COLOR_BUFFER_BIT),t.useProgram(this._programInfo.program),t.activeTexture(t.TEXTURE0),t.bindTexture(t.TEXTURE_2D,this._textureInfo.texture);const o=this._programInfo.uniformLocations.get("u_image");o&&t.uniform1i(o,0),E(t,this._programInfo,this._getUniformValues()),t.bindBuffer(t.ARRAY_BUFFER,this._quadBuffer);const a=4*Float32Array.BYTES_PER_ELEMENT,n=this._programInfo.attribLocations.get("a_position");n!==void 0&&n!==-1&&(t.enableVertexAttribArray(n),t.vertexAttribPointer(n,2,t.FLOAT,!1,a,0));const r=this._programInfo.attribLocations.get("a_texCoord");r!==void 0&&r!==-1&&(t.enableVertexAttribArray(r),t.vertexAttribPointer(r,2,t.FLOAT,!1,a,2*Float32Array.BYTES_PER_ELEMENT)),R(t)}_cleanup(){this._gl&&(this._textureInfo&&this._gl.deleteTexture(this._textureInfo.texture),this._programInfo&&this._gl.deleteProgram(this._programInfo.program),this._quadBuffer&&this._gl.deleteBuffer(this._quadBuffer),this._gl=null,this._programInfo=null,this._textureInfo=null,this._quadBuffer=null)}};exports.SomeShadeImage.styles=c.css`
215
+ :host {
216
+ display: block;
217
+ position: relative;
218
+ overflow: hidden;
219
+ }
220
+ canvas, img {
221
+ display: block;
222
+ width: 100%;
223
+ height: auto;
224
+ }
225
+ `;s([i.property()],exports.SomeShadeImage.prototype,"src",2);s([i.property()],exports.SomeShadeImage.prototype,"effect",2);s([i.property({type:Number,attribute:"dot-radius"})],exports.SomeShadeImage.prototype,"dotRadius",2);s([i.property({type:Number,attribute:"grid-size"})],exports.SomeShadeImage.prototype,"gridSize",2);s([i.property({type:Number,attribute:"angle-c"})],exports.SomeShadeImage.prototype,"angleC",2);s([i.property({type:Number,attribute:"angle-m"})],exports.SomeShadeImage.prototype,"angleM",2);s([i.property({type:Number,attribute:"angle-y"})],exports.SomeShadeImage.prototype,"angleY",2);s([i.property({type:Number,attribute:"angle-k"})],exports.SomeShadeImage.prototype,"angleK",2);s([i.property({attribute:"duotone-color"})],exports.SomeShadeImage.prototype,"duotoneColor",2);s([i.property({type:Number})],exports.SomeShadeImage.prototype,"angle",2);s([i.property({type:Number})],exports.SomeShadeImage.prototype,"threshold",2);s([i.property({type:Number,attribute:"sort-direction"})],exports.SomeShadeImage.prototype,"sortDirection",2);s([i.property({type:Number,attribute:"sort-span"})],exports.SomeShadeImage.prototype,"sortSpan",2);s([i.property({type:Number,attribute:"dot-offset-x"})],exports.SomeShadeImage.prototype,"dotOffsetX",2);s([i.property({type:Number,attribute:"dot-offset-y"})],exports.SomeShadeImage.prototype,"dotOffsetY",2);s([i.property({attribute:"bg-color"})],exports.SomeShadeImage.prototype,"bgColor",2);s([i.state()],exports.SomeShadeImage.prototype,"_webglAvailable",2);exports.SomeShadeImage=s([i.customElement("some-shade-image")],exports.SomeShadeImage);exports.get=v;exports.list=z;exports.register=d;
@@ -0,0 +1,529 @@
1
+ import { css as y, LitElement as E, html as p } from "lit";
2
+ import { property as u, state as S, customElement as C } from "lit/decorators.js";
3
+ function R(t) {
4
+ return t.getContext("webgl", {
5
+ alpha: !0,
6
+ premultipliedAlpha: !1,
7
+ preserveDrawingBuffer: !0
8
+ });
9
+ }
10
+ function v(t, e, a) {
11
+ const n = t.createShader(e);
12
+ if (!n) throw new Error("Failed to create shader");
13
+ if (t.shaderSource(n, a), t.compileShader(n), !t.getShaderParameter(n, t.COMPILE_STATUS)) {
14
+ const r = t.getShaderInfoLog(n);
15
+ throw t.deleteShader(n), new Error(`Shader compile error: ${r}`);
16
+ }
17
+ return n;
18
+ }
19
+ function T(t, e, a) {
20
+ const n = v(t, t.VERTEX_SHADER, e), r = v(t, t.FRAGMENT_SHADER, a), o = t.createProgram();
21
+ if (!o) throw new Error("Failed to create program");
22
+ if (t.attachShader(o, n), t.attachShader(o, r), t.linkProgram(o), !t.getProgramParameter(o, t.LINK_STATUS)) {
23
+ const l = t.getProgramInfoLog(o);
24
+ throw t.deleteProgram(o), new Error(`Program link error: ${l}`);
25
+ }
26
+ t.deleteShader(n), t.deleteShader(r);
27
+ const f = /* @__PURE__ */ new Map(), b = t.getProgramParameter(o, t.ACTIVE_ATTRIBUTES);
28
+ for (let l = 0; l < b; l++) {
29
+ const d = t.getActiveAttrib(o, l);
30
+ d && f.set(d.name, t.getAttribLocation(o, d.name));
31
+ }
32
+ const m = /* @__PURE__ */ new Map(), x = t.getProgramParameter(o, t.ACTIVE_UNIFORMS);
33
+ for (let l = 0; l < x; l++) {
34
+ const d = t.getActiveUniform(o, l);
35
+ if (d) {
36
+ const g = t.getUniformLocation(o, d.name);
37
+ g && m.set(d.name, g);
38
+ }
39
+ }
40
+ return { program: o, attribLocations: f, uniformLocations: m };
41
+ }
42
+ function A(t, e, a) {
43
+ for (const [n, r] of Object.entries(a)) {
44
+ const o = e.uniformLocations.get(n);
45
+ if (o) {
46
+ if (typeof r == "number")
47
+ t.uniform1f(o, r);
48
+ else if (Array.isArray(r))
49
+ switch (r.length) {
50
+ case 2:
51
+ t.uniform2fv(o, r);
52
+ break;
53
+ case 3:
54
+ t.uniform3fv(o, r);
55
+ break;
56
+ case 4:
57
+ t.uniform4fv(o, r);
58
+ break;
59
+ }
60
+ }
61
+ }
62
+ }
63
+ function w(t, e) {
64
+ const a = t.createTexture();
65
+ if (!a) throw new Error("Failed to create texture");
66
+ return t.bindTexture(t.TEXTURE_2D, a), t.texImage2D(t.TEXTURE_2D, 0, t.RGBA, t.RGBA, t.UNSIGNED_BYTE, e), 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: a, width: e.naturalWidth, height: e.naturalHeight };
67
+ }
68
+ function I(t, e) {
69
+ const a = new Float32Array([
70
+ // pos.x pos.y tex.s tex.t
71
+ -1,
72
+ -1,
73
+ 0,
74
+ 1,
75
+ 1,
76
+ -1,
77
+ 1,
78
+ 1,
79
+ -1,
80
+ 1,
81
+ 0,
82
+ 0,
83
+ 1,
84
+ 1,
85
+ 1,
86
+ 0
87
+ ]), n = t.createBuffer();
88
+ if (!n) throw new Error("Failed to create buffer");
89
+ t.bindBuffer(t.ARRAY_BUFFER, n), t.bufferData(t.ARRAY_BUFFER, a, t.STATIC_DRAW);
90
+ const r = 4 * Float32Array.BYTES_PER_ELEMENT, o = e.attribLocations.get("a_position");
91
+ o !== void 0 && o !== -1 && (t.enableVertexAttribArray(o), t.vertexAttribPointer(o, 2, t.FLOAT, !1, r, 0));
92
+ const f = e.attribLocations.get("a_texCoord");
93
+ return f !== void 0 && f !== -1 && (t.enableVertexAttribArray(f), t.vertexAttribPointer(f, 2, t.FLOAT, !1, r, 2 * Float32Array.BYTES_PER_ELEMENT)), n;
94
+ }
95
+ function U(t) {
96
+ t.drawArrays(t.TRIANGLE_STRIP, 0, 4);
97
+ }
98
+ const D = `precision mediump float;
99
+
100
+ varying vec2 v_texCoord;
101
+
102
+ uniform sampler2D u_image;
103
+ uniform vec2 u_resolution;
104
+ uniform float u_dotRadius;
105
+ uniform float u_gridSize;
106
+ uniform float u_angleC;
107
+ uniform float u_angleM;
108
+ uniform float u_angleY;
109
+ uniform float u_angleK;
110
+
111
+ float halftone(vec2 uv, float angle, float channelValue, float gridSize, float dotRadius) {
112
+ float rad = radians(angle);
113
+ float s = sin(rad);
114
+ float c = cos(rad);
115
+ mat2 rot = mat2(c, -s, s, c);
116
+
117
+ vec2 rotUV = rot * uv;
118
+ vec2 grid = fract(rotUV / gridSize) - 0.5;
119
+
120
+ float dist = length(grid) * gridSize;
121
+ float radius = dotRadius * sqrt(channelValue);
122
+
123
+ return smoothstep(radius + 0.5, radius - 0.5, dist);
124
+ }
125
+
126
+ void main() {
127
+ vec2 uv = v_texCoord * u_resolution;
128
+ vec4 color = texture2D(u_image, v_texCoord);
129
+
130
+ float r = color.r;
131
+ float g = color.g;
132
+ float b = color.b;
133
+
134
+ // RGB to CMYK
135
+ float k = 1.0 - max(max(r, g), b);
136
+ float invK = 1.0 - k;
137
+ float cy = invK > 0.001 ? (invK - r) / invK : 0.0;
138
+ float ma = invK > 0.001 ? (invK - g) / invK : 0.0;
139
+ float ye = invK > 0.001 ? (invK - b) / invK : 0.0;
140
+
141
+ // Compute halftone dots for each channel
142
+ float cDot = halftone(uv, u_angleC, cy, u_gridSize, u_dotRadius);
143
+ float mDot = halftone(uv, u_angleM, ma, u_gridSize, u_dotRadius);
144
+ float yDot = halftone(uv, u_angleY, ye, u_gridSize, u_dotRadius);
145
+ float kDot = halftone(uv, u_angleK, k, u_gridSize, u_dotRadius);
146
+
147
+ // Subtractive color mixing on white paper
148
+ float outR = (1.0 - cDot) * (1.0 - kDot);
149
+ float outG = (1.0 - mDot) * (1.0 - kDot);
150
+ float outB = (1.0 - yDot) * (1.0 - kDot);
151
+
152
+ gl_FragColor = vec4(outR, outG, outB, color.a);
153
+ }
154
+ `, c = `attribute vec2 a_position;
155
+ attribute vec2 a_texCoord;
156
+ varying vec2 v_texCoord;
157
+
158
+ void main() {
159
+ gl_Position = vec4(a_position, 0.0, 1.0);
160
+ v_texCoord = a_texCoord;
161
+ }
162
+ `, P = {
163
+ name: "halftone-cmyk",
164
+ fragmentShader: D,
165
+ vertexShader: c,
166
+ uniforms: [
167
+ { name: "u_dotRadius", type: "float", default: 4, attribute: "dot-radius" },
168
+ { name: "u_gridSize", type: "float", default: 8, attribute: "grid-size" },
169
+ { name: "u_angleC", type: "float", default: 15, attribute: "angle-c" },
170
+ { name: "u_angleM", type: "float", default: 75, attribute: "angle-m" },
171
+ { name: "u_angleY", type: "float", default: 0, attribute: "angle-y" },
172
+ { name: "u_angleK", type: "float", default: 45, attribute: "angle-k" }
173
+ ]
174
+ }, k = `precision mediump float;
175
+
176
+ varying vec2 v_texCoord;
177
+
178
+ uniform sampler2D u_image;
179
+ uniform vec2 u_resolution;
180
+ uniform float u_dotRadius;
181
+ uniform float u_gridSize;
182
+ uniform vec3 u_duotoneColor;
183
+ uniform float u_angle;
184
+
185
+ void main() {
186
+ vec2 uv = v_texCoord * u_resolution;
187
+ vec4 color = texture2D(u_image, v_texCoord);
188
+
189
+ // Convert to luminance
190
+ float luma = dot(color.rgb, vec3(0.299, 0.587, 0.114));
191
+ float darkness = 1.0 - luma;
192
+
193
+ // Rotate grid
194
+ float rad = radians(u_angle);
195
+ float s = sin(rad);
196
+ float c = cos(rad);
197
+ vec2 rotUV = mat2(c, -s, s, c) * uv;
198
+
199
+ vec2 grid = fract(rotUV / u_gridSize) - 0.5;
200
+ float dist = length(grid) * u_gridSize;
201
+ float radius = u_dotRadius * sqrt(darkness);
202
+ float dot = smoothstep(radius + 0.5, radius - 0.5, dist);
203
+
204
+ // Mix duotone color (paper) with black (dots)
205
+ vec3 result = mix(u_duotoneColor, vec3(0.0), dot);
206
+
207
+ gl_FragColor = vec4(result, color.a);
208
+ }
209
+ `, L = {
210
+ name: "halftone-duotone",
211
+ fragmentShader: k,
212
+ vertexShader: c,
213
+ uniforms: [
214
+ { name: "u_dotRadius", type: "float", default: 4, attribute: "dot-radius" },
215
+ { name: "u_gridSize", type: "float", default: 8, attribute: "grid-size" },
216
+ { name: "u_duotoneColor", type: "vec3", default: [0, 0.6, 0.8], attribute: "duotone-color" },
217
+ { name: "u_angle", type: "float", default: 0, attribute: "angle" }
218
+ ]
219
+ }, z = `precision mediump float;
220
+
221
+ varying vec2 v_texCoord;
222
+
223
+ uniform sampler2D u_image;
224
+ uniform vec2 u_resolution;
225
+ uniform float u_threshold;
226
+ uniform float u_direction;
227
+ uniform float u_span;
228
+
229
+ float brightness(vec3 c) {
230
+ return dot(c, vec3(0.299, 0.587, 0.114));
231
+ }
232
+
233
+ void main() {
234
+ vec2 uv = v_texCoord;
235
+ vec4 color = texture2D(u_image, uv);
236
+ float bri = brightness(color.rgb);
237
+
238
+ // Boundary pixel — pass through
239
+ if (bri < u_threshold) {
240
+ gl_FragColor = color;
241
+ return;
242
+ }
243
+
244
+ float rad = radians(u_direction);
245
+ vec2 dir = vec2(cos(rad), sin(rad));
246
+ vec2 step = dir / u_resolution;
247
+
248
+ int spanLen = int(u_span);
249
+
250
+ // Walk backward to find span start
251
+ int backCount = 0;
252
+ for (int i = 1; i < 256; i++) {
253
+ if (i >= spanLen) break;
254
+ vec2 sampleUV = uv - step * float(i);
255
+ if (sampleUV.x < 0.0 || sampleUV.x > 1.0 || sampleUV.y < 0.0 || sampleUV.y > 1.0) break;
256
+ float b = brightness(texture2D(u_image, sampleUV).rgb);
257
+ if (b < u_threshold) break;
258
+ backCount++;
259
+ }
260
+
261
+ // Walk forward to find span end
262
+ int fwdCount = 0;
263
+ for (int i = 1; i < 256; i++) {
264
+ if (i >= spanLen) break;
265
+ vec2 sampleUV = uv + step * float(i);
266
+ if (sampleUV.x < 0.0 || sampleUV.x > 1.0 || sampleUV.y < 0.0 || sampleUV.y > 1.0) break;
267
+ float b = brightness(texture2D(u_image, sampleUV).rgb);
268
+ if (b < u_threshold) break;
269
+ fwdCount++;
270
+ }
271
+
272
+ int totalSpan = backCount + 1 + fwdCount;
273
+ vec2 spanStartUV = uv - step * float(backCount);
274
+
275
+ // Count pixels in span that are darker than current (= rank)
276
+ int rank = 0;
277
+ for (int i = 0; i < 256; i++) {
278
+ if (i >= totalSpan) break;
279
+ vec2 sampleUV = spanStartUV + step * float(i);
280
+ float b = brightness(texture2D(u_image, sampleUV).rgb);
281
+ if (b < bri) rank++;
282
+ }
283
+
284
+ // Resample at sorted position
285
+ vec2 sortedUV = spanStartUV + step * float(rank);
286
+ gl_FragColor = texture2D(u_image, sortedUV);
287
+ }
288
+ `, F = {
289
+ name: "pixel-sort",
290
+ fragmentShader: z,
291
+ vertexShader: c,
292
+ uniforms: [
293
+ { name: "u_threshold", type: "float", default: 0.5, attribute: "threshold" },
294
+ { name: "u_direction", type: "float", default: 0, attribute: "sort-direction" },
295
+ { name: "u_span", type: "float", default: 64, attribute: "sort-span" }
296
+ ]
297
+ }, V = `precision mediump float;
298
+
299
+ varying vec2 v_texCoord;
300
+
301
+ uniform sampler2D u_image;
302
+ uniform vec2 u_resolution;
303
+ uniform float u_dotRadius;
304
+ uniform float u_gridSize;
305
+ uniform vec2 u_dotOffset;
306
+ uniform vec3 u_bgColor;
307
+
308
+ void main() {
309
+ vec2 uv = v_texCoord * u_resolution;
310
+
311
+ // Which grid cell this fragment belongs to
312
+ vec2 cell = floor(uv / u_gridSize);
313
+
314
+ // Cell origin in pixel space
315
+ vec2 cellOrigin = cell * u_gridSize;
316
+
317
+ // Dot center within the cell, shifted by u_dotOffset (0–1 range)
318
+ vec2 dotCenter = cellOrigin + u_dotOffset * u_gridSize;
319
+
320
+ // 4×4 multi-sample average color across the cell
321
+ vec3 avg = vec3(0.0);
322
+ for (int y = 0; y < 4; y++) {
323
+ for (int x = 0; x < 4; x++) {
324
+ vec2 sampleUV = (cellOrigin + (vec2(float(x), float(y)) + 0.5) * (u_gridSize / 4.0)) / u_resolution;
325
+ avg += texture2D(u_image, sampleUV).rgb;
326
+ }
327
+ }
328
+ avg /= 16.0;
329
+
330
+ // Wrapped (toroidal) distance from fragment to dot center within the cell
331
+ vec2 d = (uv - dotCenter) / u_gridSize;
332
+ d = fract(d + 0.5) - 0.5; // wrap to [-0.5, 0.5]
333
+ float dist = length(d) * u_gridSize;
334
+
335
+ // Anti-aliased dot
336
+ float mask = smoothstep(u_dotRadius + 0.5, u_dotRadius - 0.5, dist);
337
+
338
+ vec3 result = mix(u_bgColor, avg, mask);
339
+
340
+ gl_FragColor = vec4(result, 1.0);
341
+ }
342
+ `, O = {
343
+ name: "dot-grid",
344
+ fragmentShader: V,
345
+ vertexShader: c,
346
+ uniforms: [
347
+ { name: "u_dotRadius", type: "float", default: 4, attribute: "dot-radius" },
348
+ { name: "u_gridSize", type: "float", default: 8, attribute: "grid-size" },
349
+ { name: "u_dotOffset", type: "vec2", default: [0.5, 0.5], attribute: "dot-offset" },
350
+ { name: "u_bgColor", type: "vec3", default: [1, 1, 1], attribute: "bg-color" }
351
+ ]
352
+ }, h = /* @__PURE__ */ new Map();
353
+ function _(t) {
354
+ h.set(t.name, t);
355
+ }
356
+ function B(t) {
357
+ return h.get(t);
358
+ }
359
+ function X() {
360
+ return Array.from(h.keys());
361
+ }
362
+ _(P);
363
+ _(L);
364
+ _(F);
365
+ _(O);
366
+ var N = Object.defineProperty, M = Object.getOwnPropertyDescriptor, s = (t, e, a, n) => {
367
+ for (var r = n > 1 ? void 0 : n ? M(e, a) : e, o = t.length - 1, f; o >= 0; o--)
368
+ (f = t[o]) && (r = (n ? f(e, a, r) : f(r)) || r);
369
+ return n && r && N(e, a, r), r;
370
+ };
371
+ let i = class extends E {
372
+ 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._canvas = null, this._gl = null, this._programInfo = null, this._textureInfo = null, this._quadBuffer = null, this._currentEffect = null, this._image = null, this._resizeObserver = null;
374
+ }
375
+ render() {
376
+ return this._webglAvailable ? p`<canvas></canvas>` : p`<img .src=${this.src} alt="" />`;
377
+ }
378
+ firstUpdated() {
379
+ if (this._webglAvailable && (this._canvas = this.shadowRoot.querySelector("canvas"), !!this._canvas)) {
380
+ if (this._gl = R(this._canvas), !this._gl) {
381
+ this._webglAvailable = !1, this.classList.add("webgl-unavailable");
382
+ return;
383
+ }
384
+ this._resizeObserver = new ResizeObserver(() => this._handleResize()), this._resizeObserver.observe(this), this.src && this._loadImage(this.src);
385
+ }
386
+ }
387
+ updated(t) {
388
+ if (this._gl) {
389
+ if (t.has("src") && this.src) {
390
+ this._loadImage(this.src);
391
+ return;
392
+ }
393
+ if (t.has("effect")) {
394
+ this._setupProgram(), this._renderFrame();
395
+ return;
396
+ }
397
+ this._renderFrame();
398
+ }
399
+ }
400
+ disconnectedCallback() {
401
+ var t;
402
+ super.disconnectedCallback(), (t = this._resizeObserver) == null || t.disconnect(), this._cleanup();
403
+ }
404
+ _loadImage(t) {
405
+ const e = new Image();
406
+ e.crossOrigin = "anonymous", e.onload = () => {
407
+ this._image = e, this._uploadTexture(), this._sizeCanvas(), this._setupProgram(), this._renderFrame();
408
+ }, e.onerror = () => {
409
+ console.warn(`[some-shade] Failed to load image: ${t}`);
410
+ }, e.src = t;
411
+ }
412
+ _uploadTexture() {
413
+ !this._gl || !this._image || (this._textureInfo && this._gl.deleteTexture(this._textureInfo.texture), this._textureInfo = w(this._gl, this._image));
414
+ }
415
+ _sizeCanvas() {
416
+ if (!this._canvas || !this._textureInfo) return;
417
+ const t = window.devicePixelRatio || 1, e = this._textureInfo.width, a = this._textureInfo.height;
418
+ this._canvas.width = e * t, this._canvas.height = a * t, this._canvas.style.aspectRatio = `${e} / ${a}`;
419
+ }
420
+ _handleResize() {
421
+ this._renderFrame();
422
+ }
423
+ _setupProgram() {
424
+ if (!this._gl) return;
425
+ const t = B(this.effect);
426
+ if (!t) {
427
+ console.warn(`[some-shade] Unknown effect: ${this.effect}`);
428
+ return;
429
+ }
430
+ this._programInfo && this._gl.deleteProgram(this._programInfo.program), this._currentEffect = t, this._programInfo = T(this._gl, t.vertexShader, t.fragmentShader), this._quadBuffer && this._gl.deleteBuffer(this._quadBuffer), this._gl.useProgram(this._programInfo.program), this._quadBuffer = I(this._gl, this._programInfo);
431
+ }
432
+ _getUniformValues() {
433
+ const t = {};
434
+ return this._textureInfo && (t.u_resolution = [
435
+ this._textureInfo.width * (window.devicePixelRatio || 1),
436
+ this._textureInfo.height * (window.devicePixelRatio || 1)
437
+ ], 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;
438
+ }
439
+ _parseHexColor(t) {
440
+ const e = t.replace("#", ""), a = parseInt(e.substring(0, 2), 16) / 255, n = parseInt(e.substring(2, 4), 16) / 255, r = parseInt(e.substring(4, 6), 16) / 255;
441
+ return [a, n, r];
442
+ }
443
+ _renderFrame() {
444
+ const t = this._gl;
445
+ if (!t || !this._programInfo || !this._textureInfo || !this._canvas) return;
446
+ t.viewport(0, 0, this._canvas.width, this._canvas.height), t.clearColor(0, 0, 0, 0), t.clear(t.COLOR_BUFFER_BIT), t.useProgram(this._programInfo.program), t.activeTexture(t.TEXTURE0), t.bindTexture(t.TEXTURE_2D, this._textureInfo.texture);
447
+ const e = this._programInfo.uniformLocations.get("u_image");
448
+ e && t.uniform1i(e, 0), A(t, this._programInfo, this._getUniformValues()), t.bindBuffer(t.ARRAY_BUFFER, this._quadBuffer);
449
+ const a = 4 * Float32Array.BYTES_PER_ELEMENT, n = this._programInfo.attribLocations.get("a_position");
450
+ n !== void 0 && n !== -1 && (t.enableVertexAttribArray(n), t.vertexAttribPointer(n, 2, t.FLOAT, !1, a, 0));
451
+ const r = this._programInfo.attribLocations.get("a_texCoord");
452
+ r !== void 0 && r !== -1 && (t.enableVertexAttribArray(r), t.vertexAttribPointer(r, 2, t.FLOAT, !1, a, 2 * Float32Array.BYTES_PER_ELEMENT)), U(t);
453
+ }
454
+ _cleanup() {
455
+ this._gl && (this._textureInfo && this._gl.deleteTexture(this._textureInfo.texture), this._programInfo && this._gl.deleteProgram(this._programInfo.program), this._quadBuffer && this._gl.deleteBuffer(this._quadBuffer), this._gl = null, this._programInfo = null, this._textureInfo = null, this._quadBuffer = null);
456
+ }
457
+ };
458
+ i.styles = y`
459
+ :host {
460
+ display: block;
461
+ position: relative;
462
+ overflow: hidden;
463
+ }
464
+ canvas, img {
465
+ display: block;
466
+ width: 100%;
467
+ height: auto;
468
+ }
469
+ `;
470
+ s([
471
+ u()
472
+ ], i.prototype, "src", 2);
473
+ s([
474
+ u()
475
+ ], i.prototype, "effect", 2);
476
+ s([
477
+ u({ type: Number, attribute: "dot-radius" })
478
+ ], i.prototype, "dotRadius", 2);
479
+ s([
480
+ u({ type: Number, attribute: "grid-size" })
481
+ ], i.prototype, "gridSize", 2);
482
+ s([
483
+ u({ type: Number, attribute: "angle-c" })
484
+ ], i.prototype, "angleC", 2);
485
+ s([
486
+ u({ type: Number, attribute: "angle-m" })
487
+ ], i.prototype, "angleM", 2);
488
+ s([
489
+ u({ type: Number, attribute: "angle-y" })
490
+ ], i.prototype, "angleY", 2);
491
+ s([
492
+ u({ type: Number, attribute: "angle-k" })
493
+ ], i.prototype, "angleK", 2);
494
+ s([
495
+ u({ attribute: "duotone-color" })
496
+ ], i.prototype, "duotoneColor", 2);
497
+ s([
498
+ u({ type: Number })
499
+ ], i.prototype, "angle", 2);
500
+ s([
501
+ u({ type: Number })
502
+ ], i.prototype, "threshold", 2);
503
+ s([
504
+ u({ type: Number, attribute: "sort-direction" })
505
+ ], i.prototype, "sortDirection", 2);
506
+ s([
507
+ u({ type: Number, attribute: "sort-span" })
508
+ ], i.prototype, "sortSpan", 2);
509
+ s([
510
+ u({ type: Number, attribute: "dot-offset-x" })
511
+ ], i.prototype, "dotOffsetX", 2);
512
+ s([
513
+ u({ type: Number, attribute: "dot-offset-y" })
514
+ ], i.prototype, "dotOffsetY", 2);
515
+ s([
516
+ u({ attribute: "bg-color" })
517
+ ], i.prototype, "bgColor", 2);
518
+ s([
519
+ S()
520
+ ], i.prototype, "_webglAvailable", 2);
521
+ i = s([
522
+ C("some-shade-image")
523
+ ], i);
524
+ export {
525
+ i as SomeShadeImage,
526
+ B as get,
527
+ X as list,
528
+ _ as register
529
+ };
@@ -0,0 +1,225 @@
1
+ (function(n,d){typeof exports=="object"&&typeof module<"u"?d(exports,require("lit"),require("lit/decorators.js")):typeof define=="function"&&define.amd?define(["exports","lit","lit/decorators.js"],d):(n=typeof globalThis<"u"?globalThis:n||self,d(n.SomeShade={},n.Lit,n.LitDecorators))})(this,(function(n,d,s){"use strict";function S(e){return e.getContext("webgl",{alpha:!0,premultipliedAlpha:!1,preserveDrawingBuffer:!0})}function g(e,t,o){const i=e.createShader(t);if(!i)throw new Error("Failed to create shader");if(e.shaderSource(i,o),e.compileShader(i),!e.getShaderParameter(i,e.COMPILE_STATUS)){const a=e.getShaderInfoLog(i);throw e.deleteShader(i),new Error(`Shader compile error: ${a}`)}return i}function y(e,t,o){const i=g(e,e.VERTEX_SHADER,t),a=g(e,e.FRAGMENT_SHADER,o),r=e.createProgram();if(!r)throw new Error("Failed to create program");if(e.attachShader(r,i),e.attachShader(r,a),e.linkProgram(r),!e.getProgramParameter(r,e.LINK_STATUS)){const l=e.getProgramInfoLog(r);throw e.deleteProgram(r),new Error(`Program link error: ${l}`)}e.deleteShader(i),e.deleteShader(a);const f=new Map,L=e.getProgramParameter(r,e.ACTIVE_ATTRIBUTES);for(let l=0;l<L;l++){const c=e.getActiveAttrib(r,l);c&&f.set(c.name,e.getAttribLocation(r,c.name))}const v=new Map,z=e.getProgramParameter(r,e.ACTIVE_UNIFORMS);for(let l=0;l<z;l++){const c=e.getActiveUniform(r,l);if(c){const b=e.getUniformLocation(r,c.name);b&&v.set(c.name,b)}}return{program:r,attribLocations:f,uniformLocations:v}}function E(e,t,o){for(const[i,a]of Object.entries(o)){const r=t.uniformLocations.get(i);if(r){if(typeof a=="number")e.uniform1f(r,a);else if(Array.isArray(a))switch(a.length){case 2:e.uniform2fv(r,a);break;case 3:e.uniform3fv(r,a);break;case 4:e.uniform4fv(r,a);break}}}}function x(e,t){const o=e.createTexture();if(!o)throw new Error("Failed to create texture");return e.bindTexture(e.TEXTURE_2D,o),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,e.RGBA,e.UNSIGNED_BYTE,t),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:o,width:t.naturalWidth,height:t.naturalHeight}}function C(e,t){const o=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,o,e.STATIC_DRAW);const a=4*Float32Array.BYTES_PER_ELEMENT,r=t.attribLocations.get("a_position");r!==void 0&&r!==-1&&(e.enableVertexAttribArray(r),e.vertexAttribPointer(r,2,e.FLOAT,!1,a,0));const f=t.attribLocations.get("a_texCoord");return f!==void 0&&f!==-1&&(e.enableVertexAttribArray(f),e.vertexAttribPointer(f,2,e.FLOAT,!1,a,2*Float32Array.BYTES_PER_ELEMENT)),i}function I(e){e.drawArrays(e.TRIANGLE_STRIP,0,4)}const R=`precision mediump float;
2
+
3
+ varying vec2 v_texCoord;
4
+
5
+ uniform sampler2D u_image;
6
+ uniform vec2 u_resolution;
7
+ uniform float u_dotRadius;
8
+ uniform float u_gridSize;
9
+ uniform float u_angleC;
10
+ uniform float u_angleM;
11
+ uniform float u_angleY;
12
+ uniform float u_angleK;
13
+
14
+ float halftone(vec2 uv, float angle, float channelValue, float gridSize, float dotRadius) {
15
+ float rad = radians(angle);
16
+ float s = sin(rad);
17
+ float c = cos(rad);
18
+ mat2 rot = mat2(c, -s, s, c);
19
+
20
+ vec2 rotUV = rot * uv;
21
+ vec2 grid = fract(rotUV / gridSize) - 0.5;
22
+
23
+ float dist = length(grid) * gridSize;
24
+ float radius = dotRadius * sqrt(channelValue);
25
+
26
+ return smoothstep(radius + 0.5, radius - 0.5, dist);
27
+ }
28
+
29
+ void main() {
30
+ vec2 uv = v_texCoord * u_resolution;
31
+ vec4 color = texture2D(u_image, v_texCoord);
32
+
33
+ float r = color.r;
34
+ float g = color.g;
35
+ float b = color.b;
36
+
37
+ // RGB to CMYK
38
+ float k = 1.0 - max(max(r, g), b);
39
+ float invK = 1.0 - k;
40
+ float cy = invK > 0.001 ? (invK - r) / invK : 0.0;
41
+ float ma = invK > 0.001 ? (invK - g) / invK : 0.0;
42
+ float ye = invK > 0.001 ? (invK - b) / invK : 0.0;
43
+
44
+ // Compute halftone dots for each channel
45
+ float cDot = halftone(uv, u_angleC, cy, u_gridSize, u_dotRadius);
46
+ float mDot = halftone(uv, u_angleM, ma, u_gridSize, u_dotRadius);
47
+ float yDot = halftone(uv, u_angleY, ye, u_gridSize, u_dotRadius);
48
+ float kDot = halftone(uv, u_angleK, k, u_gridSize, u_dotRadius);
49
+
50
+ // Subtractive color mixing on white paper
51
+ float outR = (1.0 - cDot) * (1.0 - kDot);
52
+ float outG = (1.0 - mDot) * (1.0 - kDot);
53
+ float outB = (1.0 - yDot) * (1.0 - kDot);
54
+
55
+ gl_FragColor = vec4(outR, outG, outB, color.a);
56
+ }
57
+ `,m=`attribute vec2 a_position;
58
+ attribute vec2 a_texCoord;
59
+ varying vec2 v_texCoord;
60
+
61
+ void main() {
62
+ gl_Position = vec4(a_position, 0.0, 1.0);
63
+ v_texCoord = a_texCoord;
64
+ }
65
+ `,T={name:"halftone-cmyk",fragmentShader:R,vertexShader:m,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"}]},A={name:"halftone-duotone",fragmentShader:`precision mediump float;
66
+
67
+ varying vec2 v_texCoord;
68
+
69
+ uniform sampler2D u_image;
70
+ uniform vec2 u_resolution;
71
+ uniform float u_dotRadius;
72
+ uniform float u_gridSize;
73
+ uniform vec3 u_duotoneColor;
74
+ uniform float u_angle;
75
+
76
+ void main() {
77
+ vec2 uv = v_texCoord * u_resolution;
78
+ vec4 color = texture2D(u_image, v_texCoord);
79
+
80
+ // Convert to luminance
81
+ float luma = dot(color.rgb, vec3(0.299, 0.587, 0.114));
82
+ float darkness = 1.0 - luma;
83
+
84
+ // Rotate grid
85
+ float rad = radians(u_angle);
86
+ float s = sin(rad);
87
+ float c = cos(rad);
88
+ vec2 rotUV = mat2(c, -s, s, c) * uv;
89
+
90
+ vec2 grid = fract(rotUV / u_gridSize) - 0.5;
91
+ float dist = length(grid) * u_gridSize;
92
+ float radius = u_dotRadius * sqrt(darkness);
93
+ float dot = smoothstep(radius + 0.5, radius - 0.5, dist);
94
+
95
+ // Mix duotone color (paper) with black (dots)
96
+ vec3 result = mix(u_duotoneColor, vec3(0.0), dot);
97
+
98
+ gl_FragColor = vec4(result, color.a);
99
+ }
100
+ `,vertexShader:m,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:"pixel-sort",fragmentShader:`precision mediump float;
101
+
102
+ varying vec2 v_texCoord;
103
+
104
+ uniform sampler2D u_image;
105
+ uniform vec2 u_resolution;
106
+ uniform float u_threshold;
107
+ uniform float u_direction;
108
+ uniform float u_span;
109
+
110
+ float brightness(vec3 c) {
111
+ return dot(c, vec3(0.299, 0.587, 0.114));
112
+ }
113
+
114
+ void main() {
115
+ vec2 uv = v_texCoord;
116
+ vec4 color = texture2D(u_image, uv);
117
+ float bri = brightness(color.rgb);
118
+
119
+ // Boundary pixel — pass through
120
+ if (bri < u_threshold) {
121
+ gl_FragColor = color;
122
+ return;
123
+ }
124
+
125
+ float rad = radians(u_direction);
126
+ vec2 dir = vec2(cos(rad), sin(rad));
127
+ vec2 step = dir / u_resolution;
128
+
129
+ int spanLen = int(u_span);
130
+
131
+ // Walk backward to find span start
132
+ int backCount = 0;
133
+ for (int i = 1; i < 256; i++) {
134
+ if (i >= spanLen) break;
135
+ vec2 sampleUV = uv - step * float(i);
136
+ if (sampleUV.x < 0.0 || sampleUV.x > 1.0 || sampleUV.y < 0.0 || sampleUV.y > 1.0) break;
137
+ float b = brightness(texture2D(u_image, sampleUV).rgb);
138
+ if (b < u_threshold) break;
139
+ backCount++;
140
+ }
141
+
142
+ // Walk forward to find span end
143
+ int fwdCount = 0;
144
+ for (int i = 1; i < 256; i++) {
145
+ if (i >= spanLen) break;
146
+ vec2 sampleUV = uv + step * float(i);
147
+ if (sampleUV.x < 0.0 || sampleUV.x > 1.0 || sampleUV.y < 0.0 || sampleUV.y > 1.0) break;
148
+ float b = brightness(texture2D(u_image, sampleUV).rgb);
149
+ if (b < u_threshold) break;
150
+ fwdCount++;
151
+ }
152
+
153
+ int totalSpan = backCount + 1 + fwdCount;
154
+ vec2 spanStartUV = uv - step * float(backCount);
155
+
156
+ // Count pixels in span that are darker than current (= rank)
157
+ int rank = 0;
158
+ for (int i = 0; i < 256; i++) {
159
+ if (i >= totalSpan) break;
160
+ vec2 sampleUV = spanStartUV + step * float(i);
161
+ float b = brightness(texture2D(u_image, sampleUV).rgb);
162
+ if (b < bri) rank++;
163
+ }
164
+
165
+ // Resample at sorted position
166
+ vec2 sortedUV = spanStartUV + step * float(rank);
167
+ gl_FragColor = texture2D(u_image, sortedUV);
168
+ }
169
+ `,vertexShader:m,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"}]},U={name:"dot-grid",fragmentShader:`precision mediump float;
170
+
171
+ varying vec2 v_texCoord;
172
+
173
+ uniform sampler2D u_image;
174
+ uniform vec2 u_resolution;
175
+ uniform float u_dotRadius;
176
+ uniform float u_gridSize;
177
+ uniform vec2 u_dotOffset;
178
+ uniform vec3 u_bgColor;
179
+
180
+ void main() {
181
+ vec2 uv = v_texCoord * u_resolution;
182
+
183
+ // Which grid cell this fragment belongs to
184
+ vec2 cell = floor(uv / u_gridSize);
185
+
186
+ // Cell origin in pixel space
187
+ vec2 cellOrigin = cell * u_gridSize;
188
+
189
+ // Dot center within the cell, shifted by u_dotOffset (0–1 range)
190
+ vec2 dotCenter = cellOrigin + u_dotOffset * u_gridSize;
191
+
192
+ // 4×4 multi-sample average color across the cell
193
+ vec3 avg = vec3(0.0);
194
+ for (int y = 0; y < 4; y++) {
195
+ for (int x = 0; x < 4; x++) {
196
+ vec2 sampleUV = (cellOrigin + (vec2(float(x), float(y)) + 0.5) * (u_gridSize / 4.0)) / u_resolution;
197
+ avg += texture2D(u_image, sampleUV).rgb;
198
+ }
199
+ }
200
+ avg /= 16.0;
201
+
202
+ // Wrapped (toroidal) distance from fragment to dot center within the cell
203
+ vec2 d = (uv - dotCenter) / u_gridSize;
204
+ d = fract(d + 0.5) - 0.5; // wrap to [-0.5, 0.5]
205
+ float dist = length(d) * u_gridSize;
206
+
207
+ // Anti-aliased dot
208
+ float mask = smoothstep(u_dotRadius + 0.5, u_dotRadius - 0.5, dist);
209
+
210
+ vec3 result = mix(u_bgColor, avg, mask);
211
+
212
+ gl_FragColor = vec4(result, 1.0);
213
+ }
214
+ `,vertexShader:m,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"}]},_=new Map;function h(e){_.set(e.name,e)}function p(e){return _.get(e)}function D(){return Array.from(_.keys())}h(T),h(A),h(w),h(U);var P=Object.defineProperty,k=Object.getOwnPropertyDescriptor,u=(e,t,o,i)=>{for(var a=i>1?void 0:i?k(t,o):t,r=e.length-1,f;r>=0;r--)(f=e[r])&&(a=(i?f(t,o,a):f(a))||a);return i&&a&&P(t,o,a),a};n.SomeShadeImage=class extends d.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._canvas=null,this._gl=null,this._programInfo=null,this._textureInfo=null,this._quadBuffer=null,this._currentEffect=null,this._image=null,this._resizeObserver=null}render(){return this._webglAvailable?d.html`<canvas></canvas>`:d.html`<img .src=${this.src} alt="" />`}firstUpdated(){if(this._webglAvailable&&(this._canvas=this.shadowRoot.querySelector("canvas"),!!this._canvas)){if(this._gl=S(this._canvas),!this._gl){this._webglAvailable=!1,this.classList.add("webgl-unavailable");return}this._resizeObserver=new ResizeObserver(()=>this._handleResize()),this._resizeObserver.observe(this),this.src&&this._loadImage(this.src)}}updated(t){if(this._gl){if(t.has("src")&&this.src){this._loadImage(this.src);return}if(t.has("effect")){this._setupProgram(),this._renderFrame();return}this._renderFrame()}}disconnectedCallback(){var t;super.disconnectedCallback(),(t=this._resizeObserver)==null||t.disconnect(),this._cleanup()}_loadImage(t){const o=new Image;o.crossOrigin="anonymous",o.onload=()=>{this._image=o,this._uploadTexture(),this._sizeCanvas(),this._setupProgram(),this._renderFrame()},o.onerror=()=>{console.warn(`[some-shade] Failed to load image: ${t}`)},o.src=t}_uploadTexture(){!this._gl||!this._image||(this._textureInfo&&this._gl.deleteTexture(this._textureInfo.texture),this._textureInfo=x(this._gl,this._image))}_sizeCanvas(){if(!this._canvas||!this._textureInfo)return;const t=window.devicePixelRatio||1,o=this._textureInfo.width,i=this._textureInfo.height;this._canvas.width=o*t,this._canvas.height=i*t,this._canvas.style.aspectRatio=`${o} / ${i}`}_handleResize(){this._renderFrame()}_setupProgram(){if(!this._gl)return;const t=p(this.effect);if(!t){console.warn(`[some-shade] Unknown effect: ${this.effect}`);return}this._programInfo&&this._gl.deleteProgram(this._programInfo.program),this._currentEffect=t,this._programInfo=y(this._gl,t.vertexShader,t.fragmentShader),this._quadBuffer&&this._gl.deleteBuffer(this._quadBuffer),this._gl.useProgram(this._programInfo.program),this._quadBuffer=C(this._gl,this._programInfo)}_getUniformValues(){const t={};return this._textureInfo&&(t.u_resolution=[this._textureInfo.width*(window.devicePixelRatio||1),this._textureInfo.height*(window.devicePixelRatio||1)],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(t){const o=t.replace("#",""),i=parseInt(o.substring(0,2),16)/255,a=parseInt(o.substring(2,4),16)/255,r=parseInt(o.substring(4,6),16)/255;return[i,a,r]}_renderFrame(){const t=this._gl;if(!t||!this._programInfo||!this._textureInfo||!this._canvas)return;t.viewport(0,0,this._canvas.width,this._canvas.height),t.clearColor(0,0,0,0),t.clear(t.COLOR_BUFFER_BIT),t.useProgram(this._programInfo.program),t.activeTexture(t.TEXTURE0),t.bindTexture(t.TEXTURE_2D,this._textureInfo.texture);const o=this._programInfo.uniformLocations.get("u_image");o&&t.uniform1i(o,0),E(t,this._programInfo,this._getUniformValues()),t.bindBuffer(t.ARRAY_BUFFER,this._quadBuffer);const i=4*Float32Array.BYTES_PER_ELEMENT,a=this._programInfo.attribLocations.get("a_position");a!==void 0&&a!==-1&&(t.enableVertexAttribArray(a),t.vertexAttribPointer(a,2,t.FLOAT,!1,i,0));const r=this._programInfo.attribLocations.get("a_texCoord");r!==void 0&&r!==-1&&(t.enableVertexAttribArray(r),t.vertexAttribPointer(r,2,t.FLOAT,!1,i,2*Float32Array.BYTES_PER_ELEMENT)),I(t)}_cleanup(){this._gl&&(this._textureInfo&&this._gl.deleteTexture(this._textureInfo.texture),this._programInfo&&this._gl.deleteProgram(this._programInfo.program),this._quadBuffer&&this._gl.deleteBuffer(this._quadBuffer),this._gl=null,this._programInfo=null,this._textureInfo=null,this._quadBuffer=null)}},n.SomeShadeImage.styles=d.css`
215
+ :host {
216
+ display: block;
217
+ position: relative;
218
+ overflow: hidden;
219
+ }
220
+ canvas, img {
221
+ display: block;
222
+ width: 100%;
223
+ height: auto;
224
+ }
225
+ `,u([s.property()],n.SomeShadeImage.prototype,"src",2),u([s.property()],n.SomeShadeImage.prototype,"effect",2),u([s.property({type:Number,attribute:"dot-radius"})],n.SomeShadeImage.prototype,"dotRadius",2),u([s.property({type:Number,attribute:"grid-size"})],n.SomeShadeImage.prototype,"gridSize",2),u([s.property({type:Number,attribute:"angle-c"})],n.SomeShadeImage.prototype,"angleC",2),u([s.property({type:Number,attribute:"angle-m"})],n.SomeShadeImage.prototype,"angleM",2),u([s.property({type:Number,attribute:"angle-y"})],n.SomeShadeImage.prototype,"angleY",2),u([s.property({type:Number,attribute:"angle-k"})],n.SomeShadeImage.prototype,"angleK",2),u([s.property({attribute:"duotone-color"})],n.SomeShadeImage.prototype,"duotoneColor",2),u([s.property({type:Number})],n.SomeShadeImage.prototype,"angle",2),u([s.property({type:Number})],n.SomeShadeImage.prototype,"threshold",2),u([s.property({type:Number,attribute:"sort-direction"})],n.SomeShadeImage.prototype,"sortDirection",2),u([s.property({type:Number,attribute:"sort-span"})],n.SomeShadeImage.prototype,"sortSpan",2),u([s.property({type:Number,attribute:"dot-offset-x"})],n.SomeShadeImage.prototype,"dotOffsetX",2),u([s.property({type:Number,attribute:"dot-offset-y"})],n.SomeShadeImage.prototype,"dotOffsetY",2),u([s.property({attribute:"bg-color"})],n.SomeShadeImage.prototype,"bgColor",2),u([s.state()],n.SomeShadeImage.prototype,"_webglAvailable",2),n.SomeShadeImage=u([s.customElement("some-shade-image")],n.SomeShadeImage),n.get=p,n.list=D,n.register=h,Object.defineProperty(n,Symbol.toStringTag,{value:"Module"})}));
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "@johnfmorton/some-shade",
3
+ "version": "0.1.0-beta.1",
4
+ "type": "module",
5
+ "main": "./dist/some-shade.cjs.js",
6
+ "module": "./dist/some-shade.es.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/some-shade.es.js",
12
+ "require": "./dist/some-shade.cjs.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "dependencies": {
19
+ "lit": "^3.2.0"
20
+ },
21
+ "devDependencies": {
22
+ "typescript": "^5.5.0",
23
+ "vite": "^6.0.0",
24
+ "vite-plugin-dts": "^4.0.0"
25
+ },
26
+ "scripts": {
27
+ "dev": "vite build --watch",
28
+ "build": "vite build"
29
+ }
30
+ }