diff --git a/.gitmodules b/.gitmodules index df819cb..b4edc8e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "lol/liquid-shape-distortions"] path = lol/liquid-shape-distortions url = https://github.com/collidingScopes/liquid-shape-distortions +[submodule "lol/components/marquee"] + path = lol/components/marquee + url = https://codeberg.org/epickiwi/marquee-webcomponent.git diff --git a/lol/components/marquee b/lol/components/marquee new file mode 160000 index 0000000..e7e9071 --- /dev/null +++ b/lol/components/marquee @@ -0,0 +1 @@ +Subproject commit e7e907129fcc5ccd9ab62a120144497314f36f51 diff --git a/lol/components/marquee.js b/lol/components/marquee.js deleted file mode 100644 index a0d1eb6..0000000 --- a/lol/components/marquee.js +++ /dev/null @@ -1,205 +0,0 @@ -const TEMPLATE = document.createElement("template"); -TEMPLATE.innerHTML = ``; - -const CHECK_OPTIONS_INTERVAL = 100; - -class MarkeeComponent extends HTMLElement { - #options = { - speed: 0, - scrollPauseDelay: 1000, - playing: true, - scrollPlaying: true, - }; - - #lastFrame = 0; - - #animationFrameRequest = -1; - - #checkOptionInterval = -1; - - #scrollPlayingTimeout = -1; - - /** @type {{element: Element, rect: DOMRect, margin: number}?} */ - #nextCollectedElement = null; - - constructor() { - super(); - - this.requestTick = this.requestTick.bind(this); - this.updateOptions = this.updateOptions.bind(this); - - this.attachShadow({ mode: "open" }); - this.shadowRoot.appendChild(TEMPLATE.content.cloneNode(true)); - } - - tick() { - let now = Date.now(); - let delta = (now - this.#lastFrame) / 1000; - this.#lastFrame = now; - - if (!this.#options.playing || !this.#options.scrollPlaying || this.scrollWidth - 800 <= this.clientWidth) return; - - this.scrollLeft += Math.max(this.#options.speed * delta, 1); - - this.checkElementRecycling(); - } - - requestTick() { - this.tick(); - if (this.#options.playing) { - this.#animationFrameRequest = requestAnimationFrame(this.requestTick, 30); - } - } - - updateOptions() { - let style = window.getComputedStyle(this); - - let speed = parseFloat(style.getPropertyValue("--markee-speed")); - if (!Number.isNaN(speed)) { - this.#options.speed = speed; - } - - let wasPlaying = this.#options.playing; - - let playState = style.getPropertyValue("--markee-play-state"); - if (playState) { - this.#options.playing = playState != "paused"; - } else { - this.#options.playing = true; - } - - let scrollPauseDelay = style.getPropertyValue( - "--markee-interaction-pause-delay" - ); - if (scrollPauseDelay) { - let value = parseFloat(scrollPauseDelay); - if (scrollPauseDelay.endsWith("ms")) { - this.#options.scrollPauseDelay = value; - } else if (scrollPauseDelay.endsWith("s")) { - this.#options.scrollPauseDelay = value * 1000; - } else { - this.#options.scrollPauseDelay = 1000; - } - } - - if (wasPlaying != this.#options.playing) { - this.#lastFrame = Date.now(); - cancelAnimationFrame(this.#animationFrameRequest); - this.requestTick(); - } - } - - checkElementRecycling() { - if ( - this.children.length > 0 && - (!this.#nextCollectedElement || - this.#nextCollectedElement.element != this.children[0]) - ) { - let element = this.children[0]; - { - let i = 0; - while(element.style.display == "none" && i < this.children.length){ - i += 1; - element = this.children[i] - } - } - - let style = window.getComputedStyle(element); - - this.#nextCollectedElement = { - element, - rect: element.getBoundingClientRect(), - margin: parseFloat(style.marginLeft) + parseFloat(style.marginRight), - }; - } - - if (!this.#nextCollectedElement) return; - - let lastElement = this.children[this.children.length-1]; - { - let i = lastElement.children.length-1; - while(lastElement && lastElement.style.display == "none" && i >= 0){ - i -= 1; - lastElement = this.children[i] - } - } - - - if (lastElement) { - let rect = lastElement.getBoundingClientRect(); - let thisRect = this.getBoundingClientRect(); - let style = window.getComputedStyle(lastElement); - let margin = parseFloat(style.marginLeft) + parseFloat(style.marginRight); - - if (thisRect.width == 0) { - return; - } - - if (rect.right + margin < thisRect.left + this.clientWidth) { - return; - } - } - - if ( - this.scrollLeft >= - this.scrollWidth - - this.clientWidth - - this.#nextCollectedElement.rect.width - - this.#nextCollectedElement.margin - ) { - this.scrollLeft -= - this.#nextCollectedElement.rect.width + - this.#nextCollectedElement.margin; - this.appendChild(this.#nextCollectedElement.element); - this.#nextCollectedElement = null; - } - } - - handlePointer(e) { - this.#options.scrollPlaying = false; - clearTimeout(this.#scrollPlayingTimeout); - this.#scrollPlayingTimeout = setTimeout(() => { - this.#options.scrollPlaying = true; - }, this.#options.scrollPauseDelay); - } - - connectedCallback() { - this.updateOptions(); - this.#lastFrame = Date.now(); - this.requestTick(); - this.#checkOptionInterval = setInterval( - this.updateOptions, - CHECK_OPTIONS_INTERVAL - ); - } - - disconnectedCallback() { - clearInterval(this.#checkOptionInterval); - } -} - -customElements.define("gavle-marquee", MarkeeComponent); diff --git a/lol/effects.html b/lol/effects.html new file mode 100644 index 0000000..7bae700 --- /dev/null +++ b/lol/effects.html @@ -0,0 +1,538 @@ + + + + + + + Liquid Shape Distortions + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+

Liquid Shape Distortions 🌀

+

+ Create psychedelic art using liquid motion, distortion, shadows and light. +

+

I recommend hitting the 🎲 button until you get something you like.

+

You can also use the full controls at the top right to fine-tune all parameters.

+ +
+
    +
  • 🎲: randomize all inputs [r]
  • +
  • ⏯️: pause/play the animation [space]
  • +
  • 📷: save a screenshot image [s]
  • +
  • 🎥: start/stop video export [v]
  • +
  • 🔊: start/stop music [m]
  • +
+
+ +
+
+ +
+ + +
+ +
+ + + + + + + + + + + + + +
+ + + + + + + + + +
+ +
+

Made by: @stereo.drift

+

Song: Fahrenheit Fair Enough - Telefon Tel Aviv

+

FPS:

+
+ + + +
+
+ +

Liquid Shape Distortions 🌀

+

Psychedelic animation generator; (p)art of your next trip

+ + + +

Create psychedelic art using liquid motion, distortion, shadows and light. This tool is free, and works in real-time in the browser.

+

This project was inspired by drum & bass / acid techno music, and 90s rave posters.

+

Use this to create art for a music video, concert posters, stylized animations in creative projects, or simply to enjoy alongside some fine music.

+ +

Controls / hotkeys:

+ + +

Use the full control menu (top-right) to set a custom canvas size, adjust animation speed, control pattern and colours, etc...

+

You can export your creation as an image or video afterwards.

+

The animation is created with WebGL shaders, starting from a random seed position and mixing in elements of random noise (fractal brownian motion, 3D simplex noise), so each time you re-run it you're creating a unique piece of art.

+

This tool is completely free, open source (MIT license), without any paywalls or premium options. You are welcome to use it for personal or commercial purposes.

+

If you found this tool useful, feel free to buy me a coffee. My name is Alan, and I enjoy building open source software for art, animation, games, and more. This would be much appreciated during late-night coding sessions!

+ + Buy Me A Coffee + +

The code used to create the animation is resource-intensive, so it may run with some lag if your computer doesn't have enough computing power, too many tabs open, low battery, etc.

+

If the video export feature does not work for you, please try a free screen-recording tool such as OBS Studio.

+ +

This project is coded using webgl shaders, vanilla Javascript, HTML5 canvas, and CSS (see github repo). Video creation and encoding is done using mp4 muxer.

+

The song used is Fahrenheit Fair Enough by Telefon Tel Aviv.

+

If you enjoyed this, you may be interested in my other free / open source projects:

+ +

Feel free to reach out to discuss, ask questions, or just to say hi! You can find me @stereo.drift on instagram, or through the other places below :)

+
+
+ +
+ + + + + + + + +
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/lol/index.html b/lol/index.html index d5410ab..4195253 100644 --- a/lol/index.html +++ b/lol/index.html @@ -76,9 +76,14 @@ --markee-interaction-pause-delay: 1s; width: 100vw; + display: flex; + flex-direction: row; + justify-content: start; + align-items: flex-start; & > gavle-next-bus { max-width: 75vw; + flex-shrink: 0; } & > * { @@ -260,9 +265,9 @@ - + - +