动画Bootstrap 4卡到屏幕中心

时间:2018-04-21 08:16:17

标签: javascript jquery html css bootstrap-4

我试图获得以下效果:

  • 将一些bootstrap 4张卡显示为网格
  • 从卡片内部点击button时,它应animate,如下所示: 旋转180度,达到特定的高度/宽度(从400px到350px到整个屏幕),并将自己定位在屏幕中央。

目前,我知道如何使用

进行轮换
rotateY(180deg)

当我点击按钮时:

$('#enlarge').on('click',
    function() {
        $('#kidCard').toggleClass("flipper");
    });

在鳍状肢类中设置了旋转,但是我无法获得剩余的所需动画。 有人可以帮我这个吗?

更新

我当前的HTML:

<div class="flip-container">
    <div class="card text-white bg-primary mb-3 kid-card" id="kidCard">
        <div class="card-header">
            Child name: ...
            <i class="fa fa-trash-o" aria-hidden="true" style="cursor: pointer"></i>
        </div>
        <div class="card-body kid-card-content">
            <div class="kid-card-content-image">
                <img src="~/Content/download.png" width="110" height="110"/>
            </div>
            <div class="kid-card-content-description">
                <p class="card-text">
                    Age: ...
                </p>
                <p class="card-text">
                    Gender: ...
                </p>
                <p class="card-text">
                    Height: ...
                </p>
                <p class="card-text">
                    Weight: ...
                </p>
            </div>
        </div>
        <div class="card-footer">
            <button class="btn btn-secondary" id="enlarge">Edit</button>
        </div>
    </div>
</div>

拥有js文件:

$('#enlarge').on('click',
    function() {
        $('#kidCard').toggleClass("flipper");
    });

现在,这是我的css文件:

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

.flipper {
    transition: 2s;
    transform-style: preserve-3d;
    position: relative;
}

在变换中,我还尝试了translateY(calc(50vh - 50%)) translateX(calc(50vh - 50%)),以便将其放置在屏幕的中央,但它无法正常工作。

SOLUTION:

我终于使用了以下代码(感谢大家的贡献):

.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);
                });
            });

3 个答案:

答案 0 :(得分:1)

我不知道您的具体情况,但如果您能找到使用position: absolute的方法,那么在移动卡片时会更容易。

将div放置在屏幕中央时,重要的是要了解转换时元素的宽度和高度。如果您的用例允许您手动设置这些尺寸然后设置,您只需使用:

left: calc(50% - manuallySetWidth);
top: calc(50% - manuallySetHeight);

但如果您无法手动设置它们,则需要找到备用机制。说实话,我在这里提出的变体是使用a somewhat new addition to CSS的东西(这就是为什么它很可能还有其他更简单的解决方案)和here is apost帮助我开始使用这些。

我评论了解释程序的代码

HIH

&#13;
&#13;
//set these vars to use them in css
$('#kidCard')[0].style.setProperty('--width', $('#kidCard').width()+'px');
$('#kidCard')[0].style.setProperty('--height', $('#kidCard').height()+'px');

$('#enlarge').on('click',
  function() {
    $('#kidCard').toggleClass("flipper");
    $('body').toggleClass("shady");
});
&#13;
body{
  transition: 1s;
}

body.shady{
  background: rgba(0,0,0,.8);
  
}

.flip-container .card {
  left: 0;/*manually set each card's left and top in order for the translation to work smoothly, */
  top: 0;/*if you have them in a grid you could use i and j to do this */
  text-align: center;
  border: 1px solid red;
  transition: 1s;
  position: absolute;
  background: white;
}

.flip-container .card.flipper {
  transform: rotateY(360deg);
  left: calc(50% - var(--width)/2); /*use the variables set in js*/
  top: calc(50% - var(--height)/2);
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="flip-container">
			<div class="card text-white bg-primary mb-3 kid-card" id="kidCard">
				<div class="card-header">
					Child name: ...
					<i class="fa fa-trash-o" aria-hidden="true" style="cursor: pointer"></i>
				</div>
				<div class="card-body kid-card-content">
					<div class="kid-card-content-image">
						<img src="~/Content/download.png" width="110" height="110"/>
					</div>
					<div class="kid-card-content-description">
						<p class="card-text">
							Age: ...
						</p>
						<p class="card-text">
							Gender: ...
						</p>
						<p class="card-text">
							Height: ...
						</p>
						<p class="card-text">
							Weight: ...
						</p>
					</div>
				</div>
				<div class="card-footer">
					<button class="btn btn-secondary" id="enlarge">Edit</button>
				</div>
			</div>
		</div>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

一种可能的方法是在你的鳍状肢类上设置width,然后将边距设置为自动。设置width值和margin:auto将使块级元素居中。

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

.flipper {
    transition: 2s;
    margin: auto;
    width:400px;
    height:400px;
    transform-style: preserve-3d;
    position: relative;
}

Here is a fiddle

或者如果你更喜欢这样的弹性盒解决方案:

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

.flipper {
    transition: 2s;
    transform-style: preserve-3d;
    position: relative;
    width:400px;
    height:400px;
}

.body-flipper {
  display:flex;
  justify-content: center;
}

body, html{
  width:100% !important;
  height: 100% !important;
  margin:0;
}

Here is a fiddle

答案 2 :(得分:0)

在我看来,要达到这样的效果,CSS动画是不够的。最简单的方法是将定位更改为固定,将卡放在中间并根据需要进行缩放。看看DEMO

当然这只是一个例子,只有一张牌,但它应该适用于不同位置的多张牌。在点击卡上:

  1. 旋转180度(虽然我不明白为什么是180),
  2. 移至视口中心,
  3. 更改尺寸以填充所有视口,
  4. 动画可以双向运作。

    HTML:

    <div class="flip-container">
        <div class="card text-white bg-primary mb-3 kid-card" id="kidCard">
            <div class="card-header">
                Child name: ...
                <i class="fa fa-trash-o" aria-hidden="true" style="cursor: pointer"></i>
            </div>
            <div class="card-body kid-card-content">
                <div class="kid-card-content-image">
                    <img src="~/Content/download.png" width="110" height="110"/>
                </div>
                <div class="kid-card-content-description">
                    <p class="card-text">
                        Age: ...
                    </p>
                    <p class="card-text">
                        Gender: ...
                    </p>
                    <p class="card-text">
                        Height: ...
                    </p>
                    <p class="card-text">
                        Weight: ...
                    </p>
                </div>
            </div>
            <div class="card-footer">
                <button class="btn btn-secondary" id="enlarge">Edit</button>
            </div>
        </div>
    </div>
    

    CSS:

    .flip-container {
      width: 400px;
    }
    
    .flip-container .flipper {
        transform: rotateY(180deg);
    }
    
    .card {
      transition-duration: 2s;
    }
    
    .movement {
      transform: translate(-50%,-50%) rotateY(180deg);
    }
    

    JS:

    var element = $('#kidCard');
    var w = element.width();
    var h = element.height();
    
    $('#enlarge').on('click',
      function() {
        if(element.hasClass('movement')) {
          element.removeClass('movement');
          element.css({width: w, height: h, top: 0, left: 0});
        } else {
          var left = element.offset().left;
          var top = element.offset().top;
          element.css({position: 'fixed', left: left, top: top, width: w, height: h});
          element.addClass('movement');
          element.css({width: '100vw', height: '100vh', top: '50%', left: '50%'});
       }
    });