real-time-gradient 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,235 @@
1
+ # 🌅 dynamic-gradient
2
+
3
+ A lightweight JavaScript library for creating smooth, customizable, real-time gradients with flexible control over animation speed, direction, and hues.
4
+
5
+ ## UMD (Browser) Usage
6
+
7
+ ```html
8
+ <script src="dynamic-gradient.min.js"></script>
9
+ <script>
10
+ const gradient = DynamicGradient.init("#hero", {
11
+ type: "linear",
12
+ direction: "to right",
13
+ colors: ["#ff7e5f", "#feb47b"],
14
+ });
15
+ </script>
16
+ ```
17
+
18
+ ## ✨ Features
19
+
20
+ - 🎨 Smooth color transitions (linear, radial, conic)
21
+
22
+ - ⚡ Dynamic scheduling (interval-based animation)
23
+
24
+ - 🔄 Runtime updates (colors, speed, direction)
25
+
26
+ - 📦 Framework-agnostic — works with plain JS, React, Vue, etc.
27
+
28
+ - 🖼 Gradient-to-text clipping (textClip)
29
+
30
+ - 🛠 TypeScript typings
31
+
32
+ ## 🖼️ Basic Usage
33
+
34
+ ```html
35
+ <div id="hero" style="height: 300px;"></div>
36
+
37
+ <script type="module">
38
+ import DynamicGradient from "dynamic-gradient";
39
+
40
+ const gradient = DynamicGradient.init("#hero", {
41
+ type: "linear",
42
+ direction: "to right",
43
+ colors: ["#ff7e5f", "#feb47b"],
44
+ transitionDuration: 1000,
45
+ schedule: [
46
+ { time: "6:00", colors: ["#7fff00ff", "#ffb347ff", "#ff69b4ff"] },
47
+ { time: "18:00", colors: ["#ff4500ff", "#9370dbff", "#4682b4ff"] },
48
+ { time: "00:00", colors: ["#ffff54ff", "#ff7f50ff", "#daa520ff"] },
49
+ ],
50
+ });
51
+ </script>
52
+ ```
53
+
54
+ ## ⚙️ API Reference
55
+
56
+ `DynamicGradient.init(target, options)`
57
+ Initialize a gradient on a DOM element.
58
+
59
+ #### Parameters
60
+
61
+ - `target`: CSS selector or DOM element
62
+ - `options` : configuration object
63
+
64
+ #### Options:
65
+
66
+ - `type`: `"linear" | "radial"` (default: `"linear"` )
67
+ - `direction`: CSS gradient direction (e.g., `"to right"`, `"45deg"` )
68
+ - `colors`: array of color hex values
69
+ - `transitionDuration`: time in ms for transitions (default: `1000`)
70
+ - `schedule`: optional array of {`time: "HH:MM", colors: []`} objects
71
+ - `textClip`: boolean (default: `false`) → applies gradient as background-clip for text
72
+
73
+ ### `stopEffects()`
74
+
75
+ ```js
76
+ gradient.stopEffects();
77
+ ```
78
+
79
+ ### `triggerEffect({ applyColors, duration, hue })`
80
+
81
+ Overlay temporary effect
82
+
83
+ ```js
84
+ gradient.triggerEffect({
85
+ hue: "gold",
86
+ duration: 2000,
87
+ });
88
+ ```
89
+
90
+ ```js
91
+ gradient.triggerEffect({
92
+ applyColors: ["#9370dbff", "#4682b4ff"],
93
+ duration: 2000,
94
+ });
95
+ ```
96
+
97
+ ### `persistEffect(colors[], duration)`
98
+
99
+ Mutate a new gradient smoothly
100
+
101
+ ```js
102
+ gradient.persistEffect(["#9370db", "#4682b4"], 2000);
103
+ ```
104
+
105
+ ### `schedule([{ time: "HH:MM", colors: [] }, ...])`
106
+
107
+ Allows scheduling of time-based gradients that change automatically throughout the day.
108
+
109
+ ```js
110
+ const gradient = DynamicGradient.init("#hero", {
111
+ type: "linear",
112
+ direction: "to right",
113
+ colors: ["#ff7f50ff", "#6a5acdff", "#20b2aaff"], // default
114
+ schedule: [
115
+ { time: "06:00", colors: ["#7fff00ff", "#ffb347ff", "#ff69b4ff"] }, // morning
116
+ { time: "18:00", colors: ["#ff4500ff", "#9370dbff", "#4682b4ff"] }, // evening
117
+ { time: "00:00", colors: ["#ffff54ff", "#ff7f50ff", "#daa520ff"] }, // midnight
118
+ ],
119
+ });
120
+ ```
121
+
122
+ - `time`: "HH:MM" in `24h format`(e.g. `"06:00"`,`"18:30"` )
123
+ - `colors`: array of CSS colors for the gradient
124
+
125
+ #### Optional per-entry:
126
+
127
+ - `type`: `"linear"` or `"radial"`
128
+ - `direction`: CSS gradient direction(`"to right"`, `"45deg"`, etc.)
129
+
130
+ #### Behavior
131
+
132
+ - The most recent matching entry before or equal to the current time will be applied.
133
+ - If the time is earlier than the first scheduled entry, it wraps around and uses the last entry.
134
+ - The schedule is checked every minute, so changes align with the clock naturally.
135
+
136
+ ### `destroy()`
137
+
138
+ Stop the gradient animation and clean up.
139
+
140
+ ```js
141
+ gradient.destroy();
142
+ ```
143
+
144
+ ## 🎨 Hue Presets
145
+
146
+ Some ready-to-use gradient palettes:
147
+
148
+ ```js
149
+ hues = {
150
+ sunset: ["#ff7e5f", "#feb47b"],
151
+ ocean: ["#00c6ff", "#0072ff"],
152
+ forest: ["#11998e", "#38ef7d"],
153
+ fire: ["#ff512f", "#dd2476"],
154
+ mono: ["#ffffff", "#000000"],
155
+ };
156
+ ```
157
+
158
+ Additionally, `triggerEffect` accepts special hue keywords:
159
+
160
+ - `"white"`, `"black"`, `"gold"`, `"silver"`
161
+ - Or any custom hex string (`"#RRGGBB"`)
162
+
163
+ Usage:
164
+
165
+ ```js
166
+ gradient.setGradient({ colors: hues.forest });
167
+ ```
168
+
169
+ Or:
170
+
171
+ ```js
172
+ gradient.triggerEffect({ hue: "gold", duration: 2000 });
173
+ ```
174
+
175
+ ## 📦 TypeScript Typings
176
+
177
+ ```ts
178
+ // index.d.ts
179
+ declare module "real-time-gradient" {
180
+ type GradientType = "linear" | "radial";
181
+
182
+ type HuePreset = "white" | "black" | "gold" | "silver" | string;
183
+ // string allows custom hex codes "#RRGGBB"
184
+
185
+ interface ScheduleEntry {
186
+ time: string; // "HH:MM" in 24h format
187
+ colors: string[]; // array of CSS color values
188
+ type?: GradientType;
189
+ direction?: string;
190
+ }
191
+
192
+ interface GradientOptions {
193
+ type?: GradientType;
194
+ direction?: string;
195
+ colors?: string[];
196
+ transitionDuration?: number;
197
+ schedule?: ScheduleEntry[];
198
+ textClip?: boolean;
199
+ }
200
+
201
+ interface EffectOptions {
202
+ applyColors?: string[];
203
+ duration?: number;
204
+ hue?: HuePreset;
205
+ }
206
+
207
+ export class DynamicGradient {
208
+ constructor(container: string | HTMLElement, options?: GradientOptions);
209
+
210
+ static init(
211
+ container: string | HTMLElement,
212
+ options?: GradientOptions
213
+ ): DynamicGradient;
214
+
215
+ setGradient(options: {
216
+ colors: string[];
217
+ type?: GradientType;
218
+ direction?: string;
219
+ }): void;
220
+
221
+ schedule(entries: ScheduleEntry[]): void;
222
+
223
+ triggerEffect(options?: EffectOptions): void;
224
+
225
+ persistEffect(colors: string[], duration?: number): void;
226
+
227
+ stopEffects(): void;
228
+ destroy(): void;
229
+ }
230
+ }
231
+ ```
232
+
233
+ ## 📄 License
234
+
235
+ MIT © 2025 — @wakenedo
@@ -0,0 +1 @@
1
+ export {}
@@ -0,0 +1,231 @@
1
+ function c(n, e = "linear", t = "to right") {
2
+ return e === "linear" ? `linear-gradient(${t}, ${n.join(",")})` : `radial-gradient(circle, ${n.join(",")})`;
3
+ }
4
+ function f(n, e, t) {
5
+ const i = document.createElement("div");
6
+ return Object.assign(i.style, {
7
+ position: "absolute",
8
+ top: 0,
9
+ left: 0,
10
+ width: "100%",
11
+ height: "100%",
12
+ pointerEvents: "none",
13
+ zIndex: 0,
14
+ background: e,
15
+ opacity: "0",
16
+ transition: `opacity ${t}ms ease-in-out`
17
+ }), n.appendChild(i), i;
18
+ }
19
+ function m(n, e, t) {
20
+ const i = document.createElement("span");
21
+ i.textContent = n.textContent, Object.assign(i.style, {
22
+ position: "absolute",
23
+ top: 0,
24
+ left: 0,
25
+ width: "100%",
26
+ height: "100%",
27
+ display: "inline-block",
28
+ background: e,
29
+ WebkitBackgroundClip: "text",
30
+ backgroundClip: "text",
31
+ WebkitTextFillColor: "transparent",
32
+ color: "transparent",
33
+ pointerEvents: "none",
34
+ opacity: "0",
35
+ transition: `opacity ${t}ms ease-in-out`,
36
+ zIndex: 20
37
+ });
38
+ const s = n.parentNode;
39
+ getComputedStyle(s).position === "static" && (s.style.position = "relative"), s.appendChild(i), requestAnimationFrame(() => {
40
+ i.style.opacity = "1";
41
+ });
42
+ }
43
+ function b(n, e) {
44
+ if (n.__dgTextFx && n.__dgTextFx.duration !== e) {
45
+ const { a, b: o } = n.__dgTextFx;
46
+ return a.style.transition = o.style.transition = `opacity ${e}ms ease-in-out`, n.__dgTextFx.duration = e, n.__dgTextFx;
47
+ }
48
+ if (n.__dgTextFx) return n.__dgTextFx;
49
+ const t = n.parentNode;
50
+ getComputedStyle(t).position === "static" && (t.style.position = "relative");
51
+ const i = (a) => {
52
+ const o = document.createElement("span");
53
+ return o.textContent = n.textContent, Object.assign(o.style, {
54
+ position: "absolute",
55
+ top: 0,
56
+ left: 0,
57
+ width: "100%",
58
+ height: "100%",
59
+ display: "inline-block",
60
+ WebkitBackgroundClip: "text",
61
+ backgroundClip: "text",
62
+ WebkitTextFillColor: "transparent",
63
+ color: "transparent",
64
+ pointerEvents: "none",
65
+ opacity: "0",
66
+ willChange: "opacity",
67
+ zIndex: a,
68
+ transition: `opacity ${e}ms ease-in-out`
69
+ }), t.appendChild(o), o;
70
+ }, s = i(20), r = i(21);
71
+ return n.__dgTextFx = { a: s, b: r, visible: null, duration: e }, n.__dgTextFx;
72
+ }
73
+ function k() {
74
+ const n = /* @__PURE__ */ new Date();
75
+ return `${String(n.getHours()).padStart(2, "0")}:${String(
76
+ n.getMinutes()
77
+ ).padStart(2, "0")}`;
78
+ }
79
+ function C(n, e) {
80
+ if (!n.length) return null;
81
+ let t = n[0];
82
+ for (let i = 0; i < n.length; i++)
83
+ e >= n[i].time && (t = n[i]);
84
+ return e < n[0].time && (t = n[n.length - 1]), t;
85
+ }
86
+ const p = {
87
+ white: "#ffffff",
88
+ black: "#000000",
89
+ gold: "#ffe864ff",
90
+ silver: "#d4d4d4ff"
91
+ };
92
+ class g {
93
+ constructor(e, t = {}) {
94
+ if (this.container = typeof e == "string" ? document.querySelector(e) : e, !this.container)
95
+ throw new Error("DynamicGradient: container not found.");
96
+ this.type = t.type || "linear", this.direction = t.direction || "to right", this.colors = t.colors || ["#1e3c72", "#2a5298"], this.transitionDuration = t.transitionDuration ?? 1500, this.textClip = t.textClip || !1, this.scheduleData = t.schedule || [], this.currentInterval = null, this.lastAppliedKey = null, this.container.style.position = this.container.style.position || "relative", this.applyGradient(this.colors, this.type, this.direction, !1), this.scheduleData.length > 0 && this.schedule(this.scheduleData);
97
+ }
98
+ /** Apply gradient with optional transition */
99
+ applyGradient(e = this.colors, t = this.type, i = this.direction, s = !0) {
100
+ const r = c(e, t, i), a = this.container.style.background;
101
+ if (r !== a) {
102
+ if (this.textClip) {
103
+ const o = m(
104
+ this.container,
105
+ r,
106
+ this.duration
107
+ );
108
+ this.container.style.background = o, this.container.style.fontWeight = "inherit";
109
+ } else
110
+ s ? (this.transitionOverlay && this.transitionOverlay.remove(), this.transitionOverlay = f(
111
+ this.container,
112
+ r,
113
+ this.transitionDuration
114
+ ), requestAnimationFrame(() => {
115
+ this.transitionOverlay.style.opacity = "1";
116
+ }), setTimeout(() => {
117
+ this.container.style.background = r, this.transitionOverlay.remove(), this.transitionOverlay = null;
118
+ }, this.transitionDuration)) : this.container.style.background = r;
119
+ this.colors = e, this.type = t, this.direction = i;
120
+ }
121
+ }
122
+ /** Allow toggling text-clip dynamically */
123
+ setTextClip(e = !0) {
124
+ this.textClip = e, this.applyGradient(this.colors, this.type, this.direction, !1);
125
+ }
126
+ /** Trigger a temporary animated effect */
127
+ triggerEffect({
128
+ applyColors: e = null,
129
+ duration: t = this.transitionDuration,
130
+ loop: i = !0,
131
+ hue: s = "white"
132
+ } = {}) {
133
+ let r;
134
+ p[s] ? r = p[s] : /^#([0-9A-F]{3}){1,2}$/i.test(s) ? r = s : r = "#ffffff";
135
+ const a = e ? c(e, this.type, this.direction) : c([...this.colors, r], this.type, this.direction);
136
+ if (this.textClip) {
137
+ const y = b(this.container, t), d = () => {
138
+ const { a: h, b: v, visible: x } = y, l = x === "a" ? v : h, T = e ? c(e, this.type, this.direction) : c(
139
+ [...this.colors, p[s] || r],
140
+ this.type,
141
+ this.direction
142
+ );
143
+ l.style.background = T, l.style.backgroundClip = "text", l.style.transition = `opacity ${t}ms ease-in-out`, l.style.opacity = "0", requestAnimationFrame(() => {
144
+ requestAnimationFrame(() => {
145
+ l.style.opacity = "1";
146
+ });
147
+ }), setTimeout(() => {
148
+ l.style.opacity = "0";
149
+ }, t), y.visible = l === h ? "a" : "b", i ? (this.effectLoopTimeout && clearTimeout(this.effectLoopTimeout), this.effectLoopTimeout = setTimeout(d, t * 2)) : setTimeout(() => {
150
+ this.applyGradient(
151
+ e || this.colors,
152
+ this.type,
153
+ this.direction,
154
+ !1
155
+ ), h.style.opacity = "0", v.style.opacity = "0";
156
+ }, t * 2);
157
+ };
158
+ d();
159
+ return;
160
+ }
161
+ this.effectOverlay || (this.effectOverlay = f(
162
+ this.container,
163
+ a,
164
+ t
165
+ ));
166
+ const o = this.effectOverlay, u = () => {
167
+ o.style.background = a, o.style.opacity = "1", setTimeout(() => {
168
+ o.style.opacity = "0";
169
+ }, t);
170
+ };
171
+ this.effectRunning || (this.effectRunning = !0, u(), i ? (this.effectLoopInterval && clearInterval(this.effectLoopInterval), this.effectLoopInterval = setInterval(u, t * 2)) : setTimeout(() => {
172
+ o.remove(), this.effectOverlay = null;
173
+ }, t * 2));
174
+ }
175
+ persistEffect(e = this.colors, t = this.transitionDuration) {
176
+ const i = c(
177
+ e,
178
+ this.type,
179
+ this.direction
180
+ );
181
+ if (this.textClip) {
182
+ const s = m(
183
+ this.container,
184
+ i,
185
+ t
186
+ );
187
+ requestAnimationFrame(() => {
188
+ s.style.opacity = "1";
189
+ }), setTimeout(() => {
190
+ this.applyGradient(e, this.type, this.direction, !1);
191
+ }, t);
192
+ } else {
193
+ const s = f(this.container, i, t);
194
+ requestAnimationFrame(() => {
195
+ s.style.opacity = "1";
196
+ }), setTimeout(() => {
197
+ this.applyGradient(e, this.type, this.direction, !1), s.remove();
198
+ }, t);
199
+ }
200
+ }
201
+ stopEffects() {
202
+ this.effectLoopInterval && (clearInterval(this.effectLoopInterval), this.effectLoopInterval = null), this.effectLoopTimeout && (clearTimeout(this.effectLoopTimeout), this.effectLoopTimeout = null), this.effectRunning = !1;
203
+ }
204
+ // ✅ added: cleanup method to prevent leaks
205
+ destroy() {
206
+ this.stopEffects(), this.currentInterval && (clearInterval(this.currentInterval), this.currentInterval = null), this.transitionOverlay && (this.transitionOverlay.remove(), this.transitionOverlay = null), this.effectOverlay && (this.effectOverlay.remove(), this.effectOverlay = null);
207
+ }
208
+ setGradient({ colors: e, type: t, direction: i }) {
209
+ const s = e || this.colors, r = t || this.type, a = i || this.direction;
210
+ s.join(",") === this.colors.join(",") && r === this.type && a === this.direction || this.applyGradient(s, r, a, !0);
211
+ }
212
+ schedule(e = []) {
213
+ this.scheduleData = e.map((t) => ({
214
+ ...t,
215
+ time: t.time.padStart(5, "0")
216
+ })).sort((t, i) => t.time.localeCompare(i.time)), this.currentInterval && clearInterval(this.currentInterval), this.checkSchedule(), this.currentInterval = setInterval(() => this.checkSchedule(), 60 * 1e3);
217
+ }
218
+ checkSchedule() {
219
+ const e = k(), t = C(this.scheduleData, e);
220
+ if (t) {
221
+ const i = `${t.time}-${t.colors.join(",")}`;
222
+ i !== this.lastAppliedKey && (this.setGradient(t), this.lastAppliedKey = i);
223
+ }
224
+ }
225
+ static init(e, t) {
226
+ return new g(e, t);
227
+ }
228
+ }
229
+ export {
230
+ g as DynamicGradient
231
+ };
@@ -0,0 +1 @@
1
+ (function(h,l){typeof exports=="object"&&typeof module<"u"?l(exports):typeof define=="function"&&define.amd?define(["exports"],l):(h=typeof globalThis<"u"?globalThis:h||self,l(h.RealTimeGradient={}))})(this,function(h){"use strict";function l(n,e="linear",t="to right"){return e==="linear"?`linear-gradient(${t}, ${n.join(",")})`:`radial-gradient(circle, ${n.join(",")})`}function f(n,e,t){const i=document.createElement("div");return Object.assign(i.style,{position:"absolute",top:0,left:0,width:"100%",height:"100%",pointerEvents:"none",zIndex:0,background:e,opacity:"0",transition:`opacity ${t}ms ease-in-out`}),n.appendChild(i),i}function d(n,e,t){const i=document.createElement("span");i.textContent=n.textContent,Object.assign(i.style,{position:"absolute",top:0,left:0,width:"100%",height:"100%",display:"inline-block",background:e,WebkitBackgroundClip:"text",backgroundClip:"text",WebkitTextFillColor:"transparent",color:"transparent",pointerEvents:"none",opacity:"0",transition:`opacity ${t}ms ease-in-out`,zIndex:20});const s=n.parentNode;getComputedStyle(s).position==="static"&&(s.style.position="relative"),s.appendChild(i),requestAnimationFrame(()=>{i.style.opacity="1"})}function T(n,e){if(n.__dgTextFx&&n.__dgTextFx.duration!==e){const{a,b:o}=n.__dgTextFx;return a.style.transition=o.style.transition=`opacity ${e}ms ease-in-out`,n.__dgTextFx.duration=e,n.__dgTextFx}if(n.__dgTextFx)return n.__dgTextFx;const t=n.parentNode;getComputedStyle(t).position==="static"&&(t.style.position="relative");const i=a=>{const o=document.createElement("span");return o.textContent=n.textContent,Object.assign(o.style,{position:"absolute",top:0,left:0,width:"100%",height:"100%",display:"inline-block",WebkitBackgroundClip:"text",backgroundClip:"text",WebkitTextFillColor:"transparent",color:"transparent",pointerEvents:"none",opacity:"0",willChange:"opacity",zIndex:a,transition:`opacity ${e}ms ease-in-out`}),t.appendChild(o),o},s=i(20),r=i(21);return n.__dgTextFx={a:s,b:r,visible:null,duration:e},n.__dgTextFx}function b(){const n=new Date;return`${String(n.getHours()).padStart(2,"0")}:${String(n.getMinutes()).padStart(2,"0")}`}function k(n,e){if(!n.length)return null;let t=n[0];for(let i=0;i<n.length;i++)e>=n[i].time&&(t=n[i]);return e<n[0].time&&(t=n[n.length-1]),t}const u={white:"#ffffff",black:"#000000",gold:"#ffe864ff",silver:"#d4d4d4ff"};class p{constructor(e,t={}){if(this.container=typeof e=="string"?document.querySelector(e):e,!this.container)throw new Error("DynamicGradient: container not found.");this.type=t.type||"linear",this.direction=t.direction||"to right",this.colors=t.colors||["#1e3c72","#2a5298"],this.transitionDuration=t.transitionDuration??1500,this.textClip=t.textClip||!1,this.scheduleData=t.schedule||[],this.currentInterval=null,this.lastAppliedKey=null,this.container.style.position=this.container.style.position||"relative",this.applyGradient(this.colors,this.type,this.direction,!1),this.scheduleData.length>0&&this.schedule(this.scheduleData)}applyGradient(e=this.colors,t=this.type,i=this.direction,s=!0){const r=l(e,t,i),a=this.container.style.background;if(r!==a){if(this.textClip){const o=d(this.container,r,this.duration);this.container.style.background=o,this.container.style.fontWeight="inherit"}else s?(this.transitionOverlay&&this.transitionOverlay.remove(),this.transitionOverlay=f(this.container,r,this.transitionDuration),requestAnimationFrame(()=>{this.transitionOverlay.style.opacity="1"}),setTimeout(()=>{this.container.style.background=r,this.transitionOverlay.remove(),this.transitionOverlay=null},this.transitionDuration)):this.container.style.background=r;this.colors=e,this.type=t,this.direction=i}}setTextClip(e=!0){this.textClip=e,this.applyGradient(this.colors,this.type,this.direction,!1)}triggerEffect({applyColors:e=null,duration:t=this.transitionDuration,loop:i=!0,hue:s="white"}={}){let r;u[s]?r=u[s]:/^#([0-9A-F]{3}){1,2}$/i.test(s)?r=s:r="#ffffff";const a=e?l(e,this.type,this.direction):l([...this.colors,r],this.type,this.direction);if(this.textClip){const v=T(this.container,t),g=()=>{const{a:y,b:x,visible:C}=v,c=C==="a"?x:y,O=e?l(e,this.type,this.direction):l([...this.colors,u[s]||r],this.type,this.direction);c.style.background=O,c.style.backgroundClip="text",c.style.transition=`opacity ${t}ms ease-in-out`,c.style.opacity="0",requestAnimationFrame(()=>{requestAnimationFrame(()=>{c.style.opacity="1"})}),setTimeout(()=>{c.style.opacity="0"},t),v.visible=c===y?"a":"b",i?(this.effectLoopTimeout&&clearTimeout(this.effectLoopTimeout),this.effectLoopTimeout=setTimeout(g,t*2)):setTimeout(()=>{this.applyGradient(e||this.colors,this.type,this.direction,!1),y.style.opacity="0",x.style.opacity="0"},t*2)};g();return}this.effectOverlay||(this.effectOverlay=f(this.container,a,t));const o=this.effectOverlay,m=()=>{o.style.background=a,o.style.opacity="1",setTimeout(()=>{o.style.opacity="0"},t)};this.effectRunning||(this.effectRunning=!0,m(),i?(this.effectLoopInterval&&clearInterval(this.effectLoopInterval),this.effectLoopInterval=setInterval(m,t*2)):setTimeout(()=>{o.remove(),this.effectOverlay=null},t*2))}persistEffect(e=this.colors,t=this.transitionDuration){const i=l(e,this.type,this.direction);if(this.textClip){const s=d(this.container,i,t);requestAnimationFrame(()=>{s.style.opacity="1"}),setTimeout(()=>{this.applyGradient(e,this.type,this.direction,!1)},t)}else{const s=f(this.container,i,t);requestAnimationFrame(()=>{s.style.opacity="1"}),setTimeout(()=>{this.applyGradient(e,this.type,this.direction,!1),s.remove()},t)}}stopEffects(){this.effectLoopInterval&&(clearInterval(this.effectLoopInterval),this.effectLoopInterval=null),this.effectLoopTimeout&&(clearTimeout(this.effectLoopTimeout),this.effectLoopTimeout=null),this.effectRunning=!1}destroy(){this.stopEffects(),this.currentInterval&&(clearInterval(this.currentInterval),this.currentInterval=null),this.transitionOverlay&&(this.transitionOverlay.remove(),this.transitionOverlay=null),this.effectOverlay&&(this.effectOverlay.remove(),this.effectOverlay=null)}setGradient({colors:e,type:t,direction:i}){const s=e||this.colors,r=t||this.type,a=i||this.direction;s.join(",")===this.colors.join(",")&&r===this.type&&a===this.direction||this.applyGradient(s,r,a,!0)}schedule(e=[]){this.scheduleData=e.map(t=>({...t,time:t.time.padStart(5,"0")})).sort((t,i)=>t.time.localeCompare(i.time)),this.currentInterval&&clearInterval(this.currentInterval),this.checkSchedule(),this.currentInterval=setInterval(()=>this.checkSchedule(),60*1e3)}checkSchedule(){const e=b(),t=k(this.scheduleData,e);if(t){const i=`${t.time}-${t.colors.join(",")}`;i!==this.lastAppliedKey&&(this.setGradient(t),this.lastAppliedKey=i)}}static init(e,t){return new p(e,t)}}h.DynamicGradient=p,Object.defineProperty(h,Symbol.toStringTag,{value:"Module"})});
package/package.json ADDED
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "real-time-gradient",
3
+ "version": "1.0.0",
4
+ "description": "A Dynamic Gradient background library.",
5
+ "main": "dist/index.umd.js",
6
+ "module": "dist/index.es.js",
7
+ "types": "dist/index.d.ts",
8
+ "scripts": {
9
+ "build": "vite build"
10
+ },
11
+ "files": [
12
+ "dist"
13
+ ],
14
+ "keywords": [
15
+ "background",
16
+ "gradient",
17
+ "dynamic",
18
+ "canvas"
19
+ ],
20
+ "author": "wakenedo",
21
+ "license": "MIT",
22
+ "devDependencies": {
23
+ "vite": "^5.4.19",
24
+ "vite-plugin-dts": "^4.5.4"
25
+ }
26
+ }