css3+js动画

css3+js动画

非css的方法:js定时器 flash

能用css3就不要用js,能用requestAnimation就不用定时器

变形 transform

变形:改变元素的样式

提供的变形的效果,能用transform改变样式的就不要用其他传统方式,尤其是动画中,因为动画要求的是流畅度

scale一般不考虑缩放的问题

要搞清楚方向的问题,平面往下是正方向

transfrom:移动、缩放、旋转、斜切_xqiitan的博客-CSDN博客

translate相当于脱离文档流;会在一个新的平面;

css对于脱离了文档流的都是不同的处理,每种都是特殊的情况

伪元素选择器 - 百度文库

transform自己去看,好多细节知识点 transform-origin tyle:2d 等等

变形不是动画,变形只是改变盒子的样式;

动画是在一定时间内慢慢去改变它的样式

过渡动画 transition

给元素设置一个过渡效果,当元素的样式发生改变不是立即改变,而是按照效果来发生改变

transition-timing-function: ease-in 加速、ease-out 减速、ease-in-out 先减速再减速、

扩展的一个小样式:

-webkit-filter: grayscale(1)

transitiond的效果,之前样式是a,现在样式是b,那么我从a到b的一个动画效果,项目中不是特别强大;

transition只能是a-b,但是如果我现在a-b,b-c,c-d,实现一个相对来说比较复杂的轨迹运动

帧(轨迹)动画 animation

事件制作好运动轨迹,即每一帧元素的样式

animation:

animation-name

// 和transition是一样的

animation-iteration-count: 播放次数,默认1次,infinite

animation-fill-mode: 控制运动状态。

沿着轨迹开始走,animation走到末尾的时候会立马蹦回第1帧的位置

+forwards

+backwards

扩展一个强大公共的动画库:animation.css

npm init animate.css

  1. 使用 class="animated heartBeat infinite"

  2. 把公式粘进来自己改也行

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>title</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        body{
            height: 10000px;
        }
        @keyframes run {
            0%,100%{
                transform: translate(0,0);
            }
            25%{
                transform: translate(300px,0);
            }
            50%{
                transform: translate(300px,300px);
            }
            75%{
                transform: translate(0,300px);
            }
        }
        .run{
            animation: run 2s linear 0s infinite;
        }
    </style>
</head>
<body>
    <img class="run" src="./lesson.jpg" alt="" data-src="./lesson.jpg" width="220" height="394" loading="lazy">
    <script>
    </script>
</body>
</html>


浏览器中同步和异步

  • 翻牌

  • 钟摆

  • 西游记

笔记链接到这个文档

js的同步和异步&promise基础部分

js定时器动画

2种方式:

限定步长

限定时间

  1. 限定步长

思路分析:

从最左边运动到最右边

  1. 首先帧(轨迹)动画不好实现,因为不知道最右边的样式(屏宽是动态的);

  2. 使用transition

  3. 定时器动画,每一步向右10px 5px

最右边的left值:一屏幕的宽度 - 盒子的宽度

改变left或者transform:translate(translateX,0)。开启硬件加速性能更好

限定步长:

只要能知道目标和步长,设置interval定时器累加步长,在当前样式上累加步长,但是一定要有边界判断加上步长边界判断,超过了就直接走到边界

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>title</title>
    <style>
        *{
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        body{
            height: 10000px;
        }
        img{
            border: 10px solid red;
            width: 300px;
            position: absolute;
            left: 0px;
            top: 0px;
        }


    </style>
</head>
<body>
    <img class="run" src="./bg.jpg" alt="" loading="lazy">
    <script>
        let img=document.querySelector('.run');
        let offsetWidth=img.offsetWidth;
        let clientWidth=document.body.clientWidth;
        let end=clientWidth-offsetWidth;
        let left=0;
        let step=10;
        let timer=window.setInterval(()=>{
            left+=step;
            // 先判一下未来的,如果下一步会超过,则不加。
            if(left>=end){
                // 如果超出了手动回归终点
                img.style.left=(clientWidth-offsetWidth)+'px';
                window.clearInterval(timer);
                timer=null;
                return;
            }
            img.style.left=left+'px';
        },20)
    </script>
</body>
</html>


  1. 限定时间

限定步长:无法把控好准确的时间的

限定时间的匀速运动

引出了公式的概念

T:time 已经运动的时间

B:begin 开始位置

C:change 总距离 = Target-Begin

D:duration 总时间

curDistance=T/D*C+B

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>title</title>
    <style>
        *{
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        body{
            height: 10000px;
        }
        img{
            border: 10px solid red;
            width: 300px;
            position: absolute;
            left: 0px;
            top: 0px;
        }


    </style>
</head>
<body>
    <img class="run" src="./bg.jpg" alt="" loading="lazy">
    <script>
        let img=document.querySelector('.run');
        let offsetWidth=img.offsetWidth;
        let clientWidth=document.body.clientWidth;
        // 目标位置
        let target=clientWidth-offsetWidth;
        // 起始位置
        let begin=img.offsetLeft;
        // 总距离
        let change=target-begin;
        // 总时间
        let duration=1000;
        let time=0;
        let timer=window.setInterval(()=>{
            time+=20;
            let curLeft=time/duration*change+begin;
            if(time>=duration){
                img.style.left=target+'px';
                window.clearInterval(timer);
                timer=null;
            }
            img.style.left=curLeft+'px';
        },20)
    </script>
</body>
</html>


requestAnimationFrame

几个概念:

屏幕刷新频率

……

定时器:定时器改的时候屏幕没改,你不刷新的时候屏幕改了

深入理解 RequestAnimationFrame_aiguangyuan的博客-CSDN博客_requestanimationframe执行时机

requestAnimationFrame一般用于固定步长的动画

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>title</title>
    <style>
        *{
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        body{
            height: 10000px;
        }
        img{
            border: 10px solid red;
            width: 300px;
            position: absolute;
            left: 0px;
            top: 0px;
        }


    </style>
</head>
<body>
    <img class="run" src="./bg.jpg" alt="" loading="lazy">
    <script>
        let img=document.querySelector('.run');
        let offsetWidth=img.offsetWidth;
        let clientWidth=document.body.clientWidth;
        let end=clientWidth-offsetWidth;
        let left=img.offsetLeft;
        let step=10;
        function render() {
            left+=step;
            // 先判一下未来的,如果下一步会超过,则不加。
            if(left>=end){
                // 如果超出了手动回归终点
                img.style.left=(clientWidth-offsetWidth)+'px';
                return;
            }
            img.style.left=left+'px';
            // 2.回调末尾再加上window.requestAnimationFrame实现递归
            window.requestAnimationFrame(render)
        }
        // 1.render就是之前执行的回调
        window.requestAnimationFrame(render)
    </script>
</body>
</html>


jQuery动画库

如果要加上y方向上的运动:

用css3是最简单的,管你改什么值,只要样式改变了,就会有过渡效果

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>title</title>
    <style>
        *{
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        html,body{
            height: 100%;
        }
        .run{
            width: 300px;
            height: 178px;
            position: absolute;
            left: 0px;
            top: 0px;
            background: #0b2e13;
        }
        .run img{
            width: 100%;
            height:100%;
            display: block;
        }


    </style>
</head>
<body>
    <div class="run"><img src="./bg.jpg" alt="" loading="lazy"></div>


    <script>
        let img=document.querySelector('.run');
        let offsetWidth=img.offsetWidth;
        let clientWidth=document.documentElement.clientWidth;
        // 目标位置
        let target=clientWidth-offsetWidth;
        let targetY=document.documentElement.clientHeight-img.offsetHeight;
        // 起始位置
        let begin=img.offsetLeft;
        let beginY=img.offsetTop;
        // 总距离
        let change=target-begin;
        let changeY=targetY-beginY;
        // 总时间
        let duration=1000;
        let time=0;
        let timer=window.setInterval(()=>{
            time+=20;
            let curLeft=time/duration*change+begin;
            let curTop=time/duration*changeY+beginY;
            if(time>=duration){
                img.style.left=target+'px';
                img.style.top=(targetY)+'px';
                window.clearInterval(timer);
                timer=null;
                return;
            }
            img.style.left=curLeft+'px';
            img.style.top=curTop+'px';
        },20)
    </script>
</body>
</html>


简易封装多方向

再加一个样式的方向,宽度也跟着变,透明度、颜色……

你告诉我目标值,目标值指定几个方向,分别求出begin change,

t b c d

t:是实时的时间,不需要外界给的

b:begin 我们自己根据元素的样式求得

c:change=target-begin

这2个是一组的,是跟target有关的

d:总时长,是需要外部调用者传入的

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>title</title>
    <style>
        *{
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        html,body{
            height: 100%;
        }
        .run{
            width: 300px;
            height: 178px;
            position: absolute;
            left: 0px;
            top: 0px;
            background: #0b2e13;
        }
        .run img{
            width: 100%;
            height:100%;
            display: block;
        }


    </style>
</head>
<body>
    <div class="run"><img src="./bg.jpg" alt="" loading="lazy"></div>


    <script>
        let img=document.querySelector('.run');
        let offsetWidth=img.offsetWidth;
        let clientWidth=document.documentElement.clientWidth;
        // 目标位置
        let target=clientWidth-offsetWidth;
        let targetY=document.documentElement.clientHeight-img.offsetHeight;
        // 总时间
        let duration=1000;
        let time=0;


        /**
         * t b c d
         * t:是实时的时间,不需要外界给的
         *
         * b:begin 我们自己根据元素的样式求得
         * c:change=target-begin
         * 这2个是一组的,是跟target有关的
         *
         * d:总时长,是需要外部调用者传入的
         *
         */
        // 封装
        function animation(elem,target={},duration,callback){
            // 初始化time begin change
            let time=0,begin={},change={};
            for(let key in target){
                if(target.hasOwnProperty(key)){
                    begin[key]=parseFloat(window.getComputedStyle(elem)[key]);
                    change[key]=target[key]-begin[key];
                }
            }
            let timer=window.setInterval(()=>{
                time+=20;
                if(time>=duration){
                    window.clearInterval(timer);
                    timer=null;
                    for(let key in target){
                        if(target.hasOwnProperty(key)){
                            elem.style[key]=target[key]+'px';
                        }
                    }
                    // callback && callback()
                    if(typeof callback ==='function'){
                        callback()
                    }
                    return;
                }
                for(let key in target){
                    if(target.hasOwnProperty(key)){
                        let cur=time/duration*change[key]+begin[key];
                        elem.style[key]=cur+'px';
                    }
                }
            },20)


        }
        animation(img,{left:target,top:targetY},duration,()=>{
            img.style.transform='rotate(180deg)';
        })


    </script>
</body>
</html>


jQuery

stop和finish的区别:

stop:结束当前动画

finish:瞬间到当前动画的结束位置。会出现跳跃不建议

快捷用法

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值