@yeonseong/magic-loading 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs ADDED
@@ -0,0 +1,9 @@
1
+ "use strict";var I=Object.defineProperty;var q=Object.getOwnPropertyDescriptor;var K=Object.getOwnPropertyNames;var F=Object.prototype.hasOwnProperty;var _=(r,e)=>{for(var t in e)I(r,t,{get:e[t],enumerable:!0})},Z=(r,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of K(e))!F.call(r,n)&&n!==t&&I(r,n,{get:()=>e[n],enumerable:!(i=q(e,n))||i.enumerable});return r};var J=r=>Z(I({},"__esModule",{value:!0}),r);var W={};_(W,{MagicLoadingElement:()=>d,create:()=>D,generateMagicCircle:()=>C,hashToParams:()=>S,registerComponent:()=>y});module.exports=J(W);function V(r){let e=2166136261;for(let t=0;t<r.length;t++)e^=r.charCodeAt(t),e=Math.imul(e,16777619);return e>>>0}function S(r){let e=V(r),t=V(r+"\0"),i=2+e%3,n=3+(e>>>2)%6,s=e>>>5&3,o=e%360,l=t%360,f=(e>>>8)%24,h=[],b=[];for(let u=0;u<i;u++)h.push(6+(t>>>u*3)%7),b.push(t>>>u+16&1?1:-1);return{ringCount:i,polygonSides:n,glyphSetIndex:s,glyphsPerRing:h,primaryHue:o,secondaryHue:l,centralSymbolIndex:f,rotationDirections:b,seed:e}}var z="http://www.w3.org/2000/svg";function a(r,e={}){let t=document.createElementNS(z,r);for(let[i,n]of Object.entries(e))t.setAttribute(i,n);return t}function N(r){return a("svg",{xmlns:z,viewBox:"0 0 200 200",width:String(r),height:String(r)})}function A(r,e,t,i){let n=(i-90)*Math.PI/180;return{x:r+t*Math.cos(n),y:e+t*Math.sin(n)}}function G(r,e,t,i,n){let s=[];for(let o=0;o<i;o++){let l=n+360/i*o,{x:f,y:h}=A(r,e,t,l);s.push(`${f},${h}`)}return`M${s.join("L")}Z`}var Y=[["\u16A0","\u16A2","\u16A6","\u16A8","\u16B1","\u16B2","\u16B7","\u16B9","\u16BA","\u16BE","\u16C1","\u16C3","\u16C7","\u16C8","\u16C9","\u16CA","\u16CF","\u16D2","\u16D6","\u16D7","\u16DA","\u16DC","\u16DE","\u16DF"],["\u2609","\u263D","\u263F","\u2640","\u2642","\u2643","\u2644","\u2645","\u2646","\u2295","\u2296","\u2297","\u2298","\u2299","\u229B","\u229C","\u229D","\u25B3","\u25BD","\u260A","\u260B","\u26B6","\u26B7","\u26B8"],["\u2648","\u2649","\u264A","\u264B","\u264C","\u264D","\u264E","\u264F","\u2650","\u2651","\u2652","\u2653","\u26CE","\u2605","\u2606","\u2726","\u2727","\u22B9","\u22C6","\u2736","\u2737","\u2738","\u2739","\u273A"],["\u2721","\u2B21","\u25C8","\u25B3","\u2606","\u2727","\u229B","\u2295","\u25C7","\u25A3","\u2B22","\u2B1F","\u25C9","\u25CE","\u25CD","\u25CC","\u229A","\u2299","\u232C","\u23E3","\u23E5","\u23E2","\u2394","\u27D0"]];function E(r,e,t){let i=Y[r%Y.length],n=[],s=7,o=t%i.length;for(let l=0;l<e;l++)n.push(i[o%i.length]),o+=s;return n}var Q=0;function C(r,e){let n=`ml-glow-${Q++}`,s=N(e);s.style.setProperty("--ml-color-primary",`hsl(${r.primaryHue}, 80%, 65%)`),s.style.setProperty("--ml-color-secondary",`hsl(${r.secondaryHue}, 70%, 55%)`),s.style.setProperty("--ml-color-glow",`hsl(${r.primaryHue}, 90%, 70%)`);let o=a("defs"),l=a("filter",{id:n,x:"-50%",y:"-50%",width:"200%",height:"200%"}),f=a("feGaussianBlur",{in:"SourceGraphic",stdDeviation:"2",result:"blur"}),h=a("feMerge"),b=a("feMergeNode",{in:"blur"}),u=a("feMergeNode",{in:"SourceGraphic"});h.appendChild(b),h.appendChild(u),l.appendChild(f),l.appendChild(h),o.appendChild(l),s.appendChild(o);let R=60/r.ringCount;for(let c=0;c<r.ringCount;c++){let O=90-c*R,g=a("g");g.classList.add("ml-ring"),g.dataset.ring=String(c),g.style.opacity="0.15",g.style.willChange="transform, opacity";let $=a("circle",{cx:String(100),cy:String(100),r:String(O),fill:"none","stroke-width":c===0?"1.5":"1","stroke-dasharray":c%2===0?"6 3":"2 4"});$.style.stroke="var(--ml-color-primary)",g.appendChild($);let P=r.glyphsPerRing[c],j=E(r.glyphSetIndex,P,r.seed+c);for(let v=0;v<P;v++){let B=360/P*v,{x:H,y:X}=A(100,100,O,B),w=a("text",{x:String(H),y:String(X),"text-anchor":"middle","dominant-baseline":"central","font-size":c===0?"10":"8"});w.style.fill="var(--ml-color-primary)",w.textContent=j[v],g.appendChild(w)}g.setAttribute("filter",`url(#${n})`),s.appendChild(g)}let p=a("g");p.classList.add("ml-polygon"),p.style.opacity="0.15",p.style.willChange="transform, opacity";let k=90-r.ringCount*R-5,T=a("path",{d:G(100,100,k,r.polygonSides,0),fill:"none","stroke-width":"1.2"});if(T.style.stroke="var(--ml-color-secondary)",p.appendChild(T),r.polygonSides>=4){let c=a("path",{d:G(100,100,k*.7,r.polygonSides,360/r.polygonSides/2),fill:"none","stroke-width":"0.8"});c.style.stroke="var(--ml-color-secondary)",p.appendChild(c)}p.setAttribute("filter",`url(#${n})`),s.appendChild(p);let m=a("g");m.classList.add("ml-center"),m.style.opacity="0.15",m.style.willChange="transform, opacity";let L=E(r.glyphSetIndex,24,r.seed),M=a("text",{x:String(100),y:String(100),"text-anchor":"middle","dominant-baseline":"central","font-size":"18"});return M.style.fill="var(--ml-color-primary)",M.textContent=L[r.centralSymbolIndex%L.length],m.appendChild(M),m.setAttribute("filter",`url(#${n})`),s.appendChild(m),s}var x=class{constructor(e,t){this.rafId=null;this.lastTime=0;this.observer=null;this.visible=!0;this.burstResolve=null;this.tick=e=>{if(this.rafId=requestAnimationFrame(this.tick),!this.visible)return;let t=Math.min((e-this.lastTime)/1e3,.1);this.lastTime=e,this.state.burstPhase>=0?this.updateBurst(t):this.state.progress===null?this.updateIndeterminate(e,t):this.updateDeterminate(t),this.applyState()};this.svg=e,this.params=t,this.state={progress:null,ringOpacities:new Array(t.ringCount).fill(.15),ringRotations:new Array(t.ringCount).fill(0),ringRotationSpeeds:new Array(t.ringCount).fill(10),glowIntensity:0,burstPhase:-1}}setProgress(e){this.state.progress=e}start(){typeof IntersectionObserver<"u"&&(this.observer=new IntersectionObserver(e=>{this.visible=e[0]?.isIntersecting??!0},{threshold:0}),this.observer.observe(this.svg)),this.lastTime=performance.now(),this.tick(this.lastTime)}triggerBurst(){return new Promise(e=>{this.burstResolve=e,this.state.burstPhase=0})}destroy(){this.rafId!==null&&(cancelAnimationFrame(this.rafId),this.rafId=null),this.observer?.disconnect(),this.observer=null}updateDeterminate(e){let t=Math.max(0,Math.min(1,this.state.progress)),{ringCount:i}=this.params;for(let s=0;s<i;s++){let o=(s+1)/(i+2),l=Math.max(0,Math.min(1,(t-o*.5)/(1-o*.5)));this.state.ringOpacities[s]=.15+.85*l}let n=10+40*t;for(let s=0;s<i;s++)this.state.ringRotationSpeeds[s]=n*(1-s*.15),this.state.ringRotations[s]+=this.state.ringRotationSpeeds[s]*e*this.params.rotationDirections[s];this.state.glowIntensity=t*t}updateIndeterminate(e,t){let{ringCount:i}=this.params,n=e/1e3;for(let s=0;s<i;s++){let o=s*Math.PI*2/i;this.state.ringOpacities[s]=.3+.4*Math.sin(n*Math.PI+o)}for(let s=0;s<i;s++)this.state.ringRotations[s]+=20*t*this.params.rotationDirections[s];this.state.glowIntensity=.3+.3*Math.sin(n*Math.PI*.5)}updateBurst(e){this.state.burstPhase+=e/.5;let t=this.state.burstPhase;if(t>=1){let n=1-Math.min(1,(t-1)/.3);for(let s=0;s<this.params.ringCount;s++)this.state.ringOpacities[s]=n,this.state.ringRotations[s]+=80*e*this.params.rotationDirections[s];this.state.glowIntensity=3*n,t>=1.3&&(this.state.burstPhase=-1,this.burstResolve?.(),this.burstResolve=null);return}for(let i=0;i<this.params.ringCount;i++)this.state.ringOpacities[i]=1,this.state.ringRotations[i]+=(50+80*t)*e*this.params.rotationDirections[i];this.state.glowIntensity=1+2*t}applyState(){this.svg.querySelectorAll(".ml-ring").forEach((s,o)=>{s.style.opacity=String(this.state.ringOpacities[o]??.15),s.setAttribute("transform",`rotate(${this.state.ringRotations[o]??0}, 100, 100)`)});let t=this.svg.querySelector(".ml-polygon");if(t){let s=this.state.progress===null?.3+.3*Math.sin(performance.now()/1e3*Math.PI*.7):this.state.burstPhase>=0?1:.15+.85*Math.max(0,Math.min(1,(this.state.progress??0)-.5)*2);t.style.opacity=String(s)}let i=this.svg.querySelector(".ml-center");if(i){let s=this.state.progress===null?.4+.3*Math.sin(performance.now()/1e3*Math.PI*.3):this.state.burstPhase>=0?1:.15+.85*Math.max(0,this.state.progress??0);i.style.opacity=String(s)}let n=this.svg.querySelector("feGaussianBlur");n&&n.setAttribute("stdDeviation",String(2+this.state.glowIntensity*4))}};var U=`
2
+ :host {
3
+ display: inline-block;
4
+ line-height: 0;
5
+ }
6
+ svg {
7
+ display: block;
8
+ }
9
+ `,d=class extends HTMLElement{constructor(){super();this.animator=null;this.shadow=this.attachShadow({mode:"open"});let t=document.createElement("style");t.textContent=U,this.shadow.appendChild(t)}connectedCallback(){this.render()}disconnectedCallback(){this.animator?.destroy(),this.animator=null}attributeChangedCallback(t,i,n){if(i!==n){if(t==="text")this.render();else if(t==="progress")this.animator&&this.animator.setProgress(n===null||n===""?null:Number(n));else if(t==="size"){let s=this.shadow.querySelector("svg");if(s){let o=String(this.getSize());s.setAttribute("width",o),s.setAttribute("height",o)}}}}complete(){return this.animator?this.animator.triggerBurst():Promise.resolve()}getSize(){return Number(this.getAttribute("size"))||120}render(){this.animator?.destroy(),this.animator=null;let t=this.shadow.querySelector("svg");t&&t.remove();let i=this.getAttribute("text")||"";if(!i)return;let n=S(i),s=C(n,this.getSize());this.shadow.appendChild(s),this.animator=new x(s,n);let o=this.getAttribute("progress");this.animator.setProgress(o===null||o===""?null:Number(o)),this.animator.start()}};d.observedAttributes=["text","progress","size"];function y(){typeof customElements<"u"&&!customElements.get("magic-loading")&&customElements.define("magic-loading",d)}function D(r,e){y();let t=document.createElement("magic-loading");return t.setAttribute("text",e.text),e.size&&t.setAttribute("size",String(e.size)),e.progress!==void 0&&e.progress!==null&&t.setAttribute("progress",String(e.progress)),r.appendChild(t),{setProgress(i){i===null?t.removeAttribute("progress"):t.setAttribute("progress",String(i))},setText(i){t.setAttribute("text",i)},async complete(){await t.complete()},destroy(){t.remove()}}}y();0&&(module.exports={MagicLoadingElement,create,generateMagicCircle,hashToParams,registerComponent});
@@ -0,0 +1,52 @@
1
+ interface MagicCircleParams {
2
+ ringCount: number;
3
+ polygonSides: number;
4
+ glyphSetIndex: number;
5
+ glyphsPerRing: number[];
6
+ primaryHue: number;
7
+ secondaryHue: number;
8
+ centralSymbolIndex: number;
9
+ rotationDirections: number[];
10
+ seed: number;
11
+ }
12
+ interface MagicLoadingOptions {
13
+ text: string;
14
+ size?: number;
15
+ progress?: number | null;
16
+ }
17
+ interface AnimationState {
18
+ progress: number | null;
19
+ ringOpacities: number[];
20
+ ringRotations: number[];
21
+ ringRotationSpeeds: number[];
22
+ glowIntensity: number;
23
+ burstPhase: number;
24
+ }
25
+ interface MagicLoadingInstance {
26
+ setProgress(progress: number | null): void;
27
+ setText(text: string): void;
28
+ complete(): Promise<void>;
29
+ destroy(): void;
30
+ }
31
+
32
+ declare function hashToParams(text: string): MagicCircleParams;
33
+
34
+ declare function generateMagicCircle(params: MagicCircleParams, size: number): SVGSVGElement;
35
+
36
+ declare class MagicLoadingElement extends HTMLElement {
37
+ static observedAttributes: string[];
38
+ private animator;
39
+ private shadow;
40
+ constructor();
41
+ connectedCallback(): void;
42
+ disconnectedCallback(): void;
43
+ attributeChangedCallback(name: string, oldVal: string | null, newVal: string | null): void;
44
+ complete(): Promise<void>;
45
+ private getSize;
46
+ private render;
47
+ }
48
+ declare function registerComponent(): void;
49
+
50
+ declare function create(container: HTMLElement, options: MagicLoadingOptions): MagicLoadingInstance;
51
+
52
+ export { type AnimationState, type MagicCircleParams, MagicLoadingElement, type MagicLoadingInstance, type MagicLoadingOptions, create, generateMagicCircle, hashToParams, registerComponent };
@@ -0,0 +1,52 @@
1
+ interface MagicCircleParams {
2
+ ringCount: number;
3
+ polygonSides: number;
4
+ glyphSetIndex: number;
5
+ glyphsPerRing: number[];
6
+ primaryHue: number;
7
+ secondaryHue: number;
8
+ centralSymbolIndex: number;
9
+ rotationDirections: number[];
10
+ seed: number;
11
+ }
12
+ interface MagicLoadingOptions {
13
+ text: string;
14
+ size?: number;
15
+ progress?: number | null;
16
+ }
17
+ interface AnimationState {
18
+ progress: number | null;
19
+ ringOpacities: number[];
20
+ ringRotations: number[];
21
+ ringRotationSpeeds: number[];
22
+ glowIntensity: number;
23
+ burstPhase: number;
24
+ }
25
+ interface MagicLoadingInstance {
26
+ setProgress(progress: number | null): void;
27
+ setText(text: string): void;
28
+ complete(): Promise<void>;
29
+ destroy(): void;
30
+ }
31
+
32
+ declare function hashToParams(text: string): MagicCircleParams;
33
+
34
+ declare function generateMagicCircle(params: MagicCircleParams, size: number): SVGSVGElement;
35
+
36
+ declare class MagicLoadingElement extends HTMLElement {
37
+ static observedAttributes: string[];
38
+ private animator;
39
+ private shadow;
40
+ constructor();
41
+ connectedCallback(): void;
42
+ disconnectedCallback(): void;
43
+ attributeChangedCallback(name: string, oldVal: string | null, newVal: string | null): void;
44
+ complete(): Promise<void>;
45
+ private getSize;
46
+ private render;
47
+ }
48
+ declare function registerComponent(): void;
49
+
50
+ declare function create(container: HTMLElement, options: MagicLoadingOptions): MagicLoadingInstance;
51
+
52
+ export { type AnimationState, type MagicCircleParams, MagicLoadingElement, type MagicLoadingInstance, type MagicLoadingOptions, create, generateMagicCircle, hashToParams, registerComponent };
@@ -0,0 +1,9 @@
1
+ "use strict";var MagicLoading=(()=>{var I=Object.defineProperty;var q=Object.getOwnPropertyDescriptor;var K=Object.getOwnPropertyNames;var F=Object.prototype.hasOwnProperty;var _=(r,e)=>{for(var t in e)I(r,t,{get:e[t],enumerable:!0})},Z=(r,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of K(e))!F.call(r,n)&&n!==t&&I(r,n,{get:()=>e[n],enumerable:!(i=q(e,n))||i.enumerable});return r};var J=r=>Z(I({},"__esModule",{value:!0}),r);var W={};_(W,{MagicLoadingElement:()=>d,create:()=>D,generateMagicCircle:()=>C,hashToParams:()=>S,registerComponent:()=>y});function V(r){let e=2166136261;for(let t=0;t<r.length;t++)e^=r.charCodeAt(t),e=Math.imul(e,16777619);return e>>>0}function S(r){let e=V(r),t=V(r+"\0"),i=2+e%3,n=3+(e>>>2)%6,s=e>>>5&3,o=e%360,l=t%360,f=(e>>>8)%24,h=[],b=[];for(let u=0;u<i;u++)h.push(6+(t>>>u*3)%7),b.push(t>>>u+16&1?1:-1);return{ringCount:i,polygonSides:n,glyphSetIndex:s,glyphsPerRing:h,primaryHue:o,secondaryHue:l,centralSymbolIndex:f,rotationDirections:b,seed:e}}var z="http://www.w3.org/2000/svg";function a(r,e={}){let t=document.createElementNS(z,r);for(let[i,n]of Object.entries(e))t.setAttribute(i,n);return t}function N(r){return a("svg",{xmlns:z,viewBox:"0 0 200 200",width:String(r),height:String(r)})}function A(r,e,t,i){let n=(i-90)*Math.PI/180;return{x:r+t*Math.cos(n),y:e+t*Math.sin(n)}}function G(r,e,t,i,n){let s=[];for(let o=0;o<i;o++){let l=n+360/i*o,{x:f,y:h}=A(r,e,t,l);s.push(`${f},${h}`)}return`M${s.join("L")}Z`}var Y=[["\u16A0","\u16A2","\u16A6","\u16A8","\u16B1","\u16B2","\u16B7","\u16B9","\u16BA","\u16BE","\u16C1","\u16C3","\u16C7","\u16C8","\u16C9","\u16CA","\u16CF","\u16D2","\u16D6","\u16D7","\u16DA","\u16DC","\u16DE","\u16DF"],["\u2609","\u263D","\u263F","\u2640","\u2642","\u2643","\u2644","\u2645","\u2646","\u2295","\u2296","\u2297","\u2298","\u2299","\u229B","\u229C","\u229D","\u25B3","\u25BD","\u260A","\u260B","\u26B6","\u26B7","\u26B8"],["\u2648","\u2649","\u264A","\u264B","\u264C","\u264D","\u264E","\u264F","\u2650","\u2651","\u2652","\u2653","\u26CE","\u2605","\u2606","\u2726","\u2727","\u22B9","\u22C6","\u2736","\u2737","\u2738","\u2739","\u273A"],["\u2721","\u2B21","\u25C8","\u25B3","\u2606","\u2727","\u229B","\u2295","\u25C7","\u25A3","\u2B22","\u2B1F","\u25C9","\u25CE","\u25CD","\u25CC","\u229A","\u2299","\u232C","\u23E3","\u23E5","\u23E2","\u2394","\u27D0"]];function E(r,e,t){let i=Y[r%Y.length],n=[],s=7,o=t%i.length;for(let l=0;l<e;l++)n.push(i[o%i.length]),o+=s;return n}var Q=0;function C(r,e){let n=`ml-glow-${Q++}`,s=N(e);s.style.setProperty("--ml-color-primary",`hsl(${r.primaryHue}, 80%, 65%)`),s.style.setProperty("--ml-color-secondary",`hsl(${r.secondaryHue}, 70%, 55%)`),s.style.setProperty("--ml-color-glow",`hsl(${r.primaryHue}, 90%, 70%)`);let o=a("defs"),l=a("filter",{id:n,x:"-50%",y:"-50%",width:"200%",height:"200%"}),f=a("feGaussianBlur",{in:"SourceGraphic",stdDeviation:"2",result:"blur"}),h=a("feMerge"),b=a("feMergeNode",{in:"blur"}),u=a("feMergeNode",{in:"SourceGraphic"});h.appendChild(b),h.appendChild(u),l.appendChild(f),l.appendChild(h),o.appendChild(l),s.appendChild(o);let R=60/r.ringCount;for(let c=0;c<r.ringCount;c++){let O=90-c*R,g=a("g");g.classList.add("ml-ring"),g.dataset.ring=String(c),g.style.opacity="0.15",g.style.willChange="transform, opacity";let $=a("circle",{cx:String(100),cy:String(100),r:String(O),fill:"none","stroke-width":c===0?"1.5":"1","stroke-dasharray":c%2===0?"6 3":"2 4"});$.style.stroke="var(--ml-color-primary)",g.appendChild($);let P=r.glyphsPerRing[c],j=E(r.glyphSetIndex,P,r.seed+c);for(let v=0;v<P;v++){let B=360/P*v,{x:H,y:X}=A(100,100,O,B),w=a("text",{x:String(H),y:String(X),"text-anchor":"middle","dominant-baseline":"central","font-size":c===0?"10":"8"});w.style.fill="var(--ml-color-primary)",w.textContent=j[v],g.appendChild(w)}g.setAttribute("filter",`url(#${n})`),s.appendChild(g)}let p=a("g");p.classList.add("ml-polygon"),p.style.opacity="0.15",p.style.willChange="transform, opacity";let k=90-r.ringCount*R-5,T=a("path",{d:G(100,100,k,r.polygonSides,0),fill:"none","stroke-width":"1.2"});if(T.style.stroke="var(--ml-color-secondary)",p.appendChild(T),r.polygonSides>=4){let c=a("path",{d:G(100,100,k*.7,r.polygonSides,360/r.polygonSides/2),fill:"none","stroke-width":"0.8"});c.style.stroke="var(--ml-color-secondary)",p.appendChild(c)}p.setAttribute("filter",`url(#${n})`),s.appendChild(p);let m=a("g");m.classList.add("ml-center"),m.style.opacity="0.15",m.style.willChange="transform, opacity";let L=E(r.glyphSetIndex,24,r.seed),M=a("text",{x:String(100),y:String(100),"text-anchor":"middle","dominant-baseline":"central","font-size":"18"});return M.style.fill="var(--ml-color-primary)",M.textContent=L[r.centralSymbolIndex%L.length],m.appendChild(M),m.setAttribute("filter",`url(#${n})`),s.appendChild(m),s}var x=class{constructor(e,t){this.rafId=null;this.lastTime=0;this.observer=null;this.visible=!0;this.burstResolve=null;this.tick=e=>{if(this.rafId=requestAnimationFrame(this.tick),!this.visible)return;let t=Math.min((e-this.lastTime)/1e3,.1);this.lastTime=e,this.state.burstPhase>=0?this.updateBurst(t):this.state.progress===null?this.updateIndeterminate(e,t):this.updateDeterminate(t),this.applyState()};this.svg=e,this.params=t,this.state={progress:null,ringOpacities:new Array(t.ringCount).fill(.15),ringRotations:new Array(t.ringCount).fill(0),ringRotationSpeeds:new Array(t.ringCount).fill(10),glowIntensity:0,burstPhase:-1}}setProgress(e){this.state.progress=e}start(){typeof IntersectionObserver<"u"&&(this.observer=new IntersectionObserver(e=>{this.visible=e[0]?.isIntersecting??!0},{threshold:0}),this.observer.observe(this.svg)),this.lastTime=performance.now(),this.tick(this.lastTime)}triggerBurst(){return new Promise(e=>{this.burstResolve=e,this.state.burstPhase=0})}destroy(){this.rafId!==null&&(cancelAnimationFrame(this.rafId),this.rafId=null),this.observer?.disconnect(),this.observer=null}updateDeterminate(e){let t=Math.max(0,Math.min(1,this.state.progress)),{ringCount:i}=this.params;for(let s=0;s<i;s++){let o=(s+1)/(i+2),l=Math.max(0,Math.min(1,(t-o*.5)/(1-o*.5)));this.state.ringOpacities[s]=.15+.85*l}let n=10+40*t;for(let s=0;s<i;s++)this.state.ringRotationSpeeds[s]=n*(1-s*.15),this.state.ringRotations[s]+=this.state.ringRotationSpeeds[s]*e*this.params.rotationDirections[s];this.state.glowIntensity=t*t}updateIndeterminate(e,t){let{ringCount:i}=this.params,n=e/1e3;for(let s=0;s<i;s++){let o=s*Math.PI*2/i;this.state.ringOpacities[s]=.3+.4*Math.sin(n*Math.PI+o)}for(let s=0;s<i;s++)this.state.ringRotations[s]+=20*t*this.params.rotationDirections[s];this.state.glowIntensity=.3+.3*Math.sin(n*Math.PI*.5)}updateBurst(e){this.state.burstPhase+=e/.5;let t=this.state.burstPhase;if(t>=1){let n=1-Math.min(1,(t-1)/.3);for(let s=0;s<this.params.ringCount;s++)this.state.ringOpacities[s]=n,this.state.ringRotations[s]+=80*e*this.params.rotationDirections[s];this.state.glowIntensity=3*n,t>=1.3&&(this.state.burstPhase=-1,this.burstResolve?.(),this.burstResolve=null);return}for(let i=0;i<this.params.ringCount;i++)this.state.ringOpacities[i]=1,this.state.ringRotations[i]+=(50+80*t)*e*this.params.rotationDirections[i];this.state.glowIntensity=1+2*t}applyState(){this.svg.querySelectorAll(".ml-ring").forEach((s,o)=>{s.style.opacity=String(this.state.ringOpacities[o]??.15),s.setAttribute("transform",`rotate(${this.state.ringRotations[o]??0}, 100, 100)`)});let t=this.svg.querySelector(".ml-polygon");if(t){let s=this.state.progress===null?.3+.3*Math.sin(performance.now()/1e3*Math.PI*.7):this.state.burstPhase>=0?1:.15+.85*Math.max(0,Math.min(1,(this.state.progress??0)-.5)*2);t.style.opacity=String(s)}let i=this.svg.querySelector(".ml-center");if(i){let s=this.state.progress===null?.4+.3*Math.sin(performance.now()/1e3*Math.PI*.3):this.state.burstPhase>=0?1:.15+.85*Math.max(0,this.state.progress??0);i.style.opacity=String(s)}let n=this.svg.querySelector("feGaussianBlur");n&&n.setAttribute("stdDeviation",String(2+this.state.glowIntensity*4))}};var U=`
2
+ :host {
3
+ display: inline-block;
4
+ line-height: 0;
5
+ }
6
+ svg {
7
+ display: block;
8
+ }
9
+ `,d=class extends HTMLElement{constructor(){super();this.animator=null;this.shadow=this.attachShadow({mode:"open"});let t=document.createElement("style");t.textContent=U,this.shadow.appendChild(t)}connectedCallback(){this.render()}disconnectedCallback(){this.animator?.destroy(),this.animator=null}attributeChangedCallback(t,i,n){if(i!==n){if(t==="text")this.render();else if(t==="progress")this.animator&&this.animator.setProgress(n===null||n===""?null:Number(n));else if(t==="size"){let s=this.shadow.querySelector("svg");if(s){let o=String(this.getSize());s.setAttribute("width",o),s.setAttribute("height",o)}}}}complete(){return this.animator?this.animator.triggerBurst():Promise.resolve()}getSize(){return Number(this.getAttribute("size"))||120}render(){this.animator?.destroy(),this.animator=null;let t=this.shadow.querySelector("svg");t&&t.remove();let i=this.getAttribute("text")||"";if(!i)return;let n=S(i),s=C(n,this.getSize());this.shadow.appendChild(s),this.animator=new x(s,n);let o=this.getAttribute("progress");this.animator.setProgress(o===null||o===""?null:Number(o)),this.animator.start()}};d.observedAttributes=["text","progress","size"];function y(){typeof customElements<"u"&&!customElements.get("magic-loading")&&customElements.define("magic-loading",d)}function D(r,e){y();let t=document.createElement("magic-loading");return t.setAttribute("text",e.text),e.size&&t.setAttribute("size",String(e.size)),e.progress!==void 0&&e.progress!==null&&t.setAttribute("progress",String(e.progress)),r.appendChild(t),{setProgress(i){i===null?t.removeAttribute("progress"):t.setAttribute("progress",String(i))},setText(i){t.setAttribute("text",i)},async complete(){await t.complete()},destroy(){t.remove()}}}y();return J(W);})();
package/dist/index.js ADDED
@@ -0,0 +1,9 @@
1
+ function $(i){let s=2166136261;for(let t=0;t<i.length;t++)s^=i.charCodeAt(t),s=Math.imul(s,16777619);return s>>>0}function P(i){let s=$(i),t=$(i+"\0"),r=2+s%3,n=3+(s>>>2)%6,e=s>>>5&3,o=s%360,l=t%360,d=(s>>>8)%24,h=[],b=[];for(let u=0;u<r;u++)h.push(6+(t>>>u*3)%7),b.push(t>>>u+16&1?1:-1);return{ringCount:r,polygonSides:n,glyphSetIndex:e,glyphsPerRing:h,primaryHue:o,secondaryHue:l,centralSymbolIndex:d,rotationDirections:b,seed:s}}var V="http://www.w3.org/2000/svg";function a(i,s={}){let t=document.createElementNS(V,i);for(let[r,n]of Object.entries(s))t.setAttribute(r,n);return t}function z(i){return a("svg",{xmlns:V,viewBox:"0 0 200 200",width:String(i),height:String(i)})}function w(i,s,t,r){let n=(r-90)*Math.PI/180;return{x:i+t*Math.cos(n),y:s+t*Math.sin(n)}}function I(i,s,t,r,n){let e=[];for(let o=0;o<r;o++){let l=n+360/r*o,{x:d,y:h}=w(i,s,t,l);e.push(`${d},${h}`)}return`M${e.join("L")}Z`}var N=[["\u16A0","\u16A2","\u16A6","\u16A8","\u16B1","\u16B2","\u16B7","\u16B9","\u16BA","\u16BE","\u16C1","\u16C3","\u16C7","\u16C8","\u16C9","\u16CA","\u16CF","\u16D2","\u16D6","\u16D7","\u16DA","\u16DC","\u16DE","\u16DF"],["\u2609","\u263D","\u263F","\u2640","\u2642","\u2643","\u2644","\u2645","\u2646","\u2295","\u2296","\u2297","\u2298","\u2299","\u229B","\u229C","\u229D","\u25B3","\u25BD","\u260A","\u260B","\u26B6","\u26B7","\u26B8"],["\u2648","\u2649","\u264A","\u264B","\u264C","\u264D","\u264E","\u264F","\u2650","\u2651","\u2652","\u2653","\u26CE","\u2605","\u2606","\u2726","\u2727","\u22B9","\u22C6","\u2736","\u2737","\u2738","\u2739","\u273A"],["\u2721","\u2B21","\u25C8","\u25B3","\u2606","\u2727","\u229B","\u2295","\u25C7","\u25A3","\u2B22","\u2B1F","\u25C9","\u25CE","\u25CD","\u25CC","\u229A","\u2299","\u232C","\u23E3","\u23E5","\u23E2","\u2394","\u27D0"]];function A(i,s,t){let r=N[i%N.length],n=[],e=7,o=t%r.length;for(let l=0;l<s;l++)n.push(r[o%r.length]),o+=e;return n}var H=0;function G(i,s){let n=`ml-glow-${H++}`,e=z(s);e.style.setProperty("--ml-color-primary",`hsl(${i.primaryHue}, 80%, 65%)`),e.style.setProperty("--ml-color-secondary",`hsl(${i.secondaryHue}, 70%, 55%)`),e.style.setProperty("--ml-color-glow",`hsl(${i.primaryHue}, 90%, 70%)`);let o=a("defs"),l=a("filter",{id:n,x:"-50%",y:"-50%",width:"200%",height:"200%"}),d=a("feGaussianBlur",{in:"SourceGraphic",stdDeviation:"2",result:"blur"}),h=a("feMerge"),b=a("feMergeNode",{in:"blur"}),u=a("feMergeNode",{in:"SourceGraphic"});h.appendChild(b),h.appendChild(u),l.appendChild(d),l.appendChild(h),o.appendChild(l),e.appendChild(o);let E=60/i.ringCount;for(let c=0;c<i.ringCount;c++){let L=90-c*E,g=a("g");g.classList.add("ml-ring"),g.dataset.ring=String(c),g.style.opacity="0.15",g.style.willChange="transform, opacity";let O=a("circle",{cx:String(100),cy:String(100),r:String(L),fill:"none","stroke-width":c===0?"1.5":"1","stroke-dasharray":c%2===0?"6 3":"2 4"});O.style.stroke="var(--ml-color-primary)",g.appendChild(O);let x=i.glyphsPerRing[c],Y=A(i.glyphSetIndex,x,i.seed+c);for(let v=0;v<x;v++){let D=360/x*v,{x:j,y:B}=w(100,100,L,D),M=a("text",{x:String(j),y:String(B),"text-anchor":"middle","dominant-baseline":"central","font-size":c===0?"10":"8"});M.style.fill="var(--ml-color-primary)",M.textContent=Y[v],g.appendChild(M)}g.setAttribute("filter",`url(#${n})`),e.appendChild(g)}let p=a("g");p.classList.add("ml-polygon"),p.style.opacity="0.15",p.style.willChange="transform, opacity";let R=90-i.ringCount*E-5,k=a("path",{d:I(100,100,R,i.polygonSides,0),fill:"none","stroke-width":"1.2"});if(k.style.stroke="var(--ml-color-secondary)",p.appendChild(k),i.polygonSides>=4){let c=a("path",{d:I(100,100,R*.7,i.polygonSides,360/i.polygonSides/2),fill:"none","stroke-width":"0.8"});c.style.stroke="var(--ml-color-secondary)",p.appendChild(c)}p.setAttribute("filter",`url(#${n})`),e.appendChild(p);let m=a("g");m.classList.add("ml-center"),m.style.opacity="0.15",m.style.willChange="transform, opacity";let T=A(i.glyphSetIndex,24,i.seed),C=a("text",{x:String(100),y:String(100),"text-anchor":"middle","dominant-baseline":"central","font-size":"18"});return C.style.fill="var(--ml-color-primary)",C.textContent=T[i.centralSymbolIndex%T.length],m.appendChild(C),m.setAttribute("filter",`url(#${n})`),e.appendChild(m),e}var S=class{constructor(s,t){this.rafId=null;this.lastTime=0;this.observer=null;this.visible=!0;this.burstResolve=null;this.tick=s=>{if(this.rafId=requestAnimationFrame(this.tick),!this.visible)return;let t=Math.min((s-this.lastTime)/1e3,.1);this.lastTime=s,this.state.burstPhase>=0?this.updateBurst(t):this.state.progress===null?this.updateIndeterminate(s,t):this.updateDeterminate(t),this.applyState()};this.svg=s,this.params=t,this.state={progress:null,ringOpacities:new Array(t.ringCount).fill(.15),ringRotations:new Array(t.ringCount).fill(0),ringRotationSpeeds:new Array(t.ringCount).fill(10),glowIntensity:0,burstPhase:-1}}setProgress(s){this.state.progress=s}start(){typeof IntersectionObserver<"u"&&(this.observer=new IntersectionObserver(s=>{this.visible=s[0]?.isIntersecting??!0},{threshold:0}),this.observer.observe(this.svg)),this.lastTime=performance.now(),this.tick(this.lastTime)}triggerBurst(){return new Promise(s=>{this.burstResolve=s,this.state.burstPhase=0})}destroy(){this.rafId!==null&&(cancelAnimationFrame(this.rafId),this.rafId=null),this.observer?.disconnect(),this.observer=null}updateDeterminate(s){let t=Math.max(0,Math.min(1,this.state.progress)),{ringCount:r}=this.params;for(let e=0;e<r;e++){let o=(e+1)/(r+2),l=Math.max(0,Math.min(1,(t-o*.5)/(1-o*.5)));this.state.ringOpacities[e]=.15+.85*l}let n=10+40*t;for(let e=0;e<r;e++)this.state.ringRotationSpeeds[e]=n*(1-e*.15),this.state.ringRotations[e]+=this.state.ringRotationSpeeds[e]*s*this.params.rotationDirections[e];this.state.glowIntensity=t*t}updateIndeterminate(s,t){let{ringCount:r}=this.params,n=s/1e3;for(let e=0;e<r;e++){let o=e*Math.PI*2/r;this.state.ringOpacities[e]=.3+.4*Math.sin(n*Math.PI+o)}for(let e=0;e<r;e++)this.state.ringRotations[e]+=20*t*this.params.rotationDirections[e];this.state.glowIntensity=.3+.3*Math.sin(n*Math.PI*.5)}updateBurst(s){this.state.burstPhase+=s/.5;let t=this.state.burstPhase;if(t>=1){let n=1-Math.min(1,(t-1)/.3);for(let e=0;e<this.params.ringCount;e++)this.state.ringOpacities[e]=n,this.state.ringRotations[e]+=80*s*this.params.rotationDirections[e];this.state.glowIntensity=3*n,t>=1.3&&(this.state.burstPhase=-1,this.burstResolve?.(),this.burstResolve=null);return}for(let r=0;r<this.params.ringCount;r++)this.state.ringOpacities[r]=1,this.state.ringRotations[r]+=(50+80*t)*s*this.params.rotationDirections[r];this.state.glowIntensity=1+2*t}applyState(){this.svg.querySelectorAll(".ml-ring").forEach((e,o)=>{e.style.opacity=String(this.state.ringOpacities[o]??.15),e.setAttribute("transform",`rotate(${this.state.ringRotations[o]??0}, 100, 100)`)});let t=this.svg.querySelector(".ml-polygon");if(t){let e=this.state.progress===null?.3+.3*Math.sin(performance.now()/1e3*Math.PI*.7):this.state.burstPhase>=0?1:.15+.85*Math.max(0,Math.min(1,(this.state.progress??0)-.5)*2);t.style.opacity=String(e)}let r=this.svg.querySelector(".ml-center");if(r){let e=this.state.progress===null?.4+.3*Math.sin(performance.now()/1e3*Math.PI*.3):this.state.burstPhase>=0?1:.15+.85*Math.max(0,this.state.progress??0);r.style.opacity=String(e)}let n=this.svg.querySelector("feGaussianBlur");n&&n.setAttribute("stdDeviation",String(2+this.state.glowIntensity*4))}};var X=`
2
+ :host {
3
+ display: inline-block;
4
+ line-height: 0;
5
+ }
6
+ svg {
7
+ display: block;
8
+ }
9
+ `,y=class extends HTMLElement{constructor(){super();this.animator=null;this.shadow=this.attachShadow({mode:"open"});let t=document.createElement("style");t.textContent=X,this.shadow.appendChild(t)}connectedCallback(){this.render()}disconnectedCallback(){this.animator?.destroy(),this.animator=null}attributeChangedCallback(t,r,n){if(r!==n){if(t==="text")this.render();else if(t==="progress")this.animator&&this.animator.setProgress(n===null||n===""?null:Number(n));else if(t==="size"){let e=this.shadow.querySelector("svg");if(e){let o=String(this.getSize());e.setAttribute("width",o),e.setAttribute("height",o)}}}}complete(){return this.animator?this.animator.triggerBurst():Promise.resolve()}getSize(){return Number(this.getAttribute("size"))||120}render(){this.animator?.destroy(),this.animator=null;let t=this.shadow.querySelector("svg");t&&t.remove();let r=this.getAttribute("text")||"";if(!r)return;let n=P(r),e=G(n,this.getSize());this.shadow.appendChild(e),this.animator=new S(e,n);let o=this.getAttribute("progress");this.animator.setProgress(o===null||o===""?null:Number(o)),this.animator.start()}};y.observedAttributes=["text","progress","size"];function f(){typeof customElements<"u"&&!customElements.get("magic-loading")&&customElements.define("magic-loading",y)}function q(i,s){f();let t=document.createElement("magic-loading");return t.setAttribute("text",s.text),s.size&&t.setAttribute("size",String(s.size)),s.progress!==void 0&&s.progress!==null&&t.setAttribute("progress",String(s.progress)),i.appendChild(t),{setProgress(r){r===null?t.removeAttribute("progress"):t.setAttribute("progress",String(r))},setText(r){t.setAttribute("text",r)},async complete(){await t.complete()},destroy(){t.remove()}}}f();export{y as MagicLoadingElement,q as create,G as generateMagicCircle,P as hashToParams,f as registerComponent};
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "@yeonseong/magic-loading",
3
+ "version": "0.1.0",
4
+ "description": "Transform boring loading spinners into unique fantasy magic circles generated from text",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js",
13
+ "require": "./dist/index.cjs"
14
+ }
15
+ },
16
+ "files": [
17
+ "dist"
18
+ ],
19
+ "scripts": {
20
+ "build": "tsup",
21
+ "dev": "tsup --watch"
22
+ },
23
+ "keywords": [
24
+ "loading",
25
+ "spinner",
26
+ "magic-circle",
27
+ "web-component",
28
+ "svg",
29
+ "fantasy"
30
+ ],
31
+ "license": "MIT",
32
+ "devDependencies": {
33
+ "tsup": "^8.0.0",
34
+ "typescript": "^5.4.0"
35
+ }
36
+ }