Make Webcomponent
This commit is contained in:
parent
bfc7524d1b
commit
e1679d94c8
@ -0,0 +1,54 @@
|
|||||||
|
// class RSVPControlButton extends HTMLElement {
|
||||||
|
// constructor() {
|
||||||
|
// super()
|
||||||
|
// const shadow = this.attachShadow({mode: 'open'})
|
||||||
|
// const button = document.createElement()
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
class RSVPControls extends HTMLElement {
|
||||||
|
constructor() {
|
||||||
|
super()
|
||||||
|
const shadow = this.attachShadow({ mode: 'open' })
|
||||||
|
// const shadow = document.createElement('div')
|
||||||
|
shadow.innerHTML = `
|
||||||
|
<button action="prevSentence"><<</button>
|
||||||
|
<button action="prevWord"><</button>
|
||||||
|
<button action="stop">stop</button>
|
||||||
|
<button action="playpause">start</button>
|
||||||
|
<button action="nextWord">></button>
|
||||||
|
<button action="nextSentence">>></button>
|
||||||
|
`
|
||||||
|
this._root = shadow
|
||||||
|
// this.appendChild(shadow)
|
||||||
|
}
|
||||||
|
|
||||||
|
connectedCallback() {
|
||||||
|
for (let button of this._root.querySelectorAll('button')) {
|
||||||
|
button.addEventListener('click', e => {
|
||||||
|
let action = e.target.getAttribute('action')
|
||||||
|
let evt = new CustomEvent('control-event', { detail: { action } })
|
||||||
|
this.dispatchEvent(evt)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateUI(chapter, player) {
|
||||||
|
this.getButton('prevSentence').disabled = !chapter.hasPrevSentence()
|
||||||
|
this.getButton('prevWord').disabled = !chapter.hasPrevWord()
|
||||||
|
this.getButton('nextWord').disabled = !chapter.hasNextWord()
|
||||||
|
this.getButton('nextSentence').disabled = !chapter.hasNextSentence()
|
||||||
|
this.getButton('playpause').innerText = player.playing ? 'pause' : 'start'
|
||||||
|
}
|
||||||
|
|
||||||
|
getButton(name) {
|
||||||
|
for (let btn of this._root.querySelectorAll('button')) {
|
||||||
|
if (btn.getAttribute('action') === name) {
|
||||||
|
return btn
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.customElements.define('rsvp-controls', RSVPControls)
|
@ -0,0 +1,76 @@
|
|||||||
|
import './rsvp-word.js'
|
||||||
|
import './rsvp-controls.js'
|
||||||
|
|
||||||
|
import { Chapter } from '../src/Chapter.js'
|
||||||
|
import { Player } from '../src/Player.js'
|
||||||
|
|
||||||
|
class RSVPReader extends HTMLElement {
|
||||||
|
constructor() {
|
||||||
|
super()
|
||||||
|
const shadow = this.attachShadow({ mode: 'open' })
|
||||||
|
const word = document.createElement('rsvp-word')
|
||||||
|
const controls = document.createElement('rsvp-controls')
|
||||||
|
|
||||||
|
shadow.appendChild(word)
|
||||||
|
shadow.appendChild(controls)
|
||||||
|
|
||||||
|
this._root = shadow
|
||||||
|
this._rsvpWord = word
|
||||||
|
this._rsvpControls = controls
|
||||||
|
|
||||||
|
this.player = new Player()
|
||||||
|
this.player.subscribe('main', this.tick.bind(this))
|
||||||
|
this.setText('Sample Text. Easy there.')
|
||||||
|
|
||||||
|
this._rsvpControls.addEventListener(
|
||||||
|
'control-event',
|
||||||
|
this.handleControlEvent.bind(this)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
setText(text) {
|
||||||
|
this.chapter = new Chapter(text, 10)
|
||||||
|
this.updateChildrenUI()
|
||||||
|
}
|
||||||
|
|
||||||
|
tick() {
|
||||||
|
if (!this.chapter.hasNext()) {
|
||||||
|
this.player.stop()
|
||||||
|
} else {
|
||||||
|
this.chapter.next()
|
||||||
|
}
|
||||||
|
this.updateChildrenUI()
|
||||||
|
}
|
||||||
|
|
||||||
|
updateChildrenUI() {
|
||||||
|
this._rsvpWord.setAttribute('word', this.chapter.currentSegment)
|
||||||
|
this._rsvpControls.updateUI(this.chapter, this.player)
|
||||||
|
}
|
||||||
|
|
||||||
|
handleControlEvent(e) {
|
||||||
|
switch (e.detail.action) {
|
||||||
|
case 'prevSentence':
|
||||||
|
this.chapter.prevSentence()
|
||||||
|
break
|
||||||
|
case 'nextSentence':
|
||||||
|
this.chapter.nextSentence()
|
||||||
|
break
|
||||||
|
case 'prevWord':
|
||||||
|
this.chapter.prevWord()
|
||||||
|
break
|
||||||
|
case 'nextWord':
|
||||||
|
this.chapter.nextWord()
|
||||||
|
break
|
||||||
|
case 'playpause':
|
||||||
|
this.player.toggle()
|
||||||
|
break
|
||||||
|
case 'stop':
|
||||||
|
this.player.stop()
|
||||||
|
this.chapter.reset()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
this.updateChildrenUI()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.customElements.define('rsvp-reader', RSVPReader)
|
37
index.html
37
index.html
@ -1,47 +1,24 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
|
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
|
||||||
<title>Document</title>
|
<title>Document</title>
|
||||||
<style>
|
<style>
|
||||||
.marker {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div id="root">
|
|
||||||
<textarea id="input">
|
<textarea id="input">
|
||||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Error fuga eos odit cupiditate harum quibusdam beatae recusandae aut asperiores, molestiae provident modi quia, atque dicta et earum sunt assumenda inventore.</textarea
|
Lorem ipsum dolor sit amet consectetur adipisicing elit. Error fuga eos odit cupiditate harum quibusdam beatae recusandae aut asperiores, molestiae provident modi quia, atque dicta et earum sunt assumenda inventore.</textarea>
|
||||||
>
|
|
||||||
<button class="action" action="load" id="load">Load Text</button>
|
<button class="action" action="load" id="load">Load Text</button>
|
||||||
<div>
|
|
||||||
Info:
|
<hr>
|
||||||
</div>
|
|
||||||
<div>
|
<rsvp-reader></rsvp-reader>
|
||||||
<div>
|
|
||||||
<div class="marker">|</div>
|
|
||||||
<rsvp-word id="output"></rsvp-word>
|
|
||||||
<div class="marker">|</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<button class="action" action="prevSentence" id="prevSentence">
|
|
||||||
<<
|
|
||||||
</button>
|
|
||||||
<button class="action" action="prevWord" id="prevWord"><</button>
|
|
||||||
<button class="action" action="nextWord" id="nextWord">></button>
|
|
||||||
<button class="action" action="nextSentence" id="nextSentence">
|
|
||||||
>>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<button class="action" action="play-pause" id="play"></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script type="module" src="index.js"></script>
|
<script type="module" src="index.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
69
index.js
69
index.js
@ -1,67 +1,12 @@
|
|||||||
import { Chapter } from './src/Chapter.js'
|
import './components/rsvp-reader.js'
|
||||||
import { Player } from './src/Player.js'
|
|
||||||
|
|
||||||
import './components/rsvp-word.js'
|
|
||||||
|
|
||||||
const inputText = document.getElementById('input')
|
const inputText = document.getElementById('input')
|
||||||
const output = document.getElementById('output')
|
const rsvpReader = document.getElementsByTagName('rsvp-reader')[0]
|
||||||
|
const loadBtn = document.getElementById('load')
|
||||||
|
|
||||||
const prevSentenceButton = document.getElementById('prevSentence')
|
function loadText() {
|
||||||
const prevWordButton = document.getElementById('prevWord')
|
rsvpReader.setText(inputText.value)
|
||||||
const nextWordButton = document.getElementById('nextWord')
|
|
||||||
const nextSentenceButton = document.getElementById('nextSentence')
|
|
||||||
|
|
||||||
const playButton = document.getElementById('play')
|
|
||||||
|
|
||||||
let chapter = new Chapter(inputText.value, 10)
|
|
||||||
let player = new Player()
|
|
||||||
|
|
||||||
function updateUI() {
|
|
||||||
prevSentenceButton.disabled = !chapter.hasPrevSentence()
|
|
||||||
prevWordButton.disabled = !chapter.hasPrevWord()
|
|
||||||
nextWordButton.disabled = !chapter.hasNextWord()
|
|
||||||
nextSentenceButton.disabled = !chapter.hasNextSentence()
|
|
||||||
|
|
||||||
playButton.innerText = player.playing ? 'pause' : 'start'
|
|
||||||
|
|
||||||
output.setAttribute('word', chapter.currentSegment)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function tick() {
|
loadBtn.addEventListener('click', loadText)
|
||||||
if (!chapter.hasNext()) {
|
loadText()
|
||||||
player.stop()
|
|
||||||
} else {
|
|
||||||
chapter.next()
|
|
||||||
}
|
|
||||||
updateUI()
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleClick(e) {
|
|
||||||
switch (e.target.getAttribute('action')) {
|
|
||||||
case 'load':
|
|
||||||
chapter = new Chapter(inputText.value, 10)
|
|
||||||
break
|
|
||||||
case 'prevSentence':
|
|
||||||
chapter.prevSentence()
|
|
||||||
break
|
|
||||||
case 'nextSentence':
|
|
||||||
chapter.nextSentence()
|
|
||||||
break
|
|
||||||
case 'prevWord':
|
|
||||||
chapter.prevWord()
|
|
||||||
break
|
|
||||||
case 'nextWord':
|
|
||||||
chapter.nextWord()
|
|
||||||
break
|
|
||||||
case 'play-pause':
|
|
||||||
player.toggle()
|
|
||||||
break
|
|
||||||
}
|
|
||||||
updateUI()
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let button of document.getElementsByClassName('action')) {
|
|
||||||
button.onclick = handleClick
|
|
||||||
}
|
|
||||||
player.subscribe('main', tick)
|
|
||||||
updateUI()
|
|
||||||
|
@ -6,6 +6,10 @@ export class Chapter {
|
|||||||
this.segments = segments
|
this.segments = segments
|
||||||
this.words = words
|
this.words = words
|
||||||
this.sentences = sentences
|
this.sentences = sentences
|
||||||
|
this.reset()
|
||||||
|
}
|
||||||
|
|
||||||
|
reset() {
|
||||||
this.currentIdx = 0
|
this.currentIdx = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user