Fighting the <div> soup with a 5 minute instant Web Component
Danny Engelman

Danny Engelman @dannyengelman

About: Online since 1990 Yes! I started with Gopher. I do modern Web Component Development with technologies supported by **all** WHATWG partners (Apple, Google, Microsoft & Mozilla)

Location:
Amsterdam, the Netherlands
Joined:
Oct 20, 2018

Fighting the <div> soup with a 5 minute instant Web Component

Publish Date: Feb 10 '24
6 0

I was inspired to write this blog by this React based textGenerate effect

It is a huge site, the JavaScript is close to 1 MB:

creating my <text-reveal> Web Component

The banner above was created by DALL-E (Chat-GPT)

create a Dali like wide banner with a stopwatch folded over a Web Component JavaScript code in a soup filled with HTML <div> tags

I then fired up the Web Component Generator I created in the GPT-Store last month, and gave it the prompt:

(Open the link above with Ctrl+Click, OpenAI sometimes blocks access)

Create a Web Component where words fade in one by one for the sentence:
"Oxygen gets you high. In a catastrophic emergency, we're taking giant, panicked breaths. Suddenly you become euphoric, docile. You accept your fate. It's all right here. Emergency water landing, six hundred miles an hour. Blank faces, calm as Hindu cows"

It spit out this code:

<script>
customElements.define('reveal-words', class extends HTMLElement {
  constructor() {
    const createElement = (tag, props = {}) => Object.assign(document.createElement(tag), props);
    super();
    this.attachShadow({ mode: 'open' });
    this.shadowRoot.append(createElement('style', {
      innerHTML: `
        :host { display: block }
        span {
          opacity: 0;
          display: inline-block;
          animation: fade-in 1s ease-out forwards;
        }
        @keyframes fade-in { to { opacity: 1 }
        }`
    }), this.createElement('div'));
  }

  connectedCallback() {
    const createElement = (tag, props = {}) => Object.assign(document.createElement(tag), props);    
    setTimeout(() => {
      this.words = this.innerText.trim().split(/\s+/);
      this.div = this.shadowRoot.querySelector('div';
      this.div.append(...this.words.map((word, index) => createElement('span', {
        innerHTML: word + ' ',
        style: `animation-delay: ${index * 100}ms`
      })));
    });
  }
});
</script>

<reveal-words>Oxygen gets you high. In a catastrophic emergency, we're taking giant, panicked breaths. Suddenly you become euphoric, docile. You accept your fate. It's all right here. Emergency water landing, six hundred miles an hour. Blank faces, calm as Hindu cows</reveal-words>
Enter fullscreen mode Exit fullscreen mode

I can do better,

The <reveal-words> Web Component

So I pasted it in JSFiddle, and refactored it by hand
Moving all code to the connectedCallback

Done in 5 minutes (click the result tab)




Comments 0 total

    Add comment