Created
September 10, 2020 14:03
-
-
Save tomhodgins/cfcebe8006fa0a962cdc9bcfeea00ae0 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
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1"> | |
<title>Count Down Element</title> | |
<script type=module> | |
import html from 'https://v2.crocdn.com/_plugins/html.js' | |
class CountDown extends HTMLElement { | |
constructor() { | |
super() | |
this.time = new Date | |
} | |
connectedCallback() { | |
this.shadow = this.attachShadow({mode: 'open'}) | |
// Adjust this.time according to attributes | |
if (Number(this.getAttribute('utc-offset'))) { | |
this.time.setHours(Number(this.hours) + Number(this.getAttribute('utc-offset')) || 0) | |
} else { | |
this.time.setHours(this.hours || 0) | |
} | |
this.time.setMinutes(this.minutes || 0) | |
this.time.setSeconds(this.seconds || 0) | |
// Adjust day if needed | |
if (this.time < Date.now()) { | |
this.time.setHours(this.time.getHours() + 24) | |
} | |
// Create markup to be populated later | |
if (this.shadow.childNodes.length === 0) { | |
this.shadow.append( | |
html` | |
<ul> | |
<li id=hours> | |
<li id=minutes> | |
<li id=seconds> | |
</ul> | |
<style> | |
ul { | |
list-style: none; | |
display: inline-flex; | |
margin: 0; | |
padding: 0; | |
} | |
li:not(:first-of-type)::before { | |
content: ':'; | |
margin-left: .25em; | |
margin-right: .25em; | |
} | |
</style> | |
` | |
) | |
} | |
// Populate once right away | |
this.updateClock() | |
} | |
updateClock() { | |
const millisecond = 1 | |
const second = millisecond * 1000 | |
const minute = second * 60 | |
const hour = minute * 60 | |
const diff = this.time - Date.now() | |
this.shadow.querySelector('#hours').textContent = String( | |
Math.floor(diff / hour) | |
).padStart(2, 0) | |
this.shadow.querySelector('#minutes').textContent = String( | |
Math.floor((diff % hour) / minute) | |
).padStart(2, 0) | |
this.shadow.querySelector('#seconds').textContent = String( | |
Math.floor((diff % minute) / second) | |
).padStart(2, 0) | |
// Only repeat if not paused and before the timer ends | |
if ( | |
this.hasAttribute('paused') === false | |
&& diff <= Date.now() | |
) { | |
window.setTimeout(tick => this.updateClock(), 1000) | |
} | |
} | |
static get observedAttributes() { | |
return ['paused', 'hours', 'minutes', 'seconds'] | |
} | |
// hours="" | |
get hours() { | |
return this.getAttribute('hours') | |
} | |
set hours(string) { | |
return this.setAttribute('hours', Number(string)) | |
} | |
// minutes="" | |
get minutes() { | |
return this.getAttribute('minutes') | |
} | |
set minutes(string) { | |
return this.setAttribute('minutes', Number(string)) | |
} | |
// seconds="" | |
get seconds() { | |
return this.getAttribute('seconds') | |
} | |
set seconds(string) { | |
return this.setAttribute('seconds', Number(string)) | |
} | |
// paused="" | |
get paused() { | |
return this.getAttribute('paused') | |
} | |
set paused(string) { | |
return string | |
? this.setAttribute('paused', '') | |
: this.removeAttribute('paused') | |
} | |
// Listed to changes in paused="" | |
attributeChangedCallback(name, oldValue, newValue) { | |
console.log(name, oldValue, newValue) | |
if ( | |
name === 'paused' | |
&& newValue === null | |
) { | |
if (this.shadow) { | |
this.updateClock() | |
} | |
} | |
} | |
} | |
customElements.define('count-down', CountDown) | |
</script> | |
<h1>Count Down</h1> | |
<h2>Empty tag</h2> | |
<count-down></count-down> | |
<h2>Default content</h2> | |
<count-down>15:00</count-down> | |
<h2>Paused content</h2> | |
<count-down paused>15:00</count-down> | |
<h2>Normal Usage</h2> | |
<count-down hours=1 minutes=2>15:00</count-down> | |
<!-- <h2>UTC time zone offset</h2> | |
<count-down hours=1 minutes=2 seconds=3 utc-offset=-5 paused>15:00</count-down> --> | |
<h2>Shipping until 5pm</h2> | |
<div style="background: #cec"> | |
Same-day dispatch if ordered within the next | |
<count-down hours=17>15:00</count-down> | |
hours | |
</div> | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment