【问题标题】:Achieve a smooth scale transition in parent and children div simultaneously在父子div中同时实现平滑的缩放过渡
【发布时间】:2017-08-03 01:27:08
【问题描述】:

我正在尝试缩放 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 可以做到这一点,但我想问是否有非数学方法来实现这一点(因为我对贝塞尔曲线没有信心)。

如何使用 transform scale 属性实现平滑过渡?

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>

【问题讨论】:

    标签: css css-transitions css-transforms easing


    【解决方案1】:

    使用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>

    【讨论】:

    • 感谢您的回答。这是一种非常聪明的方式,但恐怕不适用于该场景。有背景内容(在这种转换发生时实际上正在改变),这就是我使用overflow: hidden;的原因。
    • 我明白了。图片也可以作为背景内容添加吗?
    • 您的意思是 div 的背景图像而不是
    • 是的,背景图片
    • 嗯,图像需要在过渡后出现,但我认为隐藏它没有问题,并在过渡发生时将其应用为 div 的background-image
    【解决方案2】:

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

    函数是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>

    【讨论】:

      【解决方案3】:

      不知道对你的情况有没有用:

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

      var $div = $('div');
      
      $div.on('click', function() {
      
          $div.toggleClass('scaled');
      
      });
      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);
      }
      <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>

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-09-14
        • 1970-01-01
        • 2019-12-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-18
        • 2013-07-07
        相关资源
        最近更新 更多