将transform-origin移回CSS中元素的中心

sol*_*yon 9 html javascript css animation css-transforms

当CSS元素从原始位置转换出来时,它们transform-origin不会随之移动; 使所有后续的变换和旋转仍然源于它的原始transform-origin(下面的例子).

我知道有一种解决方法...那就是继续将所有新变换添加到前一个变换的右侧.像这样:transform: translateY ( -5rem ) rotate( 45deg ) translateY( -10rem ) rotate( 15deg )...等等.这似乎总是根据需要从当前元素的中心开始新的变换.

问题

当您使用此技术基于用户输入转换元素时,您将继续向DOM添加转换......无休止地.占用大量内存并导致其他不需要的滑动效果(可能).

这是一个动画,显示transform-origin每次转换后如何不移动到元素的中心:

'use strict';

function firstRotation() { 
  var v = document.getElementById( 'v-wrp' ),
      status = document.getElementById( 'status' )
      
  setTimeout( function() { 
    status.innerHTML = 'First, the V is rotated around it\'s central axis.\
                          The <b>transform-origin</b> is centered.';
    
    v.classList.add( 'first-rotation' );
    status.classList.add( 'update' );
  }, 1000 ); 
}

function firstTranslation() { 
  var v = document.getElementById( 'v-wrp' ),
      status = document.getElementById( 'status' )
      
  setTimeout( function() { 
    status.innerHTML = 'Next, the element is translated forward in it\'s \
                        current orientation. The <b>transform-origin</b> stays\
                        behind where it was.';
                        
    v.classList.remove( 'first-rotation' );
    v.classList.add( 'first-translation' );
  }, 6000 ); 
}

function info() { 
  var v = document.getElementById( 'v-wrp' ),
      status = document.getElementById( 'status' )
      
  setTimeout( function() { 
    status.innerHTML = 'This next animation is where it\'s evident that\
                        the <b>transform-origin</b> is no longer centered, but\
                        back where it was at the beginning of these transforms';
    
  }, 11000 ); 
}

function lastRotation() { 
  var v = document.getElementById( 'v-wrp' ),
      status = document.getElementById( 'status' )
      
  setTimeout( function() { 
    status.innerHTML = 'This last rotation is far wider than desired because the\
                        transform origin is back where it started.'
  
    v.classList.remove( 'first-translation' );
    v.classList.add( 'last-rotation' );
  }, 16000 ); 
}

function end() { 
  var v = document.getElementById( 'v-wrp' ),
      status = document.getElementById( 'status' )
      
  setTimeout( function() { 
    status.classList.remove( 'update' );
  }, 21000 ); 
}

function start() {
  firstRotation();
  firstTranslation();
  info();
  lastRotation();
  end();
}

start();
Run Code Online (Sandbox Code Playgroud)
/* / / / / / / / / / / / / / ANIMATION DEFINITIONS / / / / / / / / / / / / / */
.first-rotation, .first-translation, .update, .last-rotation {
  animation-duration: 5s;
  animation-timing-function: ease-in-out;
  animation-fill-mode: forwards;
}
.first-rotation {
  animation-name: first-rotation;
}
.first-translation {
  animation-name: first-translation;
}
.update {
  animation-name: update;
  animation-iteration-count: infinite;
}
.last-rotation {
  animation-name: last-rotation;
}

/*/ / / / / / / / / / / / / / ANIMATION KEYFRAMES / / / / / / / / / / / / / /*/
@keyframes first-rotation {
  100% {
    transform: rotate( 315deg );
  }
}
@keyframes first-translation {
  0% {
    transform: rotate( 315deg );
  }
  100% {
    transform: rotate( 315deg ) translate( 0, -5rem );
  }
}
@keyframes update {
  0% {
    background-color: mediumslateblue;
  }
}
@keyframes last-rotation {
  0% {
    transform: rotate( 315deg ) translate( 0, -5rem );
  }
  100% {
    transform: rotate( 400deg ) translate( 0, -5rem );
  }
}
Run Code Online (Sandbox Code Playgroud)
<head>
  <style>
    @import url( "https://fonts.googleapis.com/css?family=Nunito" );

    html {
      overflow: hidden;
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100%;
      font-family: "Nunito", sans-serif;
    }

    html,
    body {
      margin: 0;
      padding: 0;
    }

    .v {
      display: block;
      font-size: 2rem;
      transform: rotate( 180deg );
    }

    p {
      width: 100%;
      padding: 0.5rem;
      position: absolute;
      bottom: 0;
      left: 0;
    }
  </style>
</head>
<body>
  <div id="v-wrp" class="v-wrp">
    <b class="v">V</b>
  </div>
  
  <p id="status" class="status"></p>
</body>
Run Code Online (Sandbox Code Playgroud)

这个问题

我需要在CSS或JS中找到一种方法来重置它的位置transform-origin或将其移回到变换元素的中心.向右添加更多变换是一种在实时交互式环境中不适合我的技术.尝试在这里可以看到:变换加入...不休.

我怎样才能计算变换元素的位置并将其移transform-origin回到它的中心?或者我如何获取多个变换值并将它们压缩成一个值,使元素保持在同一位置?

小智 0

您还可以使用topleft来翻译#v-wrp. 并且您可以在属性中创建动画transform-origin。在元素中尝试一下<b>。我希望它现在就能发挥作用。