1import { Controller } from "@hotwired/stimulus" 2import { LottieInitializer } from 'utils/lottie_initializer' 3 4export default class extends Controller { 5 static get targets() { 6 return [ 'lottie', 'svgpath'] 7 } 8 9 colors = { 10 plum: '#BFA6EA', 11 mint: '#9BE5DA', 12 peach: '#FFB590', 13 mustard: '#F5F596', 14 blueberry: '#9BC5EA', 15 sakura: '#FFACD6', 16 } 17 18 colorsLight = { 19 plum: '#D5C8FF', 20 mint: '#C8FFEC', 21 peach: '#FFC9A6', 22 mustard: '#FAFFA4', 23 blueberry: '#C6E6FB', 24 sakura: '#FFDFEA', 25 } 26 27 async connect() { 28 // Wait for the Lottie libraries to be loaded if they are not loaded already 29 await LottieInitializer.ensureInitialized() 30 31 if (this.hasSvgpathTarget) { 32 setTimeout(() => this.svgpathTargets.forEach((element) => { 33 const classes = element.classList 34 this.svgFileToString(element, classes); 35 }), 500) 36 } 37 38 if (this.hasLottieTarget) { 39 this.colorizationLottie() 40 } 41 } 42 43 svgFileToString(element, classes) { 44 fetch(element.src) 45 .then(response => response.text()) 46 .then(text => { 47 let bgColor = this.findBgColor(element) 48 49 // Prevent asset with original colors from displaying before JS loads 50 if (element.parentElement?.classList?.contains('opacity-0')) element.parentElement.classList.replace('opacity-0', 'opacity-100'); 51 52 if (bgColor && this.colors[bgColor]) { 53 const colorized = text.replaceAll('#EFE9FE', this.colors[bgColor]) 54 .replaceAll('#D5C8FB', this.colorsLight[bgColor]) 55 .replace('<svg', `<svg class='${classes}'`); 56 element.parentNode ? element.parentNode.innerHTML = colorized : null 57 } 58 59 }); 60 } 61 62 colorizationLottie() { 63 const player = this.lottieTarget; 64 65 const bgColor = this.findBgColor(player) 66 67 if (bgColor && this.colors[bgColor]) { 68 player.addEventListener('frame', (e) => { 69 player.shadowRoot.querySelectorAll('[fill="rgb(239,233,254)"]').forEach((e) => {e.setAttribute('fill', this.colorsLight[bgColor])}); 70 if (!player.shadowRoot.querySelectorAll('[fill="rgb(213,200,251)"]').forEach((e) => {e.setAttribute('fill', this.colors[bgColor])})) { 71 player.shadowRoot.querySelectorAll('[stroke="rgb(213,200,251)"]').forEach((e) => {e.setAttribute('stroke', this.colors[bgColor])}) 72 } 73 }); 74 } 75 this.fadeInPlayer(player) 76 } 77 78 fadeInPlayer(player) { 79 player.addEventListener('frame', (e) => { 80 setTimeout(() => { 81 player.classList.remove('opacity-0'); 82 player.classList.add('transition-all', 'duration-500', 'opacity-100'); 83 }, 300) 84 }); 85 } 86 87 findBgColor(element) { 88 // Search for the parent section 89 const sectionTarget = element.closest('.js-convertor-colorization') 90 91 let color 92 if (sectionTarget) { 93 // Search the bg-color class in the section 94 for (let i = 0; i < sectionTarget.classList.length; i++) { 95 let className = sectionTarget.classList[i]; 96 // Check if the className starts with "bg-" 97 if (className.startsWith("bg-")) { 98 const parts = className.split("-"); 99 // Get the part after bg- and before xw-50 100 color = parts[1]; 101 break; 102 } 103 } 104 } 105 106 return color 107 } 108};
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.