同时在父母和子女div中实现平滑的规模转换

时间:2017-07-28 15:30:59

标签: css css-transitions css-transforms easing

我正在尝试缩放div并使其子项看起来像父级缩放时保持在同一位置。为了实现它,我正在缩放父母和孩子:

        Children-scale  Parent-scale
start   2               0.5           -> 2 * 0.5 = 1
middle  1.5             0.75          -> 1.5 * 0.75 = 1.125 [It should be 1]
end     1               1             -> 1

从演示中可以看出,初始值和最终值是正确的,但不是中间体。起初我认为它可能是缓动功能,但是分配线性(恒定速度)没有任何区别。可能分配一个inverse easing可以做到,但我问是否有一种非数学方法来实现这一点(因为我对bezier曲线没有信心)。

如何使用变换比例属性实现平滑过渡?

var $div = $('div');

$div.on('click', function() {

    $div.toggleClass('scaled');

});
div {
    width: 100%;
    height: 200px;
    overflow:hidden;
}
img {
    width: auto;
    height: 100%;
}
div, img {
    transition: transform 1s linear;/* Other easing function make no difference */
	/* transform-origin:left top; Makes no difference */
}
div.scaled {
	transform:scaleY(0.5);
}
div.scaled img {
	transform:scaleY(2);/* 1 / 0.5 */
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span>Click the image</span>
<div><img src="http://i.imgur.com/sbyPaAsl.jpg" alt=""></div>

JSFiddle

修改

使用CSS动画并为每个x%分配正确的值,我得到了一些接近但仍然不完美的东西。 (这也需要事先知道比例值或以其他方式创建动画并使用JavaScript进行分配。)

var $div = $('div');

$div.on('click', function() {

    $div.toggleClass('scaled');

});
div {
    width: 100%;
    height: 200px;
	overflow:hidden;
}
img {
    width: auto;
    height: 100%;
}
div.scaled {
    animation: ddiv 1s linear;
}
div.scaled img {
    animation: iimg 1s linear;
}
@keyframes iimg {
    0% {transform:scaleY(2);}
    20% {transform:scaleY(1.8);}
    40% {transform:scaleY(1.6);}
    60% {transform:scaleY(1.4);}
    80% {transform:scaleY(1.2);}
    100% {transform:scaleY(1);}
}
@keyframes ddiv {
    0% {transform:scaleY(0.5);}
    20% {transform:scaleY(0.555);}/* 1 / 1.8 */
    40% {transform:scaleY(0.625);}/* 1 / 1.6 */
    60% {transform:scaleY(0.714);}/* 1 / 1.4 */
    80% {transform:scaleY(0.833);}/* 1 / 1.2 */
    100% {transform:scaleY(1);}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span>Click the image</span>
<div><img src="http://i.imgur.com/sbyPaAsl.jpg" alt=""></div>

3 个答案:

答案 0 :(得分:0)

使用pseudoelements的方法是否适合您?

这是一个想法:

var $div = $('div');

$div.on('click', function() {

  $div.toggleClass('scaled');

});
div {
  width: 100%;
  height: 200px;
  overflow: hidden;
  position: relative;
}

img {
  width: auto;
  height: 100%;
}

div:after,
div:before {
  content: '';
  position: absolute;
  height: 0;
  width: 100%;
  display: block;
  background: white;
}

div:before {
  top: 0;
}

div:after {
  bottom: 0;
}

div.scaled:after,
div.scaled:before {
  transition: height 1s linear;
}

div.scaled:after,
div.scaled:before {
  height: 50px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span>Click the image</span>
<div><img src="http://i.imgur.com/sbyPaAsl.jpg" alt=""></div>

答案 1 :(得分:0)

我正在发布问题的答案,因为我通过测试接近期望结果的值找到了贝塞尔曲线;但如果有人有更好的方法,我仍然愿意接受其他答案。

该功能为1/x。向上扩展元素需要线性缓动,缩小元素需要cubic-bezier(.25,.48,.52,.75)(它不是精确的曲线)。这样,子元素看起来几乎不会缩放。

JSFiddle

var $div = $('div');

$div.on('click', function() {

    $div.toggleClass('scaled');

});
div {
    width: 100%;
    height: 200px;
	overflow:hidden;
}
img {
    width: auto;
    height: 100%;
}
div {
    transition: transform 1s linear;
}
img {
    transition: transform 1s cubic-bezier(.25,.48,.52,.75);
}
div.scaled {
    transition: transform 1s cubic-bezier(.25,.48,.52,.75);
	transform:scaleY(0.5);
}
div.scaled img {
    transition: transform 1s linear;
	transform:scaleY(2);/* 1 / 0.5 */
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div><img src="http://i.imgur.com/sbyPaAsl.jpg" alt=""></div>

答案 2 :(得分:0)

我不知道它对你的情况是否有用:

但如果你不需要在容器中隐藏溢出物,那么让它和孩子旋转可以给你一个可能性:

&#13;
&#13;
var $div = $('div');

$div.on('click', function() {

    $div.toggleClass('scaled');

});
&#13;
div {
    width: 100%;
    height: 200px;
    border: solid 1px green;
}
img {
    width: auto;
    height: 50%;
    top: 25%;
}
div, img {
  transition: transform 1s linear;
  transform-style: preserve-3d;
  position: relative;
}
div.scaled {
	transform: rotateX(60deg);
}
div.scaled img {
	transform: rotateX(-60deg);
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span>Click the image</span>
<div><img src="http://i.imgur.com/sbyPaAsl.jpg" alt=""></div>
&#13;
&#13;
&#13;