使用requestanimationframe基于fps在水平方向上使线横向

时间:2018-08-26 11:30:19

标签: javascript html5 reactjs requestanimationframe

我在画布上放置了一行(这是一个div)(此处不相关)。假设我有一个视频播放器,播放25 fps的视频。播放视频时,此行和画布安排应用作辅助时间线。我要使线条平滑地横切(没有任何颠簸或跳动行为)。我已经解决了,直到线与视频时间同步移动为止。但是线的过渡是跳跃的。我正在移动线架副。

我的代码:

var fps = 25;
var now;
var then = Date.now();
var interval = 1000/fps;
var delta;

var myReq;

class App extends Component {

    state = {
        playing: false,
        xPos: 1,
        line1_xStart: 700,
        line1_xEnd: 700,
        isMouseDown: false,
        player: {},
        startX:0

    }

    componentDidMount() {
        canvas = document.getElementsByTagName("canvas")[0];
        ctx = canvas.getContext("2d");

        w = canvas.width;
        h = canvas.height;

        ctx.fillStyle = "#808891";
        this.init()

    }

    componentWillUpdate(nextProps, nextState){

    }

    init = ()=> {
        this.initVideoJS()
    }

    initVideoJS = ()=> {
        let x
        myPlayer = videojs('video-el');

        myPlayer.on('play', ()=>{
            this.draw()
            }
        )
        myPlayer.on("timeupdate", () => {
            duration = myPlayer.duration()
            currentTime = myPlayer.currentTime();
            x = duration
            //console.log(x)
            this.setState({line1_xEnd: 700 + (currentTime * document.getElementById("DemoCanvas").offsetWidth/duration)}, ()=>{
                console.log(this.state.line1_xEnd)
            })
        })
    }

    draw = () => {

        let totalFrames = myPlayer.duration() * 25


        now = Date.now();
        delta = now - then;

        if(this.state.startX < 900){

            if (delta > interval) {
                counter = counter + 1
                console.log("counter is " + counter)
                // update time stuffs

                // Just `then = now` is not enough.
                // Lets say we set fps at 10 which means
                // each frame must take 100ms
                // Now frame executes in 16ms (60fps) so
                // the loop iterates 7 times (16*7 = 112ms) until
                // delta > interval === true
                // Eventually this lowers down the FPS as
                // 112*10 = 1120ms (NOT 1000ms).
                // So we have to get rid of that extra 12ms
                // by subtracting delta (112) % interval (100).
                // Hope that makes sense.
                then = now - (delta % (interval));

                this.setState({ startX: this.state.startX + ((900/(totalFrames)))})

                // ... Code for Drawing the Frame ...
            }
        }

        window.requestAnimationFrame(this.draw);


    }

    handlePlay() {

    }

    render() {
        return (
            <div>
                <video id="video-el" className="video-js"  ref={node => this.video_el = node} controls preload="auto" width="640" height="264"
                       poster="MY_VIDEO_POSTER.jpg" data-setup="{}">
                    <source src="http://techslides.com/demos/sample-videos/small.mp4" type='video/mp4'/>
                </video>

                <div onClick={this.shiftLine.bind(this)}
                     onMouseDown={this.mouseDown.bind(this)}
                     onMouseUp={this.onMouseUp.bind(this)}
                     onMouseMove={this.mouseMove.bind(this)}>
                    <div className="App">
                        <canvas id="DemoCanvas" style={{width: 900, height:"60px"}}></canvas>
                    </div>
                    <div className="line"
                         style={{
                             position: 'absolute',
                             transform: `translate(${this.state.startX}px, 0px)`
                         }}
                    />

                </div>
            </div>

        );
    }
}

我们要做的就是设置每秒的帧数和每帧之间的间隔。在绘图功能中,我们从当前时间中减去上一帧的执行时间,以检查自上一帧以来经过的时间是否大于我们的间隔(基于fps)。如果条件的计算结果为true,则将当前帧的时间设置为下一个绘图调用中的“最后一帧执行时间”。

以上是在每次更改帧时移动行的代码。该视频是一个5秒的视频。我尝试通过进行以下更改来使过渡变得顺畅:

draw = () => {

        let totalFrames = myPlayer.duration() * 25


        now = Date.now();
        delta = now - then;

        if(this.state.startX < 900){

            if (delta > interval/2) {
                counter = counter + 1
                console.log("counter is " + counter)
                // update time stuffs

                // Just `then = now` is not enough.
                // Lets say we set fps at 10 which means
                // each frame must take 100ms
                // Now frame executes in 16ms (60fps) so
                // the loop iterates 7 times (16*7 = 112ms) until
                // delta > interval === true
                // Eventually this lowers down the FPS as
                // 112*10 = 1120ms (NOT 1000ms).
                // So we have to get rid of that extra 12ms
                // by subtracting delta (112) % interval (100).
                // Hope that makes sense.
                then = now - (delta % (interval/2));

                this.setState({ startX: this.state.startX + ((900/(totalFrames))/2)})

                // ... Code for Drawing the Frame ...
            }
        }

        window.requestAnimationFrame(this.draw);


    }

我将间隔除以2,并相应地更改了setState。

那里仍然有一个混蛋。它不应该是平滑的。

0 个答案:

没有答案