Robert
Robert

Reputation: 303

Flipped card doesnt hold the back div on second animate

I have a card that has the following animation: When you click on "Edit" button:

After it gets to the center of the div and the rotation is done, the card expands to full screen (after which I redirect the user). My problem is that after the second animation (actually when all animations are done) only then the back content is visible, in rest, when it's doing the rotate and translate, it's just the front content flipped visible (see JSFIDDLE down) My code looks like:

Html:

<div class="cards-holder">
    <div class="card bg-light mb-3 item" style="display: none">
        <div class="front face">
        <div class="card-header kid-card-header">
            <div class="kid-card-header-name">
                <label>Child name:&nbsp;</label>
                <label>Kevin </label>
            </div>
            <div class="kid-card-header-delete-button">
                <i class="fa fa-trash-o deleteChild" aria-hidden="true" style="cursor: pointer" idOfChild="23"></i>
            </div>
        </div>
        <div class="card-body">
            <div class="kid-card-content">
                <div class="kid-card-content-image">
                    //some image
                </div>
                <div class="kid-card-content-description">
                    <p class="card-text">
                        <label>Age: </label>
                        <label>2 years</label>
                    </p>
                    <p class="card-text">
                        <label>Gender: </label>
                        <label>Male</label>
                    </p>
                    <p class="card-text">
                        <label>Height: </label>
                        <label>50 cm</label>
                    </p>
                    <p class="card-text">
                        <label>Weight: </label>
                        <label>25 kg</label>
                    </p>
                </div>
                </div>
            </div>
            <div class="card-footer kid-card-footer">
                <button class="btn btn-secondary editChildButton" ChildId="23">Edit</button>
            </div>
        </div>
        <div class="back face">
        </div>
    </div>
</div>

CSS:

.card {
    transform-style: preserve-3d;
}

.face {
    position: absolute;
    width: 100%;
    height: 100%;
    backface-visibility: hidden;
}

    .face.back {
        display: block;
        transform: rotateY(180deg);
        background-color: #78C2AD;
    }

and JS:

$.fn.toggleZindex= function() {
    const $this = $(this);
    if($this.css("z-index")=="auto") {
        $this.css("z-index", "99999");
    }else {
        $this.css("z-index", "auto");
    }

    return this;
};

$.fn.animateRotate = function(angle, duration, easing, startingDegree, complete) {
    var args = $.speed(duration, easing, complete);
    var step = args.step;
    return this.each(function(i, e) {
        args.complete = $.proxy(args.complete, e);
        args.step = function(now) {
            $.style(e, 'transform', 'rotateY(' + now + 'deg)');
            if (step) return step.apply(e, arguments);
        };

        $({ deg: startingDegree}).animate({deg: angle}, args);
    });
};

function getRotationDegrees(obj) {
    const matrix = obj.css("-webkit-transform") ||
        obj.css("-moz-transform")    ||
        obj.css("-ms-transform")     ||
        obj.css("-o-transform")      ||
        obj.css("transform");
    if(matrix !== 'none') {
        const values = matrix.split('(')[1].split(')')[0].split(',');
        const a = values[0];
        const b = values[1];
        var angle = Math.round(Math.atan2(b, a) * (180/Math.PI));
    } else { var angle = 0; }
    return (angle < 0) ? angle + 360 : angle;
}

$('.editChildButton').on('click',
    function () {
        const idOfChild = $(this).attr('ChildId');
        const tc = $(window).height() / 2 - $('.item').height() / 2 - $(this.closest('.item')).offset().top;
        const lc = $(window).width() / 2 - $('.item').width() / 2 - $(this.closest('.item')).offset().left;

        $(this.closest('.item')).toggleZindex();

        const startingDegree = getRotationDegrees($(this.closest('.item')));

        $(this.closest('.item')).animateRotate(startingDegree == 0 ? 180 : 0, 2000, 'swing', startingDegree);

        $(this.closest('.item')).animate({
            left: lc,
            top: tc
        }, 2000, function () {
            $(this.closest('.item'))
                .css({
                    position: 'fixed', left: $(this.closest('.item')).offset().left, top:
                        $(this.closest('.item')).offset().top
                });
            $(this.closest('.item')).animate({
                left: 0,
                top: 0,
                width: '100vw',
                height: '100vh'
            }, 2000, function() {
                window.location =
                    "/Children/EditChild?childId=" + idOfChild;
            });
        });
    });

Demonstration of my problem JSFIDDLE

Basically, what I actually need is, from the moment the card rotated 180deg (from the first animation), only the blank green back is visible while doing the second animation. Also, at the end of all this, I need to redirect to another page, so I need to know when everything is done.

I updated the JDFIDDLE to show the actual positioning of my cards.

Upvotes: 1

Views: 237

Answers (1)

Rence
Rence

Reputation: 2950

You can solve this issue (and save a lot of performance) by replacing your JS animation with a CSS animation.

See this for reference: https://jsfiddle.net/g9wb4rwp/

$('.editChildButton').on('click',  function () {       
    $('.flip-container').addClass('flip');       
});
/* entire container, keeps perspective */
.flip-container {
	perspective: 1000px;
}

.flip-container.flip .flipper {
    transform: rotateY(180deg);
}

.front, .back {
	width: 100%;
	height: 480px;
}

/* flip speed goes here */
.flipper {
	transition: 0.6s;
	transform-style: preserve-3d;
	position: relative;
}

/* hide back of pane during swap */
.front, .back {
	backface-visibility: hidden;
	position: absolute;
	top: 0;
	left: 0;
}

/* front pane, placed above back */
.front {
	z-index: 2;
	/* for firefox 31 */
	transform: rotateY(0deg);
}

/* back, initially hidden pane */
.back {
	transform: rotateY(180deg);
    background: green;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.0/js/bootstrap.min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" rel="stylesheet"/>
<div class="flip-container">
	<div class="flipper">
		<div class="front">
		<div class="card-header kid-card-header">
        <div class="kid-card-header-name">
          <label>Child name:&nbsp;</label>
          <label>Kevin</label>
        </div>
        <div class="kid-card-header-delete-button">
          <i class="fa fa-trash-o deleteChild" aria-hidden="true" style="cursor: pointer" idOfChild="23"></i>
        </div>
      </div>
      <div class="card-body">
        <div class="kid-card-content">
          <div class="kid-card-content-image">
          </div>
          <div class="kid-card-content-description">
            <p class="card-text">
              <label>Age: </label>
              <label>2 years</label>
            </p>
            <p class="card-text">
              <label>Gender: </label>
              <label>Male</label>
            </p>
            <p class="card-text">
              <label>Height: </label>
              <label>50 cm</label>
            </p>
            <p class="card-text">
              <label>Weight: </label>
              <label>25 kg</label>
            </p>
          </div>
        </div>
      </div>
      <div class="card-footer kid-card-footer">
        <button class="btn btn-secondary editChildButton" ChildId="23">Edit</button>
      </div>
		</div>
		<div class="back">
			Back
		</div>
	</div>
</div>

Get end of css animation:

myselector.one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend',  { 
    // code to execute after transition ends  
});

Upvotes: 1

Related Questions