首页 > 解决方案 > 在 reactjs 组件中覆盖或停止 CSS 动画

问题描述

我正在尝试创建一个包含 32 个项目的循环导航组件。有一个图形,其中一个点对应于每个项目,右侧有一个视口,一次显示 5 个项目。为了使这种效果看起来不错,我必须在视口附近的对象之间留出更多空间,并将另一侧的点推到一起。

问题是当我旋转对象时,CSS 动画无法正常工作。顺时针旋转,所有对象都跳到它们的位置,除了最终为 0 度的对象,它平滑地旋转到正确的位置。逆时针旋转,所有对象都正确动画,除了来自 0 度的对象,它在其余动画之前跳跃。

我已经重构了代码,并尝试了更多在此处列出的内容。我唯一能说的是,我必须猜测并检查以获取 pctAdd 和 pctSub 的值,我用它们将点从中心(0 度)点定位回来。

var circle = 400;
var centerX = circle / 4;
var centerY = circle / 4;
var radius = circle / 2;
var btnCenterX = centerX - centerX / 10 - circle * .01;
var btnCenterY = centerY + centerY / 5 - circle * .01;
var btnDistance = 1.05;

var Petal = function(radian, petalIndex, num, exerciseName) {
    this.x = Math.cos(radian) * radius + centerX;
    this.y = Math.sin(radian) * radius + centerY;
    this.btnx = Math.cos(radian) * radius * btnDistance + btnCenterX;
    this.btny = Math.sin(radian) * radius * btnDistance + btnCenterY;
    this.name = exerciseName;
    this.degree = radian * 57.2958;
    this.position = num;
    this.index = petalIndex;
};

var Petals = [  // (radian, index, position, name of exercise)
    new Petal(Math.PI * 0/16, "3", 1, "Single Whip, Raise Hands"),
    new Petal(Math.PI * 1/16, "19", 2, "Crane Spreads Wings, Brush Knee Twist Step"),
    new Petal(Math.PI * 2/16, "11", 3, "Play the Fiddle, Brush Left Knee"),
    new Petal(Math.PI * 3/16, "27", 4, "Apparent Close Up, Carry Tiger to Mountain"),
    new Petal(Math.PI * 4/16, "7", 5, "Brush Right Knee, Grasp Birds Tail"),
    new Petal(Math.PI * 5/16, "23", 6, "Diagonal Single While, Fist Under Elbow"),
    new Petal(Math.PI * 6/16, "15", 7, "Retreating Monkey, Slanted Flying"),
    new Petal(Math.PI * 7/16, "31", 8, "Raise Hands, Crane Spreads Wings"),
    new Petal(Math.PI * 8/16, "2", 9, "Brush Knee Twist Step, Needle at Sea Bottom"),
    new Petal(Math.PI * 9/16, "18", 10, "Fan Through the Back, Snake Puts Out Tongue"),
    new Petal(Math.PI * 10/16, "10", 11, "Grasp Birds Tail, Single Whip"),
    new Petal(Math.PI * 11/16, "26", 12, "Cloud Hands, Single Whip"),
    new Petal(Math.PI * 12/16, "6", 13, "Snake Creeps Down, Golden Rooster"),
    new Petal(Math.PI * 13/16, "22", 14, "Kick Left, Kick Right"),
    new Petal(Math.PI * 14/16, "14", 15, "Left Foot Kicks with Sole, Brush Left Knee"),
    new Petal(Math.PI * 15/16, "30", 16, "Brush Right Knee, Punch Downward"),
    new Petal(Math.PI * 16/16, "4", 17, "Ward Off Left, Grasp Birds Tail"),
    new Petal(Math.PI * 17/16, "20", 18, "Single Whip, Work the Shuttles"),
    new Petal(Math.PI * 18/16, "12", 19, "Ward Off Left, Ward Off Right"),
    new Petal(Math.PI * 19/16, "28", 20, "Grasp Birds Tail, Single Whip"),
    new Petal(Math.PI * 20/16, "8", 21, "Snake Creeps Down, Form Seven Star"),
    new Petal(Math.PI * 21/16, "24", 22, "Retreat to Ride Tiger, Turn and Kick Horizontally"),
    new Petal(Math.PI * 22/16, "16", 23, "Shoot Tiger with Bow, Step Up Parry Punch"),
    new Petal(Math.PI * 23/16, "32", 24, "Apparent Close up, Conclusion of Tai Chi"),
    new Petal(Math.PI * 24/16, "1", 25, "Warm Ups"),
    new Petal(Math.PI * 25/16, "17", 26, "Temple Exercises"),
    new Petal(Math.PI * 26/16, "9", 27, "Stance Training"),
    new Petal(Math.PI * 27/16, "25", 28, "Five Organ Breathing"),
    new Petal(Math.PI * 28/16, "5", 29, "Stepping Exercises"),
    new Petal(Math.PI * 29/16, "21", 30, "Meditation"),
    new Petal(Math.PI * 30/16, "13", 31, "Preparation, Ward Off"),
    new Petal(Math.PI * 31/16, "29", 32, "Grasp Birds Tail"),
];

class MakeFlower extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            rotatePer: 0,
            center: 1,
            allowScroll: true,
        }
        this.rotateFlower = this.rotateFlower.bind(this);
    }

    rotateFlower(m) {
        if(!this.state.allowScroll) return;
        this.setState({allowScroll: false});
        setTimeout(() => {this.setState({allowScroll: true})}, 500);

        this.setState({rotatePer: this.state.rotatePer + 360 * m / 32});

        var r = this.state.center - m;
        if(r >= 32) r = r - 32;
        if(r < 1) r = r + 32;
        this.setState({center: r});
    }

    getStyle(rotate) {
        var navDistance = 2.5 / circle * circle;
        var btnx = Math.cos(rotate / 57.2958) * radius * navDistance + btnCenterX;
        var btny = Math.sin(rotate / 57.2958) * radius * navDistance + btnCenterY - 20;

        const buttonStyle = {transform: "translate(" + btnx + "px, " +
                btny + "px)"} 
        return buttonStyle;
    }

    render() {
        function putPetal(rotate, index, position) {
            var move = rotate + 360 * 8/32;
            var setPetalY = circle * -.158;
            var setPetalX = circle * .0075;

            const styling = {
                transform: "rotate(" + move + "deg) translate(" + 
                        setPetalX + "px, " + setPetalY + "px)",
                width: circle/2 + "px",
                zIndex: index,
            }

            return (
                <div key={position}>
                    <img aria-hidden="true" src={flame} style={styling} className="abs"
                        alt="" />
                </div>
            );
        }

        function putButton(rotate, index, position, name, center) {
            var btnx = Math.cos(rotate / 57.2958) * radius * btnDistance + btnCenterX;
            var btny = Math.sin(rotate / 57.2958) * radius * btnDistance + btnCenterY + 50;

            const pStyle = {
                transform: "translate(" + btnx + "px, " + btny + "px)"
            }

            //var distance = getDistanceFromCenter(position, center);
            // if(distance <=  6 && distance >=  -6) {
                return (
                    <div key={position}>
                        <div style={pStyle} className="segment">
                            {position}
                        </div>
                    </div>
                );
            // } //{btnx > 150 && name} replaces {name} to choose by horizontal position
        }

        function getDistanceFromCenter(position, center) {
            var distance = position - center;
            if(distance < -16) {
                distance += 32;
            } else if(distance > 15) {
                distance -= 32;
            }
            return distance;
        }

        const petals = [];
        const exercises = [];
        var addP = 0;
        var subP = 0;

        // Amount to add to each petal.  (pct - distance)/pct 
        // pct should equal half the total distance moved, but isn't
        var pctAdd = 8.5;
        var pctSub = 7.5;

        function makeLeafArray(x, rotatePer, center) {
            var rotate = Petals[x].degree + rotatePer;
            var index = Petals[x].index;
            var position = Petals[x].position;
            var name = Petals[x].name;
            var distance = getDistanceFromCenter(position, center);

            if(name.length > 33) {
                var ellipses = "...";
                name = name.slice(0, 33) + ellipses;
            }

            if(distance > 0 && distance < 16) {
                addP = addP + 360 * 1/32 * (pctAdd - distance)/pctAdd;
                rotate += addP;
                petals.push(putPetal(rotate, index, position));
                exercises.push(putButton(rotate, index, position, name, center));
            } else if (distance < 0 && distance > -16) {
                subP = subP + 360 * 1/32 * (pctSub + distance)/pctSub;
                rotate += subP;
                petals.push(putPetal(rotate, index, position));
                exercises.push(putButton(rotate, index, position, name, center));
            } else {
                petals.push(putPetal(rotate, index, position));
                exercises.push(putButton(rotate, index, position, name, center));
            }
        }

        var start = this.state.center - 1;
        for(var x = start; x < 32; x++) {
            makeLeafArray(x, this.state.rotatePer, this.state.center);
        }
        for(x = 0; x < start; x++) {
            makeLeafArray(x, this.state.rotatePer, this.state.center);
        }

        return (
            <div className="onehundred">
                <div className="circ movedown">
                    {exercises}
                </div>
                <div className="moveup">
                    {petals}
                </div>
                <div key={1} className="moveup">
                    <button className="move_buttons" style={this.getStyle(348.75)} 
                        onClick={(e) => {
                            e.preventDefault(); 
                            this.rotateFlower(-4);
                        }}>
                        ^^
                    </button>
                </div>
                <div key={2} className="moveup">
                    <button className="move_buttons" style={this.getStyle(356.25)} 
                        onClick={(e) => {
                            e.preventDefault(); 
                            this.rotateFlower(-1);
                        }}>
                        ^
                    </button>
                </div>
                <div key={3} className="moveup">
                    <button className="move_buttons" style={this.getStyle(3.75)} 
                        onClick={(e) => {
                            e.preventDefault(); 
                            this.rotateFlower(1);
                        }}>
                        ⌄
                    </button>
                </div>
                <div key={4} className="moveup">
                    <button className="move_buttons" style={this.getStyle(11.25)} 
                        onClick={(e) => {
                            e.preventDefault(); 
                            this.rotateFlower(4);
                        }}>
                        ⌄⌄
                    </button>
                </div>
            </div>
        )
    }
}

class App extends React.Component {
    constructor(props) {
        super(props);
        this.state = {

        }
    }

    render() {
        return (
            <div>
                <div className="bbs">
                    <MakeFlower />
                </div>
            </div>
        )
    }
}

export default App;

标签: javascriptcssreactjs

解决方案


推荐阅读