Skip to content

Commit

Permalink
fix: use smooth progress transition
Browse files Browse the repository at this point in the history
  • Loading branch information
ambar committed Feb 9, 2022
1 parent d39df49 commit f68c1ac
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 25 deletions.
51 changes: 37 additions & 14 deletions packages/griffith/src/components/Slider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import {css, StyleDeclarationMap} from 'aphrodite/no-important'
import clamp from 'lodash/clamp'
import {ProgressDot as ProgressDotType} from '../types'
import ProgressDot, {ProgressDotsProps} from './ProgressDot'
import formatPercent from '../utils/formatPercent'

import styles, {
horizontal as horizontalStyles,
Expand Down Expand Up @@ -40,6 +39,11 @@ type State = {
slidingValue: null | number
}

const getRatio = (value: number, total?: number) =>
total ? clamp(value / total, 0, 1) : 0

const toPercentage = (value: number) => `${value * 100}%`

export type SliderProps = OwnProps //& typeof Slider.defaultProps

class Slider extends Component<SliderProps, State> {
Expand Down Expand Up @@ -109,15 +113,38 @@ class Slider extends Component<SliderProps, State> {
return orientation === 'horizontal' ? 'width' : 'height'
}

getPercentage() {
getPercentageValue() {
const {value, total} = this.props
const {isSlideActive, slidingValue} = this.state
return formatPercent(isSlideActive ? slidingValue! : value!, total)
return getRatio(isSlideActive ? slidingValue! : value!, total)
}

getProgressStyle(value: number) {
const {orientation} = this.props
const scaleAxis = orientation === 'horizontal' ? 'scaleX' : 'scaleY'
return {
[this.getSizeKey()]: '100%',
transform: `${scaleAxis}(${value})`,
transformOrigin: this.getAlignKey(),
}
}

getProgressThumbStyle(value: number) {
const {orientation} = this.props
const horizontal = orientation === 'horizontal'
const translateAxis = horizontal ? 'translateX' : 'translateY'
return {
[this.getSizeKey()]: '100%',
transform: `${translateAxis}(${toPercentage(
horizontal ? value : 1 - value
)})`,
transformOrigin: this.getAlignKey(),
}
}

getBufferedPercentage() {
getBufferedPercentageValue() {
const {buffered, total} = this.props
return formatPercent(buffered!, total)
return getRatio(buffered!, total)
}

getSlidingValue(event: globalThis.MouseEvent) {
Expand Down Expand Up @@ -239,6 +266,7 @@ class Slider extends Component<SliderProps, State> {
onKeyDown: this.handleKeyDown,
onMouseDown: this.handleDragStart,
}
const ratio = this.getPercentageValue()
return (
<div
className={this.getClassName('root')}
Expand All @@ -250,18 +278,12 @@ class Slider extends Component<SliderProps, State> {
{Boolean(buffered) && (
<div
className={this.getClassName('bar', 'buffered')}
style={{
[this.getAlignKey()]: 0,
[this.getSizeKey()]: this.getBufferedPercentage(),
}}
style={this.getProgressStyle(this.getBufferedPercentageValue())}
/>
)}
<div
className={this.getClassName('bar')}
style={{
[this.getAlignKey()]: 0,
[this.getSizeKey()]: this.getPercentage(),
}}
style={this.getProgressStyle(ratio)}
/>
{Boolean(progressDots?.length) && (
<ProgressDot
Expand All @@ -273,9 +295,10 @@ class Slider extends Component<SliderProps, State> {
)}
</div>
{!noInteraction && (
// the position indicator (visible when hovering)
<div
className={this.getClassName('thumbWrapper')}
style={{[this.getAlignKey()]: this.getPercentage()}}
style={this.getProgressThumbStyle(ratio)}
>
<div
className={this.getClassName(
Expand Down
2 changes: 1 addition & 1 deletion packages/griffith/src/components/Video.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ class Video extends Component<VideoProps> {
}

// NOTE: 原生 `timeupdate` 事件更新频率不固定(4Hz~66Hz,由系统决定),这里以 rAF 提高了 UI 更新频率
// 但进度条更新仍然是不平滑的,需要考虑使用进度动画(TODO
// TODO: 考虑使用回调直接操作 DOM,减少 React rendering
notifyTimeUpdate = (isRaf: boolean) => {
const {onCurrentTimeUpdate, paused} = this.props

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ exports[`MinimalTimeline get MinimalTimeline component 1`] = `
>
<div
class="bar_1kpj1ed-o_O-bar_g2nzkb-o_O-bar_1kvrquw"
style="left: 0px; width: 0%"
style="width: 100%; transform: scaleX(0); transform-origin: left"
></div>
</div>
</div>
Expand All @@ -37,7 +37,11 @@ exports[`MinimalTimeline get MinimalTimeline component 2`] = `
>
<div
class="bar_1kpj1ed-o_O-bar_g2nzkb-o_O-bar_1kvrquw"
style="left: 0px; width: 32.92470120833653%"
style="
width: 100%;
transform: scaleX(0.3292470120833653);
transform-origin: left;
"
></div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ exports[`VolumeSlider get VolumeSlider component 1`] = `
className="bar_1kpj1ed-o_O-bar_1ql2ook"
style={
Object {
"bottom": 0,
"height": "50%",
"height": "100%",
"transform": "scaleY(0.5)",
"transformOrigin": "bottom",
}
}
/>
Expand All @@ -31,7 +32,9 @@ exports[`VolumeSlider get VolumeSlider component 1`] = `
className="thumbWrapper_ay4wjb-o_O-thumbWrapper_drkmbm"
style={
Object {
"bottom": "50%",
"height": "100%",
"transform": "translateY(50%)",
"transformOrigin": "bottom",
}
}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,28 @@ exports[`TimelineItem get TimelineItem component 1`] = `
class="
bar_1kpj1ed-o_O-bar_g2nzkb-o_O-bar_1kvrquw-o_O-buffered_gsgvhl
"
style="left: 0px; width: 6.417112299465241%"
style="
width: 100%;
transform: scaleX(0.06417112299465241);
transform-origin: left;
"
></div>
<div
class="bar_1kpj1ed-o_O-bar_g2nzkb-o_O-bar_1kvrquw"
style="left: 0px; width: 3.7433155080213902%"
style="
width: 100%;
transform: scaleX(0.0374331550802139);
transform-origin: left;
"
></div>
</div>
<div
class="thumbWrapper_ay4wjb-o_O-thumbWrapper_6t4rjm"
style="left: 3.7433155080213902%"
style="
width: 100%;
transform: translateX(3.7433155080213902%);
transform-origin: left;
"
>
<div class="thumb_ozdqky-o_O-thumb_1omjhz8"></div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,20 @@ exports[`VolumeItem get VolumeItem component 1`] = `
<div class="track_1bopucd-o_O-track_31rx9n-o_O-track_ytl6g2">
<div
class="bar_1kpj1ed-o_O-bar_1ql2ook"
style="bottom: 0px; height: 90%"
style="
height: 100%;
transform: scaleY(0.9);
transform-origin: bottom;
"
></div>
</div>
<div
class="thumbWrapper_ay4wjb-o_O-thumbWrapper_drkmbm"
style="bottom: 90%"
style="
height: 100%;
transform: translateY(9.999999999999998%);
transform-origin: bottom;
"
>
<div class="thumb_ozdqky-o_O-thumb_8gf5gg"></div>
</div>
Expand Down

0 comments on commit f68c1ac

Please sign in to comment.