React.js:非CSS动画 [英] React.js: Non-CSS animations

查看:241
本文介绍了React.js:非CSS动画的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  / ** 
* @jsx React.DOM
* /

$ b b 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;
}

函数lerp(低,高,分数){
返回低+(高 - 低)*分数;
}


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)}>左< / button>左< / button>
< / p> $ b $ lt; / button>
< button onClick = {this.move.bind(this,1) $ b< 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 {
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 =10cy =10cx = {this.state.x + 10} />
}
});


React.renderComponent(
< App />,
document.body
);

有更有效的动画方法吗?

代码架构是吗?



CSS Transitions -on 在这里没有帮助,因为我不使用CSS。

解决方案

href =https://github.com/pleasetrythisathome/react.animate =nofollow> project 在我的反应锤集成

这里的动画BlinkingThing的代码:

p>

  var BlinkingThing = React.createClass({
mixins:[React.Animate],
blink:function ){
var that = this;
var animateAfter = function(){
that.animate({
color:'green'
},that.props。 blinkBack);
};
this.animate({
color:'yellow'
},this.props.blinkTo,animateAfter);
},
componentDidReceiveProps:function(){
this.setState({color:this.props.color})
}
this.setState({color:this.props.color})
},
receiveHammerEvent:function(ev){
if(ev){
var value = ev.type;

switch(value){
case'tap':
this.blink();
break;
}
}
},
getInitialState:function(){
return {};
},
render:function(){
var style = {
display:'inline-block',
backgroundColor:this.state.color
};

return(< div style = {style}> {this.props.children}< / div>);
}
});

您需要一些父组件,它会传播副作用(例如触摸事件)状态在BlinkingThing组件(动画依靠状态改变,当你调用this.animate func),我做了一个HitArea组件这样做。当它发生时,它从它的孩子通过锤子事件调用receiveHammerEvent func。


React documentation doesn’t have anything about handling animations that are not CSS transitions, such as animation of scroll position and SVG attributes.

As for CSS transitions, there is an add-on.

Here is a simple SVG example example:

/**
 * @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
);

Is there a more efficient way of doing animations?
It the code architecture right?

CSS Transitions add-on doesn't help here since I don't use CSS.

解决方案

I successfully used this project in my react-hammer integration project there are some examples with hammer events and react animation.

Here code of animated "BlinkingThing":

var BlinkingThing = React.createClass({
    mixins: [React.Animate],
    blink: function () {
        var that = this;
        var animateAfter = function () {
            that.animate({
                color: 'green'
            }, that.props.blinkBack);
        };
        this.animate({
            color: 'yellow'
        }, this.props.blinkTo, animateAfter);
    },
    componentDidReceiveProps: function () {
        this.setState({color: this.props.color})
    },
    componentDidMount: function () {
        this.setState({color: this.props.color})
    },
    receiveHammerEvent: function (ev) {
        if (ev) {
            var value = ev.type;

            switch (value) {
                case 'tap':
                    this.blink();
                    break;
            }
        }
    },
    getInitialState: function () {
        return {};
    },
    render: function () {
        var style = {
            display: 'inline-block',
            backgroundColor: this.state.color
        };

        return (<div style={style}>{this.props.children}</div>);
    }
});

You need some parent component which will propagate side effects(touch events, for example) to trigger changes of state in BlinkingThing component (animation rely on state changing when you call this.animate func), I made a HitArea component to do that. It calls receiveHammerEvent func from its children passing hammer event when it occurs.

这篇关于React.js:非CSS动画的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆