过渡,变换与动画

 


过渡transition

  通常,我们的css样式是静态的,也就是说css中定义的属性就是页面渲染后的最终呈现效果。但发生像为某个元素设置:hover伪类并且此时改变一些属性(鼠标悬停在该元素时样式生效),或者使用JavaScript修改页面的某些元素的style这类操作,如果我们为该元素的一个或多个css属性中设置了过渡,那么当它们发生改变时,它会由初始值相对缓慢地变成新值,而不是直接变成新值,其中过渡的中间效果由浏览器实现。简写属性transition依次接收四个参数:

  • transition-property:需要进行过渡的属性。可以设置为关键字all,表示所有过渡能生效的属性都进行过渡;
  • transition-duration:过渡持续的时间;
  • transition-timing-function:定时函数,控制过渡过程中变化率如何加速或减速;
  • transition-delay:延迟时间,表示经过指定时间后过渡才开始生效;

 

 一个过渡高度值的菜单

代码实现:

复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .dropdown_toggle{
            display: block;
            padding: 0.5em 1em;
            border: 1px solid hsl(280,10%,80%);
            color: hsl(280,30%,60%);
            background-color: white;
            text-decoration: none;
            transition: background-color 0.2s linear;
        }
        .dropdown_toggle:hover{
            background-color: hsl(280,15%,95%);
        }
        .dropdown_drawer{
            position: absolute;
            background-color: white;
            width: 150px;
            height: 0;  /*关闭状态下高度为0,且溢出部分隐藏*/
            overflow: hidden;
            transition: height 1s ease-out;  /*为高度添加过渡属性*/
            text-align: center;
        }
        .dropdown.is-open .dropdown_drawer{ /*打开状态时的高度由内容确定*/
            height: auto; 
        }
        .menu{
            padding-left: 0;
            margin: 0;
            list-style: none;
        }
        .menu >li+li >a{
            border-top: 0;
        }
        .menu>li>a{
            display: block;
            padding: 0.5em 1em;
            color: hsl(280,40%,60%);
            background-color: white;
            text-decoration: none;
            transition: all .2s linear;
            border: 1px solid hsl(280,10%,80%);
        }
        .menu>li>a:hover{
            background-color: hsl(280,15%,95%);
            color: hsl(280,25%,10%);
        }
    </style>
</head>
<body>
    <div class="dropdown" aria-haspopup="true">
        <button class="dropdown_toggle" style="width: 150px">Menu</button>
        <div class="dropdown_drawer">
            <ul class="menu" role="menu">
                <li role="menuitem">
                    <a href="/features">Features</a>
                </li>
                <li role="menuitem">
                    <a href="/pricing">Pricing</a>
                </li>
                <li role="menuitem">
                    <a href="/support">Support</a>
                </li>
                <li role="menuitem">
                    <a href="/about">About</a>
                </li>
            </ul>
        </div>
    </div>

</body>

<script type="text/javascript">
    (function (){
       var toggle = document.getElementsByClassName('dropdown_toggle')[0];
       var dropdown = toggle.parentElement;
       var drawer = document.getElementsByClassName('dropdown_drawer')[0];
       var height = drawer.scrollHeight 

       toggle.addEventListener('click',function (e){
           e.preventDefault();
           dropdown.classList.toggle('is-open');  //点击后,为.dropdown添加.is-open类,表示菜单打开状态
           if(dropdown.classList.contains('is-open')){
               drawer.style.setProperty('height',height+'px');//打开状态时精确设置高度值
           }else {
               drawer.style.setProperty('height','0')//关闭状态时高度设置为0,可以实现关闭时的滑动效果
           }
       });
    }());
</script>
</html>
复制代码

   我们想让用户在点击菜单时,菜单项滑动打开,也即高度由0过渡到菜单项内容占据的高度。但由于并不清楚菜单项容器的高度是多少,一开始我想让高度值由0过渡到auto,但发现过渡不生效。因此,使用JavaScript获取容器的scrollHeight属性值,来计算容器的高度,然后在菜单被点击时修改.is-open状态下容器的高度,这样就能使高度由0过渡到确切值。

 

变换transform

  使用transform可以改变元素的形状和位置,其中包括二维或三维的平移、旋转、缩放和倾斜。通常结合过渡或动画一起使用。它有如下变换规则:

  • rotate(angle):元素绕一个轴心转动一定角度,值为<angle>deg;在2D空间上rotate()相当于rotateZ(),也即绕Z轴旋转;
  • translate(x,[y,[z):元素沿着x轴、y轴和z轴分别移动,值为长度或百分比;
  • scale(sx,xy):缩小或放大元素,可以为不同方向设置不同的缩放值。当需要进行3D空间上的缩放时必须使用Scale3D();
  • skew(sx,xy):倾斜元素,参数分别指定x轴与y轴方向上的倾斜量

 

  通常,元素的变换是基于元素中心的,我们可以使用transform-origin属性来更改变换的基点。

 

坐标系

  坐标系会随着元素的变换进行改变,因此要注意使用多重变换时,每次变换的参考坐标系是怎样的。正常的3D视角下,坐标系中的Z轴正方向指向屏幕外的我们。

  

 

 

 

 

3D变换

  首先要理解“透视距离”,可以把透视距离想象成摄像机与物体之间的距离,镜头越近(透视距离越小),3D效果越强。下面是不同透视距离的效果,可以看到虚线连接的交点处与摄像机的距离便是“透视距离”。

 

 

 

 

   默认情况下,透视距离的渲染是假设镜头在元素中心的正前方,可以通过修改perspective-origin属性来上下左右移动镜头的位置。

 

实现一个简单的3D立方体

代码实现:

复制代码
<!DOCTYPE html>
<html>
<head>
  <title>一个简单的3D立方体</title>
  <style>
    .container
    {
      margin: 0 auto;
      width: 400px;
      height:400px;
      background:#d8d8d8;
      border: 4px solid rgba(255, 0, 0, 0.9);
      border-radius: 10%;
    }
    .cube
    {
      position: relative;
      width: 200px;
      height: 200px;
      margin: 100px auto;
      transform-style:preserve-3d;
      perspective: 800px;
      perspective-origin: -50% -100px;  /*修改透视角度,使更好地观察图像*/
    }
    .cube div
    {
      position: absolute;
      width: 200px;  /*初始状态时,立方体的六个面都重叠在一起,此时的位置就是它们的初始位置*/
      height: 200px;
      background: rgba(255,255,255,0.1);
      box-shadow: inset 0 0 30px rgba(125,125,125,0.8);
      text-align: center;
      line-height: 200px;
      font-weight:bold;
      text-shadow:-1px 1px 5px #f60;
      color:#fff;
      font-family: sans-serif;
      text-transform: uppercase;
      font-size:30px;
    }
    .front
    {
      transform: translateZ(100px); /*front面向屏幕方向前进100px*/
    }
    .back
    {
      transform: translateZ(-100px) rotateY(180deg); /*back面先后退100px,再沿Y轴旋转180度(也即向下旋转一周进行翻面)*/
    }
    .left
    {
      transform:rotateY(270deg) translateX(-100px); 
      transform-origin:  left; /*先以正方形的左边为基点,绕Y轴旋转270度,此时坐标轴改变,X轴正向指向屏幕外,然后沿X轴负方向移动100px*/
    }
    .right
    {
      transform:rotateY(-270deg) translateX(100px);
      transform-origin:right; /*先以正方形的右边为基点,绕Y轴负方向旋转270度(正向90度),此时X轴正向指向屏幕里,然后沿X轴正向移动100px*/
    }
    .top
    {
      transform:rotateX(90deg) translateY(-100px);
      transform-origin: top;
    }
    .bottom
    {
      transform:rotateX(90deg) translateY(100px);
      transform-origin: bottom;
    }
  </style>
</head>
<body>
<div class="container">
  <div class="cube">
    <div class="front">front</div>
    <div class="back">back</div>
    <div class="top">top</div>
    <div class="bottom">bottom</div>
    <div class="left">left</div>
    <div class="right">right</div>
  </div>
</div>
</body>
</html>
复制代码

 

动画animation

  CSS中的动画由两部分组成——用来定义动画关键帧的@keyframes规则以及为元素添加动画的animation属性。从原理上看,过渡和关键帧动画类似:过渡是定义了第一帧(起始点)和最后一帧(结束点),由浏览器计算中间过程的值,使元素实现平滑变换;而关键帧动画则不局限于起始点和结束点,在中间过程我们可以添加自己想要的值,从而生成一系列无缝衔接的过渡。

  简写的animation属性包含以下几个属性:

animation-name:动画的名称,该名称需要放在@keyframes规则后面进行指定;

animation-duration:动画持续的时间;

animation-timing-function:与transition属性一样,是定时函数;

animation-iteration-count:动画的重复次数,默认值为1

 

 

实现一个加载动画

复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .loading{
            width: 150px;
            height: 15px;
            margin: 100px auto 0;
        }
        .loading span{
            display: inline-block;
            width: 15px;
            height: 100%;
            margin-right: 5px;
            border-radius: 50%;
            background-color: lightgreen;
            animation: load 1.04s ease infinite;
        }
        .loading span:last-child{
            margin-right: 0;
        }
        @keyframes load {
            0%{
                opacity: 1;
            }
            100%{
                opacity: 0;
            }
        }
        .loading span:nth-child(1){
            animation-delay: 0.13s;
        }
        .loading span:nth-child(2){
            animation-delay: 0.26s;
        }
        .loading span:nth-child(3){
            animation-delay: 0.39s;
        }
        .loading span:nth-child(4){
            animation-delay: 0.52s;
        }
        .loading span:nth-child(5){
            animation-delay: 0.65s;
        }
    </style>
</head>
<body>
<div class="loading">
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
</div>
</body>
</html>
复制代码

 

posted @   ˙鲨鱼辣椒ゝ  阅读(66)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
点击右上角即可分享
微信分享提示