• 【前端】移动互联动画


    一、CSS动画

    (一)2D动画

    CSS的2D转换
    CSS 转换(transforms):可以移动、旋转、缩放和倾斜元素。
    平移 translate()
    translate()方法是将元素从当前位置开始平移
    第一个参数 水平平移量 右为正方向
    第二个参数 竖直平移量 下为正方向

    transform: translate(-50px, -50px);
    transform: translateX(300px);
    transform: translateY(200px);
    transform: translateZ(50px);//translateZ:电脑屏幕向外移动
    
    • 1
    • 2
    • 3
    • 4

    旋转 rotate()
    参数:可以是角度值 (deg) 也可以是弧度值 (rad) 弧度制的PI = 180°
    沿轴进行顺时针旋转为正方向,0°代表竖直向上
    负数的含义其实就是 360 - 对应度数
    默认旋转函数rotate 是沿着z轴进行旋转
    缩放 sacle()
    参数:比率 1 为原本大小
    scale 写负数代表反向:
    倾斜 skew()

    transform: skew(30deg);
    transform: skew(0deg, 30deg);
    transform: skewX(30deg);
    transform: skewY(30deg);
    
    • 1
    • 2
    • 3
    • 4

    matrix() 方法
    matrix() 方法把所有 2D 变换方法组合为一个。
    matrix() 方法可接受六个参数,其中包括数学函数,这些参数使您可以旋转、缩放、移动(平移)和倾斜元素。
    参数如下:matrix(scaleX(),skewY(),skewX(),scaleY(),translateX(),translateY())

    div {
      transform: matrix(1, -0.3, 0, 1, 0, 0);
    }
    
    • 1
    • 2
    • 3

    transform也可以直接同时赋值多个值

    .box {
        width: 200px;
    	height: 200px;
        background-color: red;
        transform: translateX(100px) rotate(45deg) scale(0.5);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    变化原点
    设置transform的原点
    原点的位置会影响旋转的圆心,缩放的位置
    待选值: top bottom left right center 还可以填入像素值
    第一个参数代表水平偏移量 第二个参数代表竖直偏移量

    transform-origin: right center; 
    transform-origin: center bottom; 
    
    • 1
    • 2

    当值为像素值的时候,像素值的参考位置是元素的左上角

    transform-origin: 20px 70px;
    
    • 1

    (二)transition过渡动画

    过渡名称
    还有两个待选项
    ​ none: 无
    ​ all: 所有属性都能播放过渡动画

    transition-property: left, transform;
    transition-property: all;
    
    • 1
    • 2

    过渡时长
    动画播放的时长

    transition-duration: 2s;
    
    • 1

    过渡速度
    动画播放的速度曲线
    待选项
    ​ linear: 匀速直线运动
    ​ ease-in: 慢进
    ​ ease-out: 慢出
    ​ ease-in-out: 慢进慢出
    ​ cubic-bezier: 曲线函数

    transition-timing-function: linear;
    
    • 1

    过渡延迟

    transition-delay: 3s;
    
    • 1

    合成所有属性
    语法:transition: property duration timing-function delay;

    transition: all 3s linear 3s;
    
    • 1

    (三)animation动画

    动画帧序列

    @keyframes move{
    	//起始帧
    	from{
            transfrom:translateX(0px);
    	}
    	//可以用百分比来代表动画的中间状态
    	50%{
            transfrom:translateX(600px)
    	}
    	//结束帧
    	to{
            transform:translateX(300px);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    动画属性
    动画animation必须包含,名称和时长两个属性,才会进行播放

    以下属性可以和transition一起记忆

    • 动画名称:animation-name:move;
    • 动画播放时长:animation-duration:3s;
    • 动画播放的速度曲线:animation-timing-function:linear;
    • 动画延迟:animation-delay:3s;

    以下属性为animation独有的属性

    • 动画迭代次数:animation-iteration-count:1; //infinite 无限次
    • 动画播放方向:animation-direction:normal;
      normal:顺向播放
      reverse:反向播放
      alternate:来回播放
      alternate-reverse:反向来回播放
    • 动画填充模式:animation-fill-mode:forwords
      ​ forwards:保留结束帧的状态
      ​ backwards:保留起始帧的状态
      ​ both:保留初始和结束时的值
    • 动画播放和暂停状态:animation-play-state:
      pause:暂停
      running:继续

    复合属性

    • 官方顺序
      duration | name
      animation:2s move;
      duration | timing-function | delay | name
      animation:2s linear 3s move;
      duration | timing-function | delay | iteration-count | direction | fill-mode | play-state | name
      animation:
    • 一般顺序(参考transition)
      animation:move 3s linear 3s forwards
      动画播放和暂停
      动画播放和暂停状态:animation-play-state:
      pause:暂停
      running:继续
    	btn.addEventListener('click', () => {
            box.style.animation = 'move 1s linear forwards infinite alternate running'
        })
        btn2.addEventListener('click', () => {
            // animationPlayState 动画播放状态
            // paused 暂停
            // running 播放
    
            if (box.style.animationPlayState === 'paused') {
                box.style.animationPlayState = 'running'
            } else {
                box.style.animationPlayState = 'paused'
            }
        })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    (四)3D动画

    创建一个场景
    搭建3d场景,在父元素上设置:transform-style: preserve-3d;
    设置透视距离

    perspective: 300px;
    
    • 1

    若三维场景中不添加 perspective 则三维场景是一个正交视图
    设置透视原点

    perspective-origin: center center;
    
    • 1

    透视原点(灭点所在的坐标)
    原点为 0 值时,所在位置是scene的左上角:perspective-origin: 0 0;
    在场景里添加子元素

        
        
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在子元素上使用3d变换

    transform: rotateY(65deg);
    
    • 1

    二、jQuery

    (一)基础用法

    (1)网页中的使用

    
    
        
        
        
        
        
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    (2)jQuery使用方法

    1.查询并存储元素
    2.操作元素,包括修改元素样式,绑定事件等

    使用$()函数获取一个jQuery对象
    jQuery对象的变量名,一般以$开头

    let $box=$('.box')
    
    • 1

    jQuery对象看上去像一个数组,其中数组成员就是dom对象

    console.log($box)
    
    • 1

    给元素修改样式

    $box.css('height','100px')
    $box.css('background-color','#f00')
    
    • 1
    • 2

    jQuery对象的函数总是返回自己

    所以可以进行链式调用

    $box.css('height','100px')
    	.css('background-color','#f00')
    	.css('color','#f0f')
    	.text('hello word')
    
    • 1
    • 2
    • 3
    • 4

    (二)eq和get方法

    (1)eq()方法

    eq 读取对应索引位置的jQuery对象

    let $li=$lis.eq(1)
    
    • 1

    因为$li是jQuery对象,所以可以直接使用jQuery操作它

    $li.css('color','#f00')
    
    • 1

    (2)get()方法

    get 读取对应索引位置的dom对象

    let li = $lis.get(2)
    li.style.color = '#f00'
    
    • 1
    • 2

    使用 [] 方括号的方式去获取索引对应的 dom 对象

    其结果等价于 get 函数获取的结果

    let li = $lis[2]
    li.style.color = '#f00'
    
    • 1
    • 2

    (三)事件

    (1)使用事件属性

    绑定事件
    和dom对象绑定事件进行类比

        // 对应 jquery 的写法如下
        $btn.click(ev => {
            console.log('click');
            // ev 是jquery封装的事件对象
            console.log(ev);
        })
    
        // 再例如
        $btn.mousemove(ev => {
            console.log('mousemove');
        })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    触发事件

        // 可以直接使用事件对应的函数去触发事件,例如:
        $btn.click()
        $btn.mousemove()
    
    • 1
    • 2
    • 3

    (2)使用事件监听器

    绑定事件

        const handler = ev => {
            console.log(ev);
            console.log(1);
        }
    
        // 绑定事件
        $btn.on('click', handler)
    
        $btn.on('mousemove', ev => {
            console.log(ev);
            console.log(2);
        })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    绑定一次性事件

        // 绑定一次性事件
        $btn.one('click', ev => {
            console.log(ev);
            console.log('one');
        })
    
    • 1
    • 2
    • 3
    • 4
    • 5

    (3)解绑事件

        // 解绑指定事件处理程序
        //$btn.off('click', handler)
    
        // 解绑所有事件处理程序
        $btn.off('click')
    
    • 1
    • 2
    • 3
    • 4
    • 5

    三、canvas画布

    (一)基础简介

    (1)创建canvas标签

    
    
    • 1

    (2)给canvas标签设置 width height 属性

    //width height 属性可以设置画布的像素大小
    //width="800" 就意味着画布水平有800个真实像素
    
    
    • 1
    • 2
    • 3
    canvas {
        border: 3px solid #000;
        /*样式的宽高也可以设置canvas标签的大小,但不是真实的像素值而是拉伸后的大小*/
        width: 800px;
        height: 600px;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    (3)通过js获取canvas标签

    const canvas = document.querySelector('canvas')
    
    • 1

    (4)通过canvas标签获取context画布上下文(画布对象)

    const ctx = canvas.getContext('2d')
    
    • 1

    (5)通过context绘制画布

    //绘制一个实心矩形
    ctx.fillRect(100, 50, 100, 100)
    
    • 1
    • 2

    颜色修改
    fillStyle 可以修改所有使用fill的函数所填充的颜色
    strokeStyle 可以修改所有stroke函数的描边颜色

    (二)绘制

    (1)绘制矩形

    实心矩形
    语法:ctx.fillRect(x, y, w, h)
    x:水平坐标 y:竖直坐标 (坐标原点在canvas左上角)
    w:矩形宽度 h:矩形高度

    //修改颜色
    ctx.fillStyle = '#f00'
    ctx.fillRect(50, 100, 150, 50)
    
    • 1
    • 2
    • 3

    镂空矩形
    语法:ctx.strokeRect(x, y, w, h)
    x:水平坐标 y:竖直坐标 (坐标原点在canvas左上角)
    w:矩形宽度 h:矩形高度

    ctx.strokeRect(300, 100, 200, 100)
    
    • 1

    清空矩形
    用于清空画布

    ctx.clearRect(0, 0, 800, 600)
    
    • 1

    (2)绘制文本

    实心文字
    语法:ctx.fillText(text, x, y, max-width)
    text: 要渲染的文本
    x,y: 文本渲染的坐标位置
    max-width: 文本最大宽度,当大于该宽度,文本字体将自动缩小以自适应宽度

    ctx.fillText('祖国万岁!!', 200, 100, 100)
    //最后一个参数可省略
    ctx.fillText('祖国万岁!!', 200, 100)
    
    • 1
    • 2
    • 3

    镂空文字
    参数和实心文本相同

    ctx.strokeText('祖国万岁!!', 200, 300)
    
    • 1

    (3)绘制线

    画直线
    设置颜色和线宽

    ctx.strokeStyle = '#ff0'
    ctx.lineWidth = 15
    
    • 1
    • 2

    使用beginPath开启路径(此方法的路径是非封闭的)

    ctx.beginPath()
    
    • 1

    使用moveTo移动笔头,但不会记录路径上的线条

    xtx.moveTo()
    
    • 1

    用线绘制一个点到下一个点

    ctx.lineTo()
    
    • 1

    将路径封闭

    ctx.closePath()
    
    • 1

    显示图形,将路径所包围的图形用纯色来填充

    ctx.fill()
    
    • 1

    将路径用镂空线条进行填充

    ctx.stroke()
    
    • 1

    画弧线

        //每画一个图形开启一次路径
        ctx.beginPath()
        ctx.moveTo(400, 400)
        ctx.lineTo(500, 400)
        // 角度转弧度的公式: rad = (PI / 180) * deg
        // 弧线
        // ctx.arc(x, y, r, start, end)
        // x: 圆心横坐标
        // y: 圆心纵坐标
        // r: 圆半径
        // start: 起始弧度 0度时的方向为水平向右 顺时针为正方向
        // end: 结束弧度
        ctx.arc(400, 400, 100, 0, Math.PI / 180 * 30)
        ctx.closePath()
    
        ctx.fill()
        // ctx.stroke()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    (4)绘制图片

    语法

    ctx.drawImage(image, dx, dy);
    ctx.drawImage(image, dx, dy, dWidth, dHeight);
    ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
    
    • 1
    • 2
    • 3

    image: img 标签的 dom 对象
    dx dy: 图片在canvas中的坐标
    dWidth dHeight: 图片在canvas中的宽高
    sx, sy: 参考图片源,截图的坐标
    sWidth, sHeight: 截图的宽高
    方式一

        const img = document.querySelector('img')
        const canvas = document.querySelector('canvas')
        const ctx = canvas.getContext('2d')
    
        img.addEventListener('load', () => {
            // 图片加载完成后 再绘制图片
            // ctx.drawImage(img, 100, 100)
            // ctx.drawImage(img, 100, 100, 100, 100)
            ctx.drawImage(img, 10, 100, 170, 170, 100, 100, 170, 170);
        })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    方式二

        const canvas = document.querySelector('canvas')
        const ctx = canvas.getContext('2d')
        
    	// 动态生成图片进行绘图
        let img = document.createElement('img')
        img.style.display = 'none'
        img.src = './img/heihei.png'
        img.addEventListener('load', ev => {
            // 绘图
            ctx.drawImage(img, 10, 100, 170, 170, 100, 100, 170, 170);
            // 删除图片节点
            img.remove()
        })
        // 插入图片到页面
        document.body.appendChild(img)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    四、多媒体标签

    (一)视频标签(video)

    宽高(width height)

    控制面板(controls)

    静音(muted)

    自动播放(autoplay):自动播放要配合静音才能实现

    媒体源(src)

    预载模式(preload)

    循环(loop)

    海报(poster):video特有

    (二)音频播放器(audio)

    由于audio和video都属于HTMLMediaElement的实例

    所以audio的所有使用方法和video一样

    可以通过 instanceof 来判断一个对象是否是某个类型的实例

    video instanceof HTMLMediaElement
    
    • 1

    属性
    宽高(width height):没意义

    控制面板(controls)

    静音(muted)

    自动播放(autoplay):自动播放要配合静音才能实现,但是没意义

    媒体源(src)

    预载模式(preload)

    循环(loop)

    (三)使用Audio类名创建

        // 可以使用 Audio 类名来创建 audio 标签
        // let audio = new Audio()
        // audio.src = './audio/a4.mp3'
        // audio.play()
    
    • 1
    • 2
    • 3
    • 4

    (四)数据源标签(source)

    audio和video都可用

    source 标签若有多个,那么浏览器会从上至下加载直到某一个被加载成功为止

        
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    (五)自定义控制器

        
    当前时间: 总时间:
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
        let video = document.querySelector('video')
        let playBtn = document.querySelector('.play')
        let pauseBtn = document.querySelector('.pause')
        let totalTime = document.querySelector('.total-time')
        let currentTime = document.querySelector('.current-time')
        let inp = document.querySelector('.inp')
        let goToBtn = document.querySelector('.go-to')
        let vUpBtn = document.querySelector('.v-up')
        let vDownBtn = document.querySelector('.v-down')
        let mutedBtn = document.querySelector('.muted')
        
            let timer
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
        // 播放
        playBtn.addEventListener('click', () => {
            video.play()
    
            // 显示总时长
            // textContent 标签体的文本内容
            // duration 代表媒体时长,单位: 秒
            totalTime.textContent = video.duration
            currentTime.textContent = video.currentTime
    
            clearInterval(timer)
            timer = setInterval(() => {
                // currentTime 代表当前播放的时间
                currentTime.textContent = video.currentTime
            }, 1000)
        })
        // 暂停
        pauseBtn.addEventListener('click', () => {
            video.pause()
        })
        // 跳转进度
        goToBtn.addEventListener('click', () => {
            let currentTime = Number(inp.value)
            // 直接赋值 video 的 currentTime 就可以跳转进度
            video.currentTime = currentTime
        })
        // 音量+
        vUpBtn.addEventListener('click', () => {
            // volume 是一个 0~1 的数字 用于控制音量
            video.volume = video.volume + 0.1 > 1 ? 1 : video.volume + 0.1
        })
        // 音量-
        vDownBtn.addEventListener('click', () => {
            // volume 是一个 0~1 的数字 用于控制音量
            video.volume = video.volume - 0.1 < 0 ? 0 : video.volume - 0.1
        })
    
        // 静音
        mutedBtn.addEventListener('click', () => {
            video.muted = !video.muted
        })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    (六)滑块

    0
    
    • 1
        let inputRange = document.querySelector('input[type=range]')
        let rangeValue = document.querySelector('.range-value')
    
        inputRange.addEventListener('input', () => {
            rangeValue.textContent = inputRange.value
        })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    (七)图片标签(picture)

        
            
            
            
            
            
            
        
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
  • 相关阅读:
    java SpringBoot登录验证token拦截器
    年龄大了转嵌入式有机会吗?
    本地部署Llama3-8B/70B 并进行逻辑推理测试
    DAY13 链表
    安装MongoDB
    Zookeeper如何实现Leader选举
    正则表达式基础语法
    智能疾病查询接口
    使用 RAFT 的光流:第 1 部分
    【数据库06】web应用程序开发的任督二脉
  • 原文地址:https://blog.csdn.net/m0_52869979/article/details/126769062