>  기사  >  웹 프론트엔드  >  단일 DOM 요소에 애니메이션을 추가하는 방법에 대한 자세한 예

단일 DOM 요소에 애니메이션을 추가하는 방법에 대한 자세한 예

WBOY
WBOY앞으로
2022-08-05 14:40:022440검색

이 글은 애니메이션 효과를 추가하기 위한 DOM 요소 운영과 관련된 문제를 주로 소개하는 javascript에 대한 관련 지식을 제공합니다. 모두에게 도움이 되기를 바랍니다.

단일 DOM 요소에 애니메이션을 추가하는 방법에 대한 자세한 예

관련 권장 사항 :

자바 스크립트 비디오 자습서,

web front-end
  1. Dom 애니메이션 효과 요소는 왼쪽에서 오른쪽으로 이동하여 움직임의 왼쪽에서 오른쪽으로 이동합니다.
    <div id="box"></div>

이동의 세 가지 요소

t = setInterval(function(){终止条件})

시작점

  • 이동의 시작점은 실제로 API를 통해 현재 요소의 위치를 ​​얻고 이 위치를 제공합니다. 운동의 시작으로.

Target

  • Speed

  • 모션의 기본 원리

  • 타이머를 통해 요소가 CSS 속성 값을 타이머를 통해 짧은 간격으로 ​​​​변경하게 하세요

이러한 연속적인 모션이 사용자에게 나타나는 애니메이션 효과

  • DOM 애니메이션 효과 캡슐화
  • 캡슐화의 주요 기능은 요소가 짧은 시간 간격으로 속성을 지속적으로 변경하여 애니메이션 효과를 얻을 수 있도록 하는 것입니다.

단일 속성 모션 프레임워크:

    var box = document.getElementById("box");
    var t = null;
    t = setInterval(function(){
        
    })

균일 모션 캡슐화

    // 元素的属性值 === 目标点
    if(dom.attr === target){
        clearInterval(t);
    }
    투명도 대응
<button id="btn">开始运动</button>
<div id="box"></div>
<div id="line"></div>
<script>
    var  box = document.getElementById("box");
    var  btn = document.getElementById("btn");
    var  target = 500;
    // 速度可以根据 起始点和目标点进行判断,从而决定正负; 
    var speed  = 17;
    // - 方向; 
    btn.onclick = function(){
        // 1. 获取元素初始位置;
        var _left = box.offsetLeft;
        speed  = target - _left >= 0 ? speed : -speed ;
        var interval = setInterval( function(){
            // 4. 判定运动的终止条件; 
            if(Math.abs(target - _left) <= Math.abs(speed) ){
                // 因为终止时有可能没有到达目标点,因此我们把元素赋值到目标点位置; 
                box.style.left = target + "px";
                clearInterval( interval );
            }else{
                // 2. 元素根据初始位置进行改变; 
                _left += speed;
                // 3. DOM操作,根据已有数据让元素属性发生改变; 
                box.style.left = _left + "px";
            }
        } , 30)
    }
    </script>
    버퍼링 동작
  • 버퍼링 동작은 동작 방식입니다
    이런 동작은 동작 중에 속도가 변하는 동작입니다
    • 거리가 작을수록 작아집니다 the speed
    <script>// - 提取属性名作为参数; btn.onclick = function(){
        animate( "left", 500 )}function animate( attr , target , speed = 10 ){
        // 1. 获取元素初始样式
        var _style = getComputedStyle( box );
        // 2. 根据属性要求取出当前的属性的属性值; 
        var _css_style = parseInt(_style[attr]);
        speed  = target - _css_style >= 0 ? speed : -speed ;
        var interval = setInterval( function(){
            // 4. 判定运动的终止条件; 
            if(Math.abs(target - _css_style) <= Math.abs(speed) ){
                // 因为终止时有可能没有到达目标点,因此我们把元素赋值到目标点位置; 
                box.style[attr] = target + "px";
                clearInterval( interval );
            }else{
                // 2. 元素根据初始位置进行改变; 
                _css_style += speed;
                // 3. DOM操作,根据已有数据让元素属性发生改变; 
                box.style[attr] = _css_style + "px";
            }
        } , 30)}</script>
  • 다중 속성 모션 프레임워크(확장)
다중 속성 모션 프레임워크

animate를 여러 번 호출하면 타이머가 여러 개 열립니다

    타이머의 데이터가 동일하기 때문에, 효과를 볼 수 없습니다
  • 하지만 타이머를 여러 번 켜면 컴퓨터 성능이 극도로 소모됩니다
  • 현재 타이머를 켜기 전에 이전 타이머를 닫으세요
<script>function animate( dom , attr , target , speed = 10 ){
    // 1. 获取元素初始样式
    var _style = getComputedStyle( dom );
    // 2. 根据属性要求取出当前的属性的属性值; 
    if( attr === "opacity"){
        var _css_style = parseInt(_style[attr] * 100 );
        target *= 100;
    }else{
        var _css_style = parseInt(_style[attr]);
    }
    speed  = target - _css_style >= 0 ? speed : -speed ;
    var interval = setInterval( function(){
        // 4. 判定运动的终止条件; 
        if(Math.abs(target - _css_style) <= Math.abs(speed) ){
            // 因为终止时有可能没有到达目标点,因此我们把元素赋值到目标点位置; 
            if( attr === "opacity"){
                dom.style[attr] = target / 100;
            }else{
                dom.style[attr] = target + "px";
            }
            clearInterval( interval );
        }else{
            // 2. 元素根据初始位置进行改变; 
            _css_style += speed;
            // 3. DOM操作,根据已有数据让元素属性发生改变; 
            if( attr === "opacity"){
                dom.style[attr] = _css_style / 100 ;
            }else{
                dom.style[attr] = _css_style + "px";
            }
        }
    } , 30)}</script>
  • 회전형 차트 기능 구현
  • <button id="btn">开始运动</button>
    <div id="box"></div>
    <script>
    var  box = document.getElementById("box");
    var  btn = document.getElementById("btn");
    btn.onclick = function(){
        animate( box , "left" , 500 )
    }
    function animate( dom , attr , target , transition = "buffer", speed = 10 ){
        var _style = getComputedStyle( dom );
        if( attr === "opacity"){
            var _css_style = parseInt(_style[attr] * 100 );
            target *= 100;
        }else{
            var _css_style = parseInt(_style[attr]);
        }     
          
        if( transition === "liner"){
            speed  = target - _css_style >= 0 ? speed : -speed ;
        }
          
        var interval = setInterval( function(){
            if( transition === "buffer"){
                // 计算速度; 
                speed = (target - _css_style) / 10;
                //速度不取整在小数部分会做很多无意义的计算; 
                speed = speed > 0 ? Math.ceil(speed) :Math.floor( speed )
            }
    
            if(Math.abs(target - _css_style) <= Math.abs(speed) ){
                // 因为终止时有可能没有到达目标点,因此我们把元素赋值到目标点位置; 
                if( attr === "opacity"){
                    dom.style[attr] = target / 100;
                }else{
                    dom.style[attr] = target + "px";
                }
                    clearInterval( interval );
            }else{
                // 2. 元素根据初始位置进行改变; 
                _css_style += speed;
                // 3. DOM操作,根据已有数据让元素属性发生改变; 
                if( attr === "opacity"){
                    dom.style[attr] = _css_style / 100 ;
                }else{
                    dom.style[attr] = _css_style + "px";
                }
            }
        } , 30)
    }     
    </script>
    //只需要改变里面transition的值就可以调整运动模式
    //buffer为缓冲运动
    //liner为匀速运动
    <script>// 在一个定时器之中,用for循环同时执行多次dom样式操作; // 1. 需要优化的部分:参数,要把样式部分的参数优化成一个对象; function animate( dom , attrs , transition = "buffer", speed = 10 ){
        var _style = getComputedStyle( dom );
        // 获取元素当前的属性 : 
        for(var attr in attrs ){
            // attr ? 要过渡的css属性名;
            // attrs[attr] ? 要过渡的当前属性; 
            attrs[attr] = {
                target : attrs[attr],
                // 元素当前的属性放入到这个对象之中; 
                now  : parseInt(_style[attr])
            }
        }
        // 因为直接关闭interval是没有作用的,此时的inteval是一个局部变量,每次animate被调用的时候都会直接重置; 
        // 我们应该吧定时器的id放在当前正在执行过渡效果的dom对象上; 
        clearInterval(dom.interval);
        dom.interval = setInterval( function(){
            for(var attr in attrs){
            // 取出 attrs 之中的目标点和当前值; 
                speed = (attrs[attr].target -  attrs[attr].now) / 10 ;                    
                // 根据速度正负,进行速度取整; 
                speed = speed > 0 ? Math.ceil( speed ) : Math.floor( speed );
                // 判定终止条件; 
                if( attrs[attr].target ===  attrs[attr].now){
                    // 删除已经到达目标点的属性; 
                    delete attrs[attr]
                    // 判定attrs里面已经没有属性了; 
                    for(var a in attrs){
                        return false;
                    }
                    clearInterval(dom.interval);
                }else{
                    attrs[attr].now += speed;
                    dom.style[ attr ] = attrs[attr].now + "px";
                }
            }
        } , 30)}// 优化参数之后,key值是等待运动的css属性,value值是元素的目标; btn.onclick = function(){
        animate( box , { width : 500 , height : 400 } )}</script>
  • 예제는 다음과 같습니다

    프로젝트 배경: Uniapp h5 애플리케이션, 사용자에게 다운로드를 요청하는 DOM은 원래 각 탭바(총 4개)에 추가하고 싶었지만 다른 방법을 시도하고 싶습니다.

    효과는 다음과 같습니다

    : 코드로 직접 이동:

     <style>
                *{
                      margin: 0;
                      padding: 0;
                }
                .container{
                      width: 1130px;
                      height: 286px;
                      margin: 0 auto;
                      position: relative;
                      overflow: hidden;
                }
                .wrapper{
                      width: 6780px;
                      position: absolute;
                      left: 0;
                }
                .slide{
                      float: left;
                }
    
                .slide , .slide img{
                      width: 1130px;
                      height: 286px;
                }
                .button-prev{
                      left: 0;
                      background-position: 30px center;
                      background-image: url(https://static.zcool.cn/git_z/z/widget/slider/images/svg/left_arrow.svg?v=2);
                      top: 0;
                      width: 13px;
                      height: 100%;
                      padding: 0 80px;
                      border-radius: 2px;
                      position: absolute;
                      background-repeat: no-repeat;
                }
                .button-prev:hover{
                      background-image: url(https://static.zcool.cn/git_z/z/widget/slider/images/svg/left_arrowhover.svg?v=2);
                }
                .button-next{
                      right: 0;
                      background-position: 91px center;
                      background-image: url(https://static.zcool.cn/git_z/z/widget/slider/images/svg/right_arrow.svg?v=2);
                      top: 0;
                      width: 13px;
                      height: 100%;
                      padding: 0 80px;
                      border-radius: 2px;
                      position: absolute;
                      background-repeat: no-repeat;
                }
                .button-next:hover{
                      background-image: url(https://static.zcool.cn/git_z/z/widget/slider/images/svg/right_arrowhover.svg?v=2);
                }
                .pagination{
                      position: absolute;
                      bottom: 10%;
                      width: 100%;
                      height: 10px;
                      left: 30px;
                }
                .pagination span{
                      display: inline-block;
                      width: 10px;
                      height: 10px;
                      margin-left: 10px;
                      border-radius: 50%;                  
                      background-color: cornflowerblue;
                      border: 2px solid transparent;
                      background-clip: content-box;
                }
                .pagination span.active{
                      border: 2px solid skyblue;
                      box-shadow: 0 0 5px skyblue;
                      background-color: #fff;
                }
          </style>

    코드를 통해 노드를 생성하면 코드는 스타일과 애니메이션이 됩니다. ;

    js 설정 변환 애니메이션에 대해; 이 가장자리가 3D 형식으로 변경되었습니다

    <!-- 类名请使用和我一样的类名 -->
    <div class="container">
        <div class="wrapper">
              <!-- 第0张图片 -->
              <div class="slide">
                    <img src="https://img.zcool.cn/ad_manager/location/f35d611484931101c43350bbdbd5.jpg" alt="">
              </div>
              <div class="slide">
                    <img src="https://img.zcool.cn/ad_manager/location/3dcb6113a3471101c433505bbd72.jpg" alt="">
              </div>
              <div class="slide">
                    <img src="https://img.zcool.cn/ad_manager/location/65f36113a3341101c4335014b174.jpg" alt="">
              </div>
              <div class="slide">
                    <img src="https://img.zcool.cn/ad_manager/location/7f97611481181101c43350225b33.jpg" alt="">
              </div>
              <div class="slide">
                    <img src="https://img.zcool.cn/ad_manager/location/afcf6114801e1101c433507f9e28.jpg" alt="">
              </div>
              <!-- 最后一张图片 -->
              <!-- 把第0张图片放在整个图片结构的最后 -->
              <div class="slide">
                    <img src="https://img.zcool.cn/ad_manager/location/f35d611484931101c43350bbdbd5.jpg" alt="">
              </div>
        </div>
        <div class="button-next"></div>
        <div class="button-prev"></div>
        <div class="pagination">
              <span class="active"></span>
              <span></span>
              <span></span>
              <span></span>
              <span></span>
        </div>
    </div>
    
    <script src="./utils.js"></script>
    <script>
        // 轮播图的核心就是左右切换按钮,实现显示元素下标的改变; 
        var index = 0 ; 
        var prev = 0;
    
        var next_btn = document.querySelector(".button-next");
        var prev_btn = document.querySelector(".button-prev");
        var slides   = document.querySelectorAll(".slide");
        var wrapper  = document.querySelector(".wrapper");
        // 自动播放的阻止功能是在鼠标移入container容器之中就触发的; 
        var container   = document.querySelector(".container");
    
        var bullets = document.querySelectorAll(".pagination span");
    
        // 绑定事件 
        // - 轮播图改变下标功能必须设置边界; 
        function bindEvent(){
              next_btn.onclick = function(){
                    add();
                    bannerAnimate();
              }
              prev_btn.onclick = function(){
                    reduce()
                    bannerAnimate();
              }
              container.onmouseover = function(){
                    stop();
              }
              container.onmouseout = function(){
                    autoPlay();
              }
    
              bullets.forEach( function( ele , i ){
    
                    ele.onmouseover = function(){
                          prev = index;
                          // 防止穿帮逻辑; 
                          // - 如果在假的第0张图片上(在最后一张图片上)
                          // - 我们先让真假图片呼喊然后在进行元素的动画效果; 
                          if( index === 5 ){
                                wrapper.style.left = 0;
                          }
                          index = i;
                          bannerAnimate();
                    }
              })
        }
        // 下标增加;
        function add(){
              
              prev = index;
    
              if( index === slides.length - 1 ){
                    // 这个逻辑会在最后一张图片进行切换时进入; 
                    // 我们让wrapper直接位移到开头,改变元素位置的同时让用户无法感知; 
                    wrapper.style.left = 0;
                    // 我们需要从第0个图片切换到第一个图片;
                    // -因为我们最后一张图片的显示和开头图片的显示是一样的
                    index = 1;
              }else{
                    index ++;
              }
        }
        // 下标减少; 
        function reduce(){
              prev = index;
    
              if( index === 0 ){
                    wrapper.style.left = -(slides.length - 1) * 1130 + "px";
                    index = slides.length - 2;
              }else{
                    index --;
              }
        }
        // 根据我们的算法去实现动画效果;
        function bannerAnimate(){
              animate( wrapper , { left : - index * 1130 });
    
              // 给对应的分页器按钮添加active; 
    
              // 先去清空所有的类名; 
    
              bullets.forEach( function( ele ){
                    ele.classList.remove("active")
              })
    
              // 下标需要进行特殊处理,在显示最后一张图片的时候,给第0个按钮添加active; 
    
              bullets[ index === 5 ? 0 : index ].classList.add("active");
        }
        bindEvent();
    
        var interval = null;
        function autoPlay(){
              // 间隔3s,让js点击一下下一页按钮; 
              interval = setInterval( function(){
                    // 虚拟点击 : 
                    next_btn.dispatchEvent( new Event("click"));
              } , 3000 )
        }
    
        function stop(){
              clearInterval( interval )
        }
    
        autoPlay();
    
    </script>
    [관련 권장사항:
    javascript 비디오 튜토리얼

    , 웹 프론트엔드

    ]

    위 내용은 단일 DOM 요소에 애니메이션을 추가하는 방법에 대한 자세한 예의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

  • 성명:
    이 기사는 csdn.net에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제