Элемент CSS Transition в плавной анимации flexbox и из нее - PullRequest
0 голосов
/ 03 ноября 2018

Я создаю базовую навигацию для веб-сайта, и графические / анимированные функции, которые мне бы хотелось, это:

1: в состоянии «HOME» логотип / значок сайта большой и центрирован, а над остальными ссылками навигации / страницы.

2: На любой другой странице, кроме домашней, логотип / значок меньше и пропорционально размещается в горизонтальном гибком боксе с другими элементами.

3: между этими двумя состояниями происходит плавный переход.

Я реализовал это уже, как вы можете видеть ниже, но переход происходит нервно, когда страница в натуральную величину. Я новичок как в CSS, так и в Angular, поэтому заранее прости мое невежество.

Мой вопрос:

Есть ли лучший способ реализовать анимацию flex-box in / out-out, чем я здесь предоставил, и / или есть ли оптимизация CSS-анимации, которой мне не хватает для дальнейшего сглаживания этого перехода?

Конечный продукт будет иметь одинаковый цвет фона, но я выбрал яркие цвета на этой иллюстрации, чтобы показать, что div делают на заднем плане.

Примечание: я пытался использовать 'will-change', но безрезультатно, и я знаю, что могу сделать это без использования angular, но помимо этой простой анимации есть функции, которые будут использовать angular в будущем.

Вот и скрипка для этого тоже: https://jsfiddle.net/willcthomson/f6wk4Lpq/

/* angular */ 
function mainCtrl($scope) { 

  		$scope.ng_div_home = 'div_home_scale_up';
      $scope.ng_div_logo = 'div_logo_scale_up';
      $scope.ng_div_logo_upper_container = 'div_logo_upper_container_scale_up';
      $scope.ng_logo = '';
      $scope.ng_ISHOME = true;

  		$scope.f_scale = function()
  				{
            if(!$scope.ng_ISHOME)
              {
              $scope.ng_div_home = "div_home_scale_down";
              $scope.ng_div_logo = "div_logo_scale_down";
              $scope.ng_div_logo_upper_container = 'div_logo_upper_container_scale_down';
              }
            else
              {
              $scope.ng_div_home = "div_home_scale_up";
              $scope.ng_div_logo = "div_logo_scale_up";
              $scope.ng_div_logo_upper_container = 'div_logo_upper_container_scale_up';
              }
            console.log("ishome is:"+$scope.ng_ISHOME);
  				};


}
/* css */
html{
  position: relative;
  min-height: 100%;
  background-color: #222222;
  }

body{
  background-color: #00000000;
  }


/*a container that sits on top of the nav bar and grows vertically to make room fo the expanding logo-icon*/
.div_logo_upper_container 
  {
    /* background-color: #111111; */
    background-color: magenta;
    width: 80%;
    margin: auto;
    transition: height .5s linear;
    margin-top: 5vw;
  }

/*a flex container to hold nav elements*/
.nav_container 
  {
    /* background-color: #111111; */
    background-color: yellow;
    width: 80%;
    
    margin: auto;
    display: flex;    
    
    align-items: stretch;
    align-items: flex-end;
 
  }
  

/*a div that scales forcing the other flex elements respond */
.div_home
    {
      background-color: #00000000;
      background-color: cyan;
      margin: auto;
      transition: .5s linear;
      will-change: transform, width, flex,;
    }

/*a div that holds the logo, and does the actual scaling and movement*/
.div_logo    
    {
      padding: 3px;
      margin: 3px;
      margin-left: 2vw;
      transition:  .5s linear;
      will-change: width;
    }

.img_logo   
    {
    max-width:100%;
    max-height: 100%;
    min-width: 8%;
    min-height: 8%;
    will-change:width;
    will-change:height;
    }

/*expands the home container amongst the other flex elements to make room for incoming logo*/
.div_home_scale_down
  {
    width: 10vw;
    flex: .5 1 40px;
  }    

/*shrinks the home container to allow flex elements to expand into the created gap*/
.div_home_scale_up
  {
    width: 3px;
    transform: translate(25vw,-10vh);
    align-self: center;
  }    

/*expands the logo container*/
.div_logo_scale_up
  {
    width: 30vw;
    margin-top: 5vh;
  }

/*shrinks the logo container*/
.div_logo_scale_down
  {
    margin: 1vh;
    width: 10vw;  
    position: static;

  }

/*expands the area above the nav container to contain the larger icon*/
.div_logo_upper_container_scale_up
  {
    height: 10vh;
  }  

/*shrinks the upper container as the icon files in with other elements  */
.div_logo_upper_container_scale_down
  {
    height: 1px;
  }  

.nav_items
    {
    flex: 1 1 10px;
    margin-bottom: 2vh;

    font-family: verdana;
    font-size: 30px;
    color:grey;
    text-align: center;
    margin: 3px;
    transition: font-size, color, transform, .5s linear;
    }  
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<!--html-->
<div ng-app>
<div ng-controller="mainCtrl">

<div class="div_logo_upper_container" ng_class="ng_div_logo_upper_container"></div>
<div class="nav_container">
    <div class = "div_home" ng-class="ng_div_home">
      <div class = "div_logo" ng-class="ng_div_logo" ng-click="ng_ISHOME=true;f_scale();">
        <img  class = "img_logo" src="https://avatars1.githubusercontent.com/u/579414?s=200&v=4" > 
      </div>
    </div>
  	<div  class = "nav_items">  	
  		<p ng-click="ng_ISHOME=false;f_scale();">Two</p>
  	</div>
  	<div class = "nav_items">
  		<p ng-click="ng_ISHOME=false;f_scale();">Three</p>
  	</div>
  	<div class = "nav_items">
  		<p ng-click="ng_ISHOME=false;f_scale();">Four</p>
  	</div>
    
  </div> <!-- end nav_container -->
  </div> <!-- end ctrl -->
  </div> <!-- end app -->

ASDF

1 Ответ

0 голосов
/ 03 ноября 2018

Анимация "дрожит", потому что вы анимируете слишком много свойств одновременно, и они влияют не только на слои Paint и Composite.

Если вы находите вышеприведенное утверждение расплывчатым, обратитесь к этим двум статьям:

Общепринятым решением для этого типа анимации является наличие одного элемента в DOM для каждого из двух состояний анимации. Они оба должны быть расположены (подойдет любое значение position, отличное от static). Вы будете использовать transform, чтобы анимировать элемент начального состояния в направлении позиции и размера элемента целевого состояния. Получив .getBoundingClientRect () для каждого, вы можете определить необходимые преобразования, необходимые для точного перехода).

Безусловно, самое большое преимущество этого метода состоит в том, что анимируемый элемент остается в той же позиции в потоке документов и, не изменяя размер или перемещаясь, он не вызывает перекомпоновку для последующих элементов DOM или родительских элементов. Только его визуализированная проекция перемещается.

Как только анимация заканчивается, вы переключаете visibility обоих элементов и удаляете transform s из только что анимированного (теперь скрытого - вы хотите установить animation-duration:0s; для этого изменения), чтобы сбросить визуализированный проекция обратно на свое обычное место в DOM.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...