{"version":3,"sources":["../../../templates/js/src/bubbles.ts"],"sourcesContent":["function distance2d(x: number, y: number, x2: number, y2: number) {\n return Math.sqrt(Math.pow(x2 - x, 2) + Math.pow(y2 - y, 2));\n}\n\nfunction clampedNRandom(min: number, max: number, mean = 0.5, stdev = 0.2) {\n var r = noramlizedRandom((mean = 0.5), (stdev = 0.2));\n if (r < min) return min;\n if (r > max) return max;\n return r;\n}\n\nfunction noramlizedRandom(mean = 0.5, stdev = 0.05) {\n const u = 1 - Math.random();\n const v = Math.random();\n const z = Math.sqrt(-2.0 * Math.log(u)) * Math.cos(2.0 * Math.PI * v);\n return z * stdev + mean;\n}\n\nfunction getRandomColor(): string {\n const hue = Math.floor(Math.random() * 40) + 20; // yellow hue\n const saturation = Math.floor(Math.random() * 30) + 70; // 70-100% for vibrancy\n const lightness = Math.floor(Math.random() * 40) + 50; // 50-90% for brightness\n return `hsl(${hue}, ${saturation}%, ${lightness}%)`;\n}\nfunction randInt(min: number, max: number) {\n return Math.floor(max * Math.random() + min);\n}\n\nclass Bubble {\n element: HTMLElement;\n size: number;\n x: number;\n y: number;\n hasContent: boolean = false;\n\n constructor(size: number, x: number, y: number, color: string) {\n this.size = size;\n this.x = x;\n this.y = y;\n\n this.element = document.createElement(\"div\");\n this.element.classList.add(\n \"absolute\",\n \"rounded-full\",\n \"cursor-pointer\",\n \"select-none\",\n );\n this.element.style.width = `${this.size}px`;\n this.element.style.height = `${this.size}px`;\n this.element.style.backgroundColor = color;\n\n // Add click event listener to the bubble\n this.element.addEventListener(\"click\", () => {\n this.onClick();\n });\n }\n\n mount(container: HTMLElement) {\n container.appendChild(this.element);\n this.element.style.left = `calc(${this.x * 100}% - ${this.size / 2}px)`;\n this.element.style.top = `calc(${this.y * 100}% - ${this.size / 2}px)`;\n }\n\n // Click behavior for each bubble\n onClick(): void {\n if (this.hasContent) {\n alert(`More information coming soon!`);\n }\n }\n}\n\nclass BubbleScene {\n container: HTMLElement;\n bubbles: Array;\n constructor(container: HTMLElement, amount: number) {\n this.container = container;\n this.bubbles = new Array(amount);\n // Create bubbles on the screen\n this.spawnBubbles();\n }\n\n // Spawn random bubbles\n spawnBubbles(): void {\n const rect = this.container.getBoundingClientRect();\n const maxSize = 150;\n const overlap = 0.6;\n const minDist = 0;\n const max = this.bubbles.length * 3;\n var loops = 0;\n for (let i = 0; i < this.bubbles.length; i++) {\n const x = clampedNRandom(0.1, 0.9);\n const y = clampedNRandom(0.1, 0.9);\n const centerDistance = distance2d(0.5, 0.5, x, y);\n const size = maxSize * (1 - centerDistance);\n const color = getRandomColor();\n\n let skip = false;\n if (loops < max) {\n for (let j = 0; j < i; j++) {\n const p = this.bubbles[j];\n const dist = distance2d(\n x * rect.width,\n y * rect.height,\n p.x * rect.width,\n p.y * rect.height,\n );\n if (dist < minDist + (size / 2 + p.size / 2) * overlap) {\n i--;\n skip = true;\n break;\n }\n }\n }\n if (skip) {\n loops++;\n continue;\n }\n\n const bubble = new Bubble(size, x, y, color);\n this.bubbles[i] = bubble;\n bubble.mount(this.container);\n }\n }\n}\n\nfunction BubbleMain(container: HTMLElement, amount: number) {\n const scene = new BubbleScene(container, amount);\n\n console.info(scene.bubbles);\n const texts = [\"Hello!\", \"#VeryAsian\", \"To be, AND not to be\"];\n\n var amt = texts.length;\n\n if (amount * 0.8 < amt) {\n amt = Math.floor(amount * 0.8);\n }\n\n for (var i = 0; i < amt; i++) {\n const j = randInt(0, scene.bubbles.length);\n const bubble = scene.bubbles[j];\n\n if (!bubble || bubble.hasContent) {\n continue;\n }\n\n const textDiv = document.createElement(\"div\");\n textDiv.textContent = texts[i];\n textDiv.className =\n \"absolute text-c-black text-center p-2 w-full top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 select-none\";\n\n bubble.element.appendChild(textDiv);\n bubble.element.style.zIndex = \"1000\";\n bubble.hasContent = true;\n }\n}\ndeclare global {\n interface Window {\n bubbles: {\n BubbleMain: (container: HTMLElement, amount: number) => void;\n };\n }\n}\n\nwindow.bubbles = {\n BubbleMain: BubbleMain,\n};\n"],"mappings":"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","names":["distance2d","x","y","x2","y2","clampedNRandom","min","max","mean","stdev","r","noramlizedRandom","u","v","getRandomColor","hue","saturation","lightness","randInt","Bubble","size","color","container","BubbleScene","amount","rect","maxSize","overlap","minDist","loops","centerDistance","skip","j","p","bubble","BubbleMain","scene","texts","amt","i","textDiv"]}