Skip to content

Commit

Permalink
feat: add redux and fix player error
Browse files Browse the repository at this point in the history
  • Loading branch information
oct16 committed Mar 14, 2020
1 parent c7cc5b3 commit 6ef5ba7
Show file tree
Hide file tree
Showing 20 changed files with 348 additions and 100 deletions.
2 changes: 1 addition & 1 deletion assets/template.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<body>

<script type="module">
import { replay } from './replay.js'
import { replay } from './replay.esm.js'
replay()
</script>

Expand Down
2 changes: 1 addition & 1 deletion examples/test.html
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ <h2>Form:</h2>
}
</script>
<script type="module">
import { record, DB } from './replay.js'
import { record, DB } from './replay.esm.js'
DB.then(db => {
db.clear()
const ctr = record({
Expand Down
2 changes: 1 addition & 1 deletion examples/todo.html
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ <h1>todos</h1>
</script>

<script type="module">
import { record, DB } from './replay.js'
import { record, DB } from './replay.esm.js'
DB.then(db => {
db.clear()
const ctr = record({
Expand Down
3 changes: 1 addition & 2 deletions packages/player/src/container.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import { VNode, convertVNode } from '@WebReplay/virtual-dom'
import HTML from './ui.html'
import STYLE from './ui.css'
import { Pointer } from './pointer'

export class Container {
container: HTMLElement
sandBox: HTMLIFrameElement
pointer: Pointer

vNode: VNode
width: number
Expand Down Expand Up @@ -42,6 +40,7 @@ export class Container {
const element = parser.parseFromString(HTML, 'text/html').body.firstChild as HTMLElement
element.style.width = this.width + 'px'
element.style.height = this.height + 'px'
element.style.position = 'relative'
element.style.margin = '0 auto'
return (this.container = element)
}
Expand Down
8 changes: 4 additions & 4 deletions packages/player/src/dom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ import {
FormElementEvent,
ChildListUpdateDataType
} from '@WebReplay/snapshot'
import { Player } from './player'
import { PlayerComponent } from './player'
import { nodeStore } from '@WebReplay/utils'
import { convertVNode } from '@WebReplay/virtual-dom';
import { convertVNode } from '@WebReplay/virtual-dom'

export function execFrame(this: Player, snapshot: SnapshotData) {
export function updateDom(this: PlayerComponent, snapshot: SnapshotData) {
const { type, data } = snapshot
switch (type) {
case SnapshotType.MOUSE:
Expand Down Expand Up @@ -49,7 +49,7 @@ export function execFrame(this: Player, snapshot: SnapshotData) {
break
case 'childList':
const parentNode = nodeStore.getNode(parentId) as HTMLElement
const targetNode = nodeStore.getNode(nodeId) as Element || convertVNode(vNode, null)
const targetNode = (nodeStore.getNode(nodeId) as Element) || convertVNode(vNode, null)
if (type === ChildListUpdateDataType.DELETE) {
if (targetNode) {
parentNode!.removeChild(targetNode)
Expand Down
21 changes: 15 additions & 6 deletions packages/player/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,27 @@
import { DBPromise, Redux } from '@WebReplay/utils'
import { DBPromise, ProgressTypes, PlayerTypes, reduxStore } from '@WebReplay/utils'
import { Container } from './container'
import { Panel } from './panel'

export async function replay() {
const indexDB = await DBPromise
const { width, height, vNode, data } = await indexDB.getData()

const box = new Container({ vNode, width, height })
new Panel(box.container, data)
const c = new Container({ vNode, width, height })
new Panel(c.container, data)

Redux.dispatch({
type: 'PLAY',
reduxStore.dispatch({
type: ProgressTypes.INFO,
data: {
speed: 1
frame: 0,
curTime: data[0].time,
startTime: data[0].time,
endTime: data[data.length - 1].time,
length: data.length
}
})

reduxStore.dispatch({
type: PlayerTypes.SPEED,
data: { speed: 1 }
})
}
36 changes: 20 additions & 16 deletions packages/player/src/keyboard.ts
Original file line number Diff line number Diff line change
@@ -1,43 +1,47 @@
import { Redux } from '@WebReplay/utils'
// import { Redux } from '@WebReplay/utils'

export class Keyboard {
import { reduxStore } from '@WebReplay/utils'
import { PlayerTypes } from '@WebReplay/utils'

export class KeyboardComponent {
container: HTMLElement
controller: HTMLElement

pauseBtn: HTMLElement
playBtn: HTMLElement

speed: number

constructor(container: HTMLElement) {
this.container = container
this.initCtrlKeyboard()
this.init()
}

initCtrlKeyboard() {
init() {
this.controller = this.container.querySelector('.wr-keyboard') as HTMLElement
this.pauseBtn = this.controller.querySelector('.pause') as HTMLButtonElement
this.playBtn = this.controller.querySelector('.play') as HTMLButtonElement
this.controller.addEventListener('click', (e: MouseEvent) => {
if (e.target) {
const speed = (e.target as HTMLElement).getAttribute('speed')
Redux.dispatch({
type: 'PLAY',
this.controller.addEventListener('click', (e: MouseEvent & { target: HTMLElement & { type: string } }) => {
if (e.target && e.target.type === 'button') {
const speed = Number((e.target as HTMLElement).getAttribute('speed'))
this.speed = speed
reduxStore.dispatch({
type: PlayerTypes.SPEED,
data: {
speed
}
})
}
})

Redux.subscribe(state => {
if (!isNaN(state.speed)) {
this.paly(state.speed)
this.setSpeed(state.speed)
}
reduxStore.subscribe('player', state => {
this.paly(state.speed)
this.setSpeed(state.speed)
})
}

paly(speed: number) {
if (speed != 0) {
if (speed !== 0) {
this.pauseBtn.removeAttribute('disabled')
this.playBtn.setAttribute('disabled', '')
} else {
Expand All @@ -51,7 +55,7 @@ export class Keyboard {
;[...speedNodes].forEach(node => {
node.removeAttribute('disabled')
})
const index = speed == 1 ? 0 : speed == 4 ? 1 : speed == 8 ? 2 : -1
const index = speed === 1 ? 0 : speed === 2 ? 1 : speed === 4 ? 2 : -1
if (index > -1) {
speedNodes[index].setAttribute('disabled', '')
}
Expand Down
19 changes: 12 additions & 7 deletions packages/player/src/panel.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import { Keyboard } from './keyboard'
import { Player } from './player'
import { Pointer } from './pointer'
import { KeyboardComponent } from './keyboard'
import { PlayerComponent } from './player'
import { PointerComponent } from './pointer'
import { SnapshotData } from '@WebReplay/snapshot'
import { ProgressComponent } from './progress'

export class Panel {
container: HTMLElement
data: SnapshotData[]

keyboard: Keyboard
player: Player
keyboard: KeyboardComponent
progress: ProgressComponent
pointer: PointerComponent
player: PlayerComponent

constructor(container: HTMLElement, data: SnapshotData[]) {
this.container = container
Expand All @@ -17,7 +20,9 @@ export class Panel {
}

initComponent() {
this.keyboard = new Keyboard(this.container)
this.player = new Player(this.data, new Pointer())
this.keyboard = new KeyboardComponent(this.container)
this.progress = new ProgressComponent(this.container)
this.pointer = new PointerComponent()
this.player = new PlayerComponent(this.data, this.pointer, this.progress)
}
}
88 changes: 65 additions & 23 deletions packages/player/src/player.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,33 @@
import { Pointer } from './pointer'
import { PointerComponent } from './pointer'
import { SnapshotData } from '@WebReplay/snapshot'
import { execFrame } from './dom'
import { Redux } from '@WebReplay/utils'
import { updateDom } from './dom'
import { reduxStore, PlayerTypes, ProgressState } from '@WebReplay/utils'
import { ProgressComponent } from './progress'

export class Player {
export class PlayerComponent {
data: SnapshotData[]
isPause = false
isPause = true
index = 0
speed: number
requestID: number
startTime: number
pointer: Pointer
pointer: PointerComponent
progress: ProgressComponent
progressState: ProgressState

constructor(data: SnapshotData[], pointer: Pointer) {
progressPercentage = 0
progressNextTime = 0

constructor(data: SnapshotData[], pointer: PointerComponent, progress: ProgressComponent) {
this.data = data
this.pointer = pointer
this.progress = progress

Redux.subscribe(state => {
reduxStore.subscribe('player', state => {
this.progressState = reduxStore.getState()['progress']
const speed = state.speed
this.speed = speed

if (speed > 0) {
this.play(speed)
} else {
Expand All @@ -25,42 +36,73 @@ export class Player {
})
}

play(speed: number = 1) {
function loop(this: Player, timeStamp: DOMHighResTimeStamp) {
if (!this.data[this.index]) {
play(speed: number) {
this.isPause = false

const { startTime, endTime } = this.progressState
const duration = endTime - startTime

const stepTime = duration / 100

cancelAnimationFrame(this.requestID)
this.requestID = requestAnimationFrame(loop.bind(this))

const initTime = Date.now()
this.startTime = 0

function loop(this: PlayerComponent) {
const timeStamp = Date.now() - initTime
if (this.index > 0 && !this.data[this.index + 1]) {
this.stop()
return
}
if (!this.startTime) {
this.startTime = Number(this.data[this.index].time) - timeStamp
this.startTime = Number(this.data[this.index].time)
}

const currTime = this.startTime + timeStamp * speed
const nextTime = Number(this.data[this.index].time)
if (this.index >= this.data.length - 1) {
return this.stop()
} else if (currTime >= nextTime) {
execFrame.call(this, this.data[this.index])
const nextTime = Number(this.data[this.index + 1].time)

if (!this.progressNextTime) {
this.progressNextTime = currTime
}

// for progress
if (currTime > this.progressNextTime) {
this.progressNextTime = this.progressNextTime + stepTime
this.progress.updateProgress(this.progressPercentage)
this.progressPercentage = this.progressPercentage + 1
}

if (currTime >= nextTime) {
this.execFrame.call(this, this.data[this.index])
this.index++
}

this.requestID = requestAnimationFrame(loop.bind(this))
}

this.requestID = requestAnimationFrame(loop.bind(this))
}

pause() {
cancelAnimationFrame(this.requestID)
this.startTime = 0
Redux.dispatch({
type: 'PLAY',
this.isPause = true

reduxStore.dispatch({
type: PlayerTypes.SPEED,
data: {
speed: 0
}
})
}

stop() {
this.pause()
this.index = 0
this.progressPercentage = 0
this.progressNextTime = 0
this.pause()
}

execFrame(this: PlayerComponent, snapshot: SnapshotData) {
updateDom.call(this, snapshot)
}
}
2 changes: 1 addition & 1 deletion packages/player/src/pointer.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export class Pointer {
export class PointerComponent {
x = 0
y = 0

Expand Down
22 changes: 22 additions & 0 deletions packages/player/src/progress.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { ProgressState } from '@WebReplay/utils'

export class ProgressComponent {
progress: HTMLElement
thumb: HTMLElement
slider: HTMLElement
speed: number
rafId: number

progressState: ProgressState

totalDistance = 0
constructor(c: HTMLElement) {
this.progress = c.querySelector('.wr-progress')! as HTMLElement
this.thumb = this.progress.querySelector('.wr-thumb') as HTMLElement
this.slider = this.progress.querySelector('.wr-slider-bar') as HTMLElement
}

updateProgress(percentage: number) {
this.thumb.style.left = percentage - 0.5 + '%'
}
}
4 changes: 3 additions & 1 deletion packages/player/src/ui.css
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ body {

#wr-player {
position: relative;
pointer-events: none;
}

#wr-pointer {
Expand All @@ -29,7 +30,7 @@ body {
}

.wr-panel {
width: 100vw;
width: 100%;
box-sizing: border-box;
padding: 10px;
height: 40px;
Expand Down Expand Up @@ -73,4 +74,5 @@ body {
left: 0%;
transform: translateY(-3px);
z-index: 10;
/* transition: left .1s linear; */
}
Loading

0 comments on commit 6ef5ba7

Please sign in to comment.