Last active
July 16, 2020 01:49
-
-
Save tomhodgins/def6ac1e6439c1e2f2a088bbf1b22035 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script type=module> | |
class WordCarousel extends HTMLElement { | |
constructor() { | |
super() | |
this.carousel | |
this.active = false | |
} | |
static get observedAttributes() { | |
return [ | |
'words', | |
'fade-duration', | |
'word-duration' | |
] | |
} | |
// words="one two three" | |
get words() { | |
return this.getAttribute('words')?.split(/\s+/) || [''] | |
} | |
set words(string = '') { | |
return this.setAttribute('words', string) | |
} | |
// fade-duration=500 | |
get fadeDuration() { | |
return this.getAttribute('fade-duration') || 500 | |
} | |
set fadeDuration(number = 500) { | |
return this.setAttribute('fade-duration', number) | |
} | |
// word-duration=3000 | |
get wordDuration() { | |
return this.getAttribute('word-duration') || 3000 | |
} | |
set wordDuration(number = 3000) { | |
return this.setAttribute('word-duration', number) | |
} | |
startAnimation() { | |
const [first] = this.words | |
if (first !== '') { | |
this.textContent = first | |
if (2 <= this.words.length && this.active === false) { | |
this.active = true | |
this.style.transition = `opacity ${this.fadeDuration}ms ease-in-out` | |
this.carousel = window.setInterval( | |
() => { | |
this.style.opacity = 0 | |
window.setTimeout( | |
() => { | |
const index = this.words.indexOf(this.textContent) | |
this.textContent = this.words[index + 1] || first | |
this.style.removeProperty('opacity') | |
}, | |
this.fadeDuration | |
) | |
}, | |
this.wordDuration | |
) | |
} | |
} | |
} | |
stopAnimation() { | |
if (this.active === true) { | |
this.active = false | |
window.clearInterval(this.carousel) | |
} | |
} | |
connectedCallback() { | |
this.startAnimation() | |
} | |
attributeChangedCallback() { | |
if ( | |
this.active === true | |
&& this.words.length < 2 | |
) { | |
this.stopAnimation() | |
} | |
if ( | |
this.active === false | |
&& 2 <= this.words.length | |
) { | |
this.startAnimation() | |
} | |
} | |
disconnectedCallback() { | |
this.stopAnimation() | |
} | |
} | |
customElements.define('word-carousel', WordCarousel) | |
</script> | |
<!-- basic --> | |
<word-carousel></word-carousel> | |
<!-- default content --> | |
<word-carousel>Default Content</word-carousel> | |
<!-- no words --> | |
<word-carousel words></word-carousel> | |
<!-- empty words --> | |
<word-carousel words=""></word-carousel> | |
<!-- one word --> | |
<word-carousel words=one></word-carousel> | |
<!-- multiple words --> | |
<word-carousel words="one two three"></word-carousel> | |
<!-- full example --> | |
<word-carousel words="four five six">Words…</word-carousel> | |
<!-- custom durations --> | |
<word-carousel words="seven eight nine" fade-duration=100 word-duration=1000></word-carousel> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment