React.js:非CSS动画

NVI*_*NVI 19 javascript css animation svg reactjs

React文档没有关于处理非CSS转换的动画的任何内容,例如滚动位置和SVG属性的动画.

至于CSS过渡,有一个附加组件.

这是一个简单的SVG示例示例:

动画SVG圈

/**
 * @jsx React.DOM
 */


function animate(duration, onStep) {
    var start = Date.now();
    var timer = {id: 0};
    (function loop() {
        timer.id = requestAnimationFrame(function() {
            var diff = Date.now() - start;
            var fraction = diff / duration;
            onStep(fraction);
            if (diff < duration) {
                loop();
            }
        });
    })();
    return timer;
}

function lerp(low, high, fraction) {
    return low + (high - low) * fraction;
}


var App = React.createClass({
    getInitialState: function() {
        return {x: 0}
    },

    move: function(i) {
        this.setState({x: this.state.x + i * 100});
    },

    render: function() {
        return <div className="ShowerItem">
            <p>
                <button onClick={this.move.bind(this, -1)}>Left</button>
                <button onClick={this.move.bind(this, 1)}>Right</button>
            </p>
            <svg><Dot x={this.state.x}/></svg>
        </div>;
    }
});



var Dot = React.createClass({

    getInitialState: function() {
        return {
            x: 0,
            final: 0
        };
    },

    timer: null,

    render: function() {
        var from = this.state.x;
        var to = this.props.x;
        if (to !== this.state.final) {
            this.state.final = to;
            if (this.timer) {
                cancelAnimationFrame(this.timer.id);
            }

            this.timer = animate(500, function(fraction) {
                var x = lerp(from, to, fraction);
                if (fraction >= 1) {
                    this.setState({
                        value: to
                    });
                    this.timer = null;
                } else {
                    this.setState({x: x});
                }
            }.bind(this))
        }

        return <circle r="10" cy="10" cx={this.state.x + 10}/>
    }
});


React.renderComponent(
    <App/>,
    document.body
);
Run Code Online (Sandbox Code Playgroud)

有更有效的动画制作方法吗?
它的代码架构对吗?

CSS Transitions附加组件在这里没有帮助,因为我不使用CSS.

NVI*_*NVI -1

这是我到目前为止所想到的: http: //jsfiddle.net/NV/NtP7n/

\n\n

我重写Dot以利用 React\xe2\x80\x99s 绘制循环:

\n\n
var Dot = React.createClass({\n\n    getInitialState: function() {\n        return {\n            start: 0,\n            x: 0,\n            final: 0,\n            startTime: 0\n        };\n    },\n\n    render: function() {\n        var state = this.state;\n        var props = this.props;\n        var amount = 0;\n\n        if (state.final !== props.x) {\n            state.final = props.x;\n            state.start = state.x;\n            state.startTime = Date.now();\n        } else {\n            amount = (Date.now() - state.startTime) / this.props.duration;\n        }\n\n        if (amount <= 1) {\n            var x = state.start + amount * (props.x - state.start);\n            setTimeout(function() {\n                this.setState({x: x});\n            }.bind(this), 1);\n        } else {\n            state.final = state.x = x = props.x;\n        }\n\n        return <circle r="10" cy="10" cx={x + 10}/>\n    }\n});\n
Run Code Online (Sandbox Code Playgroud)\n\n

我必须打电话:

\n\n
setTimeout(function() {\n    this.setState({current: x});\n}.bind(this), 1);\n
Run Code Online (Sandbox Code Playgroud)\n\n

只是为了在下一个刻度时强制更新。我必须使用 setTimeout 因为render方法中不允许 setState\xe2\x80\x99t 。我想知道是否可以在不使用 setTimeout 的情况下在下一个时钟周期排队更新。

\n