PageSourceSearch

https://subart.si/wp-content/plugins/breakdance/subplugins/breakda…/animated-heading.js?bd_ver=2.8.1

js subart.si collected 2026-10-08 02:14:35 UTC 7,604 bytes, 275 lines download raw bytes

1(function () {
2  const { mergeObjects } = BreakdanceFrontend.utils;
3
4  class BreakdanceAnimatedHeading {
5    defaultOptions = {
6      content: {
7        changing_text: [
8          {
9            text: "awesome",
10          },
11          {
12            text: "great",
13          },
14          {
15            text: "cool",
16          },
17        ],
18      },
19      design: {
20        effect: {
21          type: "rotating",
22          typing: {
23            type_speed: { number: 100, unit: 'ms' },
24            start_delay: { number: 0, unit: 'ms' },
25            back_speed: { number: 100, unit: 'ms' },
26            back_delay: { number: 100, unit: 'ms' },
27            shuffle: false,
28            disable_loop: false,
29            hide_cursor: false,
30            cursor: "|",
31          },
32          rotating: {
33            duration: { number: 700, unit: 'ms' },
34            delay: { number: 200, unit: 'ms' },
35            easing_in: "easeOutSine",
36            easing_out: "easeInExpo",
37            transform_origin: {
38              x: 50,
39              y: 50,
40            },
41            opacity_in: [0, 1],
42            opacity_out: 0,
43            effect: "flipX",
44          },
45        },
46      },
47    };
48
49    constructor(selector, options) {
50      this.selector = selector;
51      this.element = document.querySelector(
52        `${this.selector} .bde-animated-heading__text`
53      );
54      this.options = mergeObjects(this.defaultOptions, options);
55      this.init();
56    }
57
58    getDuration(value) {
59      if (typeof value === "number") return;
60      if (!value) return value;
61      if (value.unit === "ms") return value.number;
62      return value.number * 1000; // Convert S to MS
63    }
64
65    // Init anime.js
66    initAnime() {
67      const { design } = this.options;
68      this.words = this.createWords();
69
70      this.animeTimeline = anime.timeline({
71        loop: true,
72      });
73
74      this.animateWords(design.effect.rotating.effect, this.words);
75    }
76
77    createWords() {
78      let wordsArray = [];
79      this.wordsWrapper = document.querySelector(
80        `${this.selector} .bde-animated-heading__wrapper`
81      );
82
83      this.options.content.changing_text.forEach((item) => {
84        if (item.text && item.text.length > 0) {
85          const span = document.createElement("span");
86          span.setAttribute("class", "bde-animated-heading__word");
87          span.innerText = item.text.trim();
88          this.wordsWrapper.appendChild(span);
89          wordsArray.push(span);
90        }
91      });
92
93      return wordsArray;
94    }
95
96    // Destroy anime.js
97    destroyAnime() {
98      if (!this.animeTimeline) return;
99      // Clean up the timeline
100      this.animeTimeline.remove(this.words);
101      this.animeTimeline = null;
102      this.wordsWrapper = null;
103      this.words.forEach((word) => word.remove());
104    }
105
106    _anime(element, effectIn, effectOut) {
107      const effect = this.options.design.effect.rotating;
108
109      this.animeTimeline
110        .add({
111          ...effectIn,
112          targets: element,
113          opacity: effect.opacity_in,
114          duration: this.getDuration(effect.duration),
115          easing: effect.easing_in,
116          changeBegin: () => {
117            const newWidth = element.clientWidth;
118            this.wordsWrapper.style.width = newWidth + "px";
119          },
120        })
121        .add({
122          ...effectOut,
123          targets: element,
124          opacity: effect.opacity_out,
125          duration: this.getDuration(effect.duration),
126          easing: effect.easing_out,
127          delay: this.getDuration(effect.delay),
128        });
129    }
130
131    animateWords(effectName, words) {
132      switch (effectName) {
133        case "slideDown":
134          words.forEach((element) => {
135            this._anime(
136              element,
137              { translateY: ["-150%", 0] },
138              { translateY: "150%" }
139            );
140          });
141          break;
142        case "slideRight":
143          words.forEach((element) => {
144            this._anime(
145              element,
146              { translateX: ["-100%", 0] },
147              { translateX: "100%" }
148            );
149          });
150          break;
151        case "slideUp":
152          words.forEach((element) => {
153            this._anime(
154              element,
155              { translateY: ["150%", 0] },
156              { translateY: "-150%" }
157            );
158          });
159          break;
160        case "slideLeft":
161          words.forEach((element) => {
162            this._anime(
163              element,
164              { translateX: ["100%", 0] },
165              { translateX: "-100%" }
166            );
167          });
168          break;
169        case "rotate":
170          words.forEach((element) => {
171            this._anime(element, { rotate: [45, 0] }, { rotate: [0, -45] });
172          });
173          break;
174        case "flipX":
175          words.forEach((element) => {
176            this._anime(element, { rotateX: [-90, 0] }, { rotateX: [0, -90] });
177          });
178          break;
179        case "flipY":
180          words.forEach((element) => {
181            this._anime(element, { rotateY: [-90, 0] }, { rotateY: [0, -90] });
182          });
183          break;
184        case "zoomIn":
185          words.forEach((element) => {
186            this._anime(element, { scale: [0, 1] }, { scale: [1, 2] });
187          });
188          break;
189        case "zoomOut":
190          words.forEach((element) => {
191            this._anime(element, { scale: [2, 1] }, { scale: [1, 0] });
192          });
193          break;
194        default:
195          console.warn(`Animated Heading: ${effectName} effect not found.`);
196      }
197    }
198
199    // Init Typed.js
200    initTyped() {
201      const settings = this.options.design.effect.typing;
202      const text = this.options.content.changing_text;
203      const strings = text.map((word) => word.text);
204      this.typedElement = document.querySelector(
205        `${this.selector} .js-eeah-typed`
206      );
207
208      this.typedElement.innerHTML = "";
209
210      this.typed = new Typed(this.typedElement, {
211        strings: strings,
212        smartBackspace: true,
213        typeSpeed: this.getDuration(settings.type_speed),
214        startDelay: this.getDuration(settings.start_delay),
215        backSpeed: this.getDuration(settings.back_speed),
216        backDelay: this.getDuration(settings.back_delay),
217        shuffle: !!settings.shuffle,
218        fadeOut: false,
219        showCursor: !settings.hide_cursor,
220        loop: !settings.disable_loop,
221        cursorChar: settings.cursor,
222      });
223
224      this.typed.start();
225    }
226
227    // Destroy typed.js
228    destroyTyped() {
229      if (!this.typed) return;
230      this.typed.destroy();
231      this.typedElement.innerHTML = "";
232      this.typed = null;
233    }
234
235    // Update plugin
236    update(options = {}) {
237      this.options = mergeObjects(this.defaultOptions, options);
238      this.destroy();
239      this.init();
240    }
241
242    // Destory plugin
243    destroy() {
244      const { type } = this.options.design.effect;
245      switch (type) {
246        case "rotating":
247          this.destroyAnime();
248          break;
249        case "typing":
250          this.destroyTyped();
251          break;
252        default:
253          console.warn(
254            `Animated Heading: ${type} animation could not be destroyed.`
255          );
256      }
257    }
258
259    // Init plugin
260    init() {
261      const { type } = this.options.design.effect;
262      switch (type) {
263        case "rotating":
264          this.initAnime();
265          break;
266        case "typing":
267          this.initTyped();
268          break;
269        default:
270          console.warn(`Animated Heading: ${type} animation not initialised.`);
271      }
272    }
273  }
274  window.BreakdanceAnimatedHeading = BreakdanceAnimatedHeading;
275})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.