变换图标动画

时间:2019-06-18 09:05:27

标签: javascript html css

我一直在尝试创建自己的图标转换动画,当菜单关闭时该动画是向右的箭头,而在打开菜单时是一个x。除了它在动画时改变位置的事实外,这似乎是我正在尝试实现的目标。

我希望越来越多的黄线使x也能平滑地动画化,而不是将图标稍微向左或向右移动。

enter image description here

我自己在网上找不到很好的例子,所以决定这么做。我无法为其设置动画,有人可以将我指向正确的方向。

angular.module('app',[])

.controller('mainCtrl', function() {
  var vm = this;
  
  vm.menu = {
    opened: false
  };
  
  vm.toggleMenu = function() {
    vm.menu.opened = !vm.menu.opened;
  }
  
})
.close-x {
  position: relative;
  padding: 0 27px 0 22px;
  height: 30px;
  width: 30px;
  cursor: pointer;
}

.close-x:before, .close-x:after {
  position: absolute;
  content: ' ';
  height: 14px;
  top: 6px;
  width: 2px;
  background-color: #426294;
}
.close-x:before {
  transform: rotate(45deg);
  transition: ease-in-out 0.2s;
}
.close-x:after {
  transform: rotate(-45deg);
  transition: ease-in-out 0.2s;
}

.close-x.arrow-x:before,
.close-x.arrow-x:after {
  height: 8px;
  top: 11px;
  transition: ease-in-out 0.2s;
}
.close-x.arrow-x:after {
  transform: rotate(-45deg) translate(3px,-3px);
  -webkit-transform: rotate(-45deg) translate(3px,-3px);
  transition: ease-in-out 0.2s;
}
<html ng-app="app">
  <head>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.5/angular.min.js"></script>
  </head>
  <body>
    <div ng-controller="mainCtrl as vm">
      <div class="close-x" ng-class="{'arrow-x': !vm.menu.opened}" ng-click="vm.toggleMenu()"></div>
    </div>
  </body>
</html>

2 个答案:

答案 0 :(得分:1)

它之所以会移动是因为您要操纵动画的高度来散发该动画,如果您希望动画是可视的,则绝不能播放尺寸。

这是对背景进行动画处理的解决方案

angular.module('app', []).controller('mainCtrl', function() {var vm = this; vm.menu = {opened: false }; vm.toggleMenu = function() {vm.menu.opened = !vm.menu.opened; } })
body {
  overflow: hidden;
  transform: scale(5);
  padding-left:46%;
  padding-top:20px;
  /* ignore, just to zoom in*/
}

*,
*:before,
*:after {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.close-x {
  position: relative;
  /*   padding: 0 27px 0 22px; */
  height: 30px;
  width: 30px;
  cursor: pointer;
  border:1px solid;
} 

.close-x:before,
.close-x:after {
  position: absolute;
  content: ' ';
  height: 14px;
  top: 6px;
  left: 50%;
  /* instead of padding on the parent*/
  transform: translateX(-50%);
  /* to center horizontally */
  width: 2px;
  background-color: #426294;
  background: linear-gradient(to bottom, #426294, #426294) 0px 0px/100% 100% no-repeat;
}

.close-x:before {
  transform: translateX(-50%) rotate(-135deg);
  transition: ease-in-out 0.2s;
}

.close-x:after {
  transform: translateX(-50%) rotate(-45deg);
  transition: ease-in-out 0.2s;
}

.close-x.arrow-x:before,
.close-x.arrow-x:after {
  background: linear-gradient(to bottom, #426294, #426294) 0px 0px/2px 8px no-repeat;
}
<html ng-app="app">

<head>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.5/angular.min.js"></script>
</head>

<body>
  <div ng-controller="mainCtrl as vm">
    <div class="close-x" ng-class="{'arrow-x': !vm.menu.opened}" ng-click="vm.toggleMenu()"></div>
  </div>
</body>

</html>


编辑:我从头开始制作了一个新书,因为它比修复您自己的书要快,它可以动画显示应该在IE中工作的宽度

div {
  /* height and width can be changed but they have to match*/
  height: 100px;
  width: 100px;
  position: relative;
}

div:before,
div:after {
  content: '';
  position: absolute;
  width: 120%;
  height: 20%;
  transition: width .5s linear;
}

div:before {
  bottom: 0;
  background: orange;
  transform-origin: left top;
  transform: translateY(25%) rotate(-45deg);
}

div:after {
  background: orange;
  transform-origin: left bottom;
  transform: translateY(-25%) rotate(45deg);
}

div:hover:before,
div:hover:after {
  width: 69%;
}
<h1>Hover over it.</h1>
<div></div>

注意::如果您更改厚度(即伪元素的高度),则如果您不了解我的意思,也将调整中间部分的收缩位置。我说尝试改变高度,您会明白的。

答案 1 :(得分:0)

您忘记在没有transition:after选择器的情况下在原始CSS类中设置:before属性:

angular.module('app',[])

.controller('mainCtrl', function() {
  var vm = this;
  
  vm.menu = {
    opened: false
  };
  
  vm.toggleMenu = function() {
    vm.menu.opened = !vm.menu.opened;
  }
  
})
.close-x {
  position: relative;
  padding: 0 27px 0 22px;
  height: 30px;
  width: 30px;
  cursor: pointer;
  transition: ease-in-out 0.2s;
}

.close-x:before, .close-x:after {
  position: absolute;
  content: ' ';
  height: 14px;
  top: 6px;
  width: 2px;
  background-color: #426294;
}
.close-x:before {
  transform: rotate(45deg);
  transition: ease-in-out 0.2s;
}
.close-x:after {
  transform: rotate(-45deg);
  transition: ease-in-out 0.2s;
}

.close-x.arrow-x:before,
.close-x.arrow-x:after {
  height: 8px;
  top: 11px;
  transition: ease-in-out 0.2s;
}
.close-x.arrow-x:after {
  transform: rotate(-45deg) translate(3px,-3px);
  -webkit-transform: rotate(-45deg) translate(3px,-3px);
  transition: ease-in-out 0.2s;
}
<html ng-app="app">
  <head>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.5/angular.min.js"></script>
  </head>
  <body>
    <div ng-controller="mainCtrl as vm">
      <div class="close-x" ng-class="{'arrow-x': !vm.menu.opened}" ng-click="vm.toggleMenu()"></div>
    </div>
  </body>
</html>