IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> 移动互联应用学习内容总结 -> 正文阅读

[游戏开发]移动互联应用学习内容总结

一、css动画相关

1.动画原理及2D变化

动画原理:连续的播放多张图片,形成一个连贯的动画;
css代码中如何理解动画:一个元素存在多个css状态,连续的播放改元素的这些css状态,将形成一组动画,这就是css动画;
帧率:描述动画在1s钟之内播放多少个状态;

transition

参考:https://developer.mozilla.org/zh-CN/docs/Web/CSS/transition
什么是transition?
transition是过渡的意思,将会使元素从一个状态用动画形式过渡到另一个状态

定义初始状态

transition:translateX(0px)

注意:播放过度动画至少包含 transition-property transition-duration

指定css属性能够产生过渡动画
transition-property:left,transform;

transition-property还有两个待选项
- none:无
- all:所有属性都能播放过渡动画

动画播放时常
transition-duration: 2s;
动画播放的速度曲线

待选项

  • linear:匀速直线运动
  • ease-in:慢进
  • ease-out:慢出
  • ease-in-out:慢进慢出
  • cubic-bezier:曲线函数
 transition-timing-function:linear;
动画播放延迟
 transition-delay:3s;
合成属性
 transition: property duration timing-function delay;

过渡:产生过渡动画的属性,持续时间,速度,延迟时间

通过class来控制过渡动画

通常来说使用 active 类名来代表播放动画的状态,在点击某个按钮或者元素时,通过改变它的class来实现不同的效果。

改变类名的两种方式:

  • className
    某某元素.className= ‘类名’
  • classList.add(‘新添加的类名’)
    某某元素.classList.add(‘新添加的类名’)
    两者的区别在于,className每次改类名都是完整的修改,classList是添加新的一个类名,原来如果有类名那么也还在那里。
    classList的其他方法
    classList.remove() 移除某个类
    classList.contains() 判断是否包含某个类名 返回一个 bool 值; true 为包含
transition 动画事件

场景: 假设有一个按钮控制动画的来回播放,当点击按钮播放动画的过程中需要禁用按钮,只有动画播放完了才能解除按钮的禁用,此时可以捕获事件来完成需求

参考:
https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/transitionrun_event
https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLElement/transitionstart_event
https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLElement/transitionend_event

禁用按钮 btn.disabled = true
true为禁用,false为不禁用

transitionend过渡完成,transitionrun过渡运行中,transitionstart过渡开始
如果在这个事件中,设置了后台的打印,发现打印多条测试语句,是因为有多少个过渡属性就会打印多少次测试语句。

transitionrun在创建过渡时触发(即在任何延迟开始时)。
transitionstart当实际动画开始时触发(即在任何延迟结束时)。

2.元素2D变化transform

1.平移

transform变换,用于描述物体的位置旋转缩放
translate平移,第一个参数:水平平移量(x轴);第二个参数:竖直平移量(y轴)
右为正方向:左移正数,右移负数
transform:translate(100px,200px)
translateX/Y/Z();独立的在某一个轴上平移,单参数

2.旋转

transform:rotate()
rotate()旋转
单位:deg角度,rad弧度
参数:可以是角度值,也可以是弧度值
转换:弧度制的PI=180°
旋转的正方向(顺时针)就是数值的正方向(正值),0度代表竖直向上;负数的含义就是360度-对应的度数,如(-30deg)=(360-30deg)=(30deg);默认旋转函数rotate是沿着z轴(即垂直屏幕的线)进行旋转的。
rotateX()沿着水平轴进行旋转,对称轴为横向,类似滚筒旋转
rotateY()与X轴相反

3.缩放

scale()缩放
scale(水平方向,竖直方向)缩放,可以单参数也可以双参数
transform:scale(1) //1倍大小(即原来的大小)
transform:scale(-1) //反向
参数:比率;1为原本大小
写负数代表反向
scaleX()水平方向的缩放(变瘦)
scaleY()竖直方向的缩放(变高变大)

4.倾斜

transform:skew();
skew()倾斜,参数为角度值
skew(水平方向,竖直方向)缩放,可以单参数也可以双参数

5.原点
        transform-origin: center;

待选值: top bottom left right center 还可以填入像素值

transform-origin: right center;

第一个参数代表水平偏移量 第二个参数代表竖直偏移量,当值为像素值的时候,像素值的参考位置是元素的左上角

3.3d变换和animation动画

animation动画

动画名称 animation-name:move;
动画播放时长 animation-duration:3s;
动画播放的速度曲线 animation-timing-function:linear;
动画延迟 animation-delay:3s;
动画播放状态 animation-play-state:paused(暂停)、running(播放)

animation独有的属性

动画的迭代次数(动画的播放次数) infinite 无限次

animation-iteration-count:1;
动画播放方向

待选项:normal(顺向播放) reverse(反向播放) alternate(来回播放) alternate-reverse(反向来回播放)

animation-direction:normal;
动画填充模式

(动画播放结束后所保留的状态)
forwards:保留结束帧的状态
backwards:保留起始帧的状态
both:即保留初始状态,又保留结束状态(保留初始和结束时的状态)
animation-fill-mode:forwards;

可以定义复合属性,取代上面的所有属性
赋值顺序,可以参考如下顺序
duration | timing-function | delay | iteration-count | direction | fill-mode
| play-state | name
duration | timing-function | delay | name
duration | name

动画帧序列
    @keyframes move {

        /* 起始帧 */
        from {
            /* 每一帧中描述该元素的状态 */
            transform: translateX(0px);
            opacity: 0;
        }

        /* 可以用百分比来代表动画的中间状态 */
        50% {
            transform: translateX(600px);
            opacity: 1;
        }

        /* 结束帧 */
        to {
            transform: translateX(300px);
        }
    }
动画的播放和暂停
   btn2.addEventListener('click', () => {
        // animationPlayState 动画播放状态
        // paused 暂停
        // running 播放

        if (box.style.animationPlayState === 'paused') {
            box.style.animationPlayState = 'running'
        } else {
            box.style.animationPlayState = 'paused'
        }
    })
3D变换
<style>
        .scene {
            height: 100vh;
            /* 变换样式
                perserve-3d 代表将元素变成一个3D空间
            */
            transform-style: preserve-3d;
            /* 灭点到屏幕的距离 */
            /* 若三维场景中不添加 perspective 则三维场景是一个正交视图 */
            perspective: 300px;

            /* 透视原点(灭点所在的坐标)
                原点为 0 值时,所在位置是scene的左上角
            */
            /* perspective-origin: center center; */
            perspective-origin: 0 0;
        }
    </style>
<body>
    <!-- 创建一个场景,用来显示三维图形 -->
    <div class="scene">

        <!-- 给三维空间中添加三维元素 -->
        <div class="box"></div>
    </div>
</body>

参考:https://developer.mozilla.org/zh-CN/docs/Web/CSS/transform-style

3d变换 是让我们的元素看上去在三维空间中发生变换(平移 旋转 缩放 倾斜)

透视的特点:

  • 存在地平线
  • 存在灭点
  • 近大远小
  • 灭点离物体越近,透视产生的形变越明显

和透视相对应的就是正交,正交视角没有透视的远近感,相反是种平面的感觉

总结:
要使用3d变换需要依序执行以下步骤:

  1. 搭建3d场景,在父元素上设置:transform-style: preserve-3d;
  2. 在父元素上设置透视距离:perspective: 100px;
  3. 给场景添加演员,给场景元素添加子元素
  4. 在子元素上使用3d变换

4.渐变色分栏布局与响应式

1.渐变色

参考:https://developer.mozilla.org/zh-CN/docs/Web/CSS/gradient
背景的渐变色实际上是设置的 background-image 而不是 background-color

线性渐变

语法: linear-gradient(direction, color1, color2, color3 … )
direction: 渐变色的朝向 以 to 开头, 或者可以添加角度值; 默认值为 to top
color1 color2 …: 渐变的颜色序列

background-image: linear-gradient(30deg, #f00, #0f0, #00f);

颜色值后可以添加像素距离,该像素值代表着该颜色所处的位置,该位置颜色将到下一个位置的颜色之间进行渐变

background-image: linear-gradient(to right, #f00, #f00 50px, #0f0 50px, #0f0 100px, #00f 200px);
重复线性渐变
background-image: repeating-linear-gradient(to right, #f00, #f00 50px, #00f 50px, #00f 100px);
径向渐变
background-image: radial-gradient(#f00, orange, #0f0, #ff0, #f0f);
background-image: radial-gradient(#f00, #f00 50px, #00f 50px, #00f 100px, #0f0 100px, #0f0 200px);
重复径向渐变
background-image: repeating-radial-gradient(#f00, #f00 50px, #ff0 50px, #ff0 100px);
2.分栏布局
        /* 设置文本列数 */
        column-count: 3;
        /* 设置列宽度 */
        column-width: 150px;
        /* 分栏边框,属性值和边框的属性值相同 */
        column-rule: 5px double red;
        /* 两列文本中间的间距 */
        column-gap: 100px;

        word-break: keep-all;
3.响应式(媒体查询)

参考地址:https://developer.mozilla.org/zh-CN/docs/Web/CSS/@media
https://developer.mozilla.org/zh-CN/docs/Web/CSS/Media_Queries/Using_media_queries

  • 响应式是什么?
    当某个事情发生后,立即做出反应就叫响应式
    此处我们讨论的是页面的响应式

  • 什么是页面的响应式?
    页面的元素样式会根据页面的宽度做出变化

  • 为什么要使用页面响应式
    为了让同一个页面能够适配不同的设备

  • 如何实现响应式?
    使用媒体查询,来实现响应式布局

媒体查询的作用:当媒体查询条件成立时,将应用花括号中代码块的样式
语法:@media media-type and (condition1) and (condition2) …

媒体类型 media-type:
备选项
all: 所有设备
print:打印机的预览模式
screen:显示屏
speech:语音合成器

    min-width: 屏幕最小宽度 
    max-width: 屏幕最大宽度 
  <style>
@media screen and (min-width: 600px) and (max-width: 900px) {
            .box {
                background-color: orange !important;
            }
        }
  </style>
  • 知识补充
    @import 可以引入css样式
    @import url(./…)
    @import和link有什么区别?link可以引用别的样式,不一定要css,@import只能引用css样式

二、jQuery

1.jquery的引入及基础用法

jquery 简介

英文官网: https://jquery.com/

中文简单教学(支持文档查询):https://www.jquery123.com/

什么是jquery

jquery是一个js的工具库,充当程序的核心库

jquery的作用

jquery有以下主要功能:

针对页面元素,jquery提供了很多操纵页面元素的函数

还有一些工具函数,方便一些运算

jquery可以充当发起网络请求的客户端工具

安装

  1. 在官网上点击download进行下载
  2. cdn: 共享资源节点
  3. npm 安装
    npm init
    npm i jquery
    # 安装完后从 node_modules/jquery/dist 文件夹中获取资源
    

在页面中的使用

<!DOCTYPE html>
<html>
    <head></head>
    <body></body>
    <!-- 通过脚本形式进行引入 -->
    <script src="./jquery.min.js"></script>
    <script>
        // 在引入jquery后,此处就可以使用jquery的功能了
    </script>
</html>

jquery 使用的方法

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

使用 $() 函数获取一个 jQuery 对象,jquery 对象的变量名 一般以 $ 美元符开头,jquery 对象看上去像一个数组 其中数组成员就是 dom 对象

<script>
	let $box = $('.box')
 //给元素添加样式
    $box.css('height', '100px')
    $box.css('background-color', '#f00')
    
 // jquery对象的函数总返回自己
// 所以可以进行链式调用
    $box.css('height', '100px')
        .css('background-color', '#f00')
        .css('color', '#fff')
        .text('hello world')
    </script>

2.创建jquery对象

使用jquery $() 函数查询出来的返回值 就是一个jquery 对象
$box 就是一个jquery 对象

let $box = $('.box')

获取jquery对象的方法有两种

  1. 使用 css 选择器

let $li = $(‘ul>li’)

  1. 使用 dom 对象
    先查询一个dom对象
let box = document.querySelector('.box')

使用dom对象获取一个jquery对象

let $box = $(box)

3.eq和get

<script>
    let $lis = $('ul>li')

    // eq 读取对应索引位置的jquery对象
    let $li = $lis.eq(1)
    // 因为 $li 是jquery对象 所以可以直接使用jquery操作它
    $li.css('color', '#0f0')

    // get 读取对应索引位置的dom对象
     let li = $lis.get(2)
     li.style.color = '#f00'

    // 使用 [] 方括号的方式去获取索引对应的 dom 对象
    // 其结果等价于 get 函数获取的结果
    let li = $lis[2]
    li.style.color = '#f00'
</script>

4.创建并插入元素元素

<script>

    // 创建一个节点,该节点就是一个jquery对象
    let $box = $(`<div class="box">new</div>`)

    // 某个元素追加一个子节点
    // $(document.body).append($box)

    // 追加一个子节点到另一个元素中
    // $box.appendTo($(document.body))

    // 某个元素追加一个节点到头部
    // $(document.body).prepend($box)

    // 追加一个子节点到另一个元素的头部
    // $box.prependTo($(document.body))

    let $box2 = $('.box').eq(1)

    // 某个元素的前面追加一个元素
    // $box2.before($box)

    // 某个元素被添加到另一个元素的前面
    // $box.insertBefore($box2)

    // 某个元素的后面添加一个元素
    // $box2.after($box)

    // 某个元素被添加到另一个元素的后面
    $box.insertAfter($box2)

</script>

5.设置样式(读取、赋值)

<script>

    let $box = $('.box')

    // 读取样式
    let width = $box.css('width')
    console.log(width);

    // 读取多个样式
    let r = $box.css(['width', 'color', 'font-size'])
    console.log(r);

    // 赋值样式
    // $box.css('background-color', '#f00')

    // 通过函数来赋值样式
    $box.css('background-color', (index, value) => {
        // index 遍历的数组成员的索引
        // value 对应索引元素的样式值
        console.log(index, value);

        // 返回一个参数就可以赋值css属性
        if (index === 0) {
            return 'pink'
        } else {
            return 'gold'
        }
    })
</script>

6.设置类(添加、判断、删除)

<script>
    let $box = $('.box')

    // 添加类
    $box.addClass('active')

    // 判断是否存在某个类名
    $box.hasClass('active')

    // 删除类
    $box.removeClass('active')
</script>

7.设置属性(读取、赋值、删除)

<script>
    let $box = $('.box')

    // 读取属性
    let clazz = $box.attr('class')
    console.log(clazz);

    // 赋值属性
    $box.attr('my-data', 'hello world')

    // 删除属性
    $box.removeAttr('class')
</script>

8.设置标签体(innerHTML)

<script>
    let $p = $('.p')

    // 相当于dom对象的innerText
    $p.text('<span style="color: red">hello</span>&nbsp;world')

    // 相当于dom对象的innerHTML
    $p.html('<span style="color: red">hello</span>&nbsp;world')
</script>

9.绑定/解绑事件

<script>
    let $btn = $('button')

    // 和dom对象绑定事件进行类比
    // dom 对象有两种绑定事件的方法
    // 1. 使用 事件属性 例如: onclick onmousemove

    // 对应 jquery 的写法如下
    $btn.click(ev => {
        console.log('click');
        // ev 是jquery封装的事件对象
        console.log(ev);
    })

    // 再例如
    $btn.mousemove(ev => {
        console.log('mousemove');
    })

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

    // 2. 使用事件监听器
    // $btn[0].addEventListener('click', ev=>{})

    // 对应的jquery写法:

    const handler = ev => {
        console.log(ev);
        console.log(1);
    }

    // 绑定事件
    $btn.on('click', handler)

    $btn.on('click', ev => {
        console.log(ev);
        console.log(2);
    })

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

    // 解绑指定事件处理程序
    // $btn.off('click', handler)

    // 解绑所有事件处理程序
    $btn.off('click')

</script>

10.遍历元素

<script>
    let $lis = $('li')

    // each 遍历数组
    $lis.each((index, item) => {
        // index 数组成员的索引
        console.log(index);
        // item 当前被遍历的数组成员
        // 此处的item是一个 dom 对象 不是jquery对象
        console.log(item);

        if ((index + 1) % 2 === 0) {
            $(item).css('background-color', '#f00')
        }
    })
</script>

11.表单元素取值赋值

<script>
    // 查询表单元素
    let $name = $('input[name=name]')
    let $sex = $('input[name=sex]')
    let $hobbies = $('input[name=hobbies]')
    let $clazz = $('select[name=clazz]')
    let $desc = $('textarea[name=desc]')
    let $btn = $('form button')

    // sex 变量用于保存性别值
    let sex

    // hobbies 变量用于保存爱好的多选结果
    // 一般是一个数组
    let hobbies = []

    $btn.click(ev => {
        // 使用jquery读取表单数据

        // 读取输入框
        let name = $name.val()
        console.log(name);

        // 读取单选/多选
        // 通过元素的 checked 属性读取
        $sex.each((i, el) => {
            // 使用 dom api
            // console.log(el.value)
            // console.log(el.checked)
            // 使用jquery读取值
            if (el.checked) {
                // 使用 jquery 的 val 函数 读取单选按钮的 value 值
                sex = $(el).val()
            }
        })

        console.log(sex);


        // 清空数组
        hobbies.splice(0, hobbies.length)
        $hobbies.each((i, el) => {
            if (el.checked) {
                // 若当前选项被勾选了
                // 则将选项值插入到数组中
                hobbies.push($(el).val())
            }
        })

        console.log(hobbies);

        // 读取下拉框
        console.log($clazz.val());

        // 读取文本域
        console.log($desc.val());
    })


    // 伪造一个服务器返回的假数据
    let stu = {
        name: '法外狂徒张三',
        sex: 'female',
        hobbies: ['dlq', 'tzq'],
        clazz: '1',
        desc: '从出生到入土\n张三的传奇一生'
    }

    // 回显数据到表单上
    function review() {
        // jquery赋值value
        $name.val(stu.name)

        // 回显性别
        $sex.each((i, el) => {
            // 判断选项的value是否等于数据的sex值
            if ($(el).val() === stu.sex) {
                // 勾选
                el.checked = true
            }
        })

        // 回显爱好
        $hobbies.each((i, el) => {
            // 使用数组的 includes 来判断 $(el).val() 是否被数组 hobbies 包含
            // indexOf 
            if (stu.hobbies.includes($(el).val())) {
                // 勾选
                el.checked = true
            }
        })

        // 回显班级
        $clazz.val(stu.clazz)

        // 回显简介
        $desc.val(stu.desc)
    }

    review()
</script>

12.一些基本特效

<script>
    // 参考:https://www.jquery123.com/category/effects/

    let $box1 = $('.box1');
    let $box2 = $('.box2');
    let $box3 = $('.box3');
    let $box4 = $('.box4');

    // jquery 特效

    // 基本动画
    $('.section1 button:nth-child(1)').click(() => {
        // 显示元素 原理是设置元素的display属性
        $box1.show()
    })
    $('.section1 button:nth-child(2)').click(() => {
        // 隐藏元素
        $box1.hide()
    })
    $('.section1 button:nth-child(3)').click(() => {
        // 开关元素
        $box1.toggle()
    })

    // 自定义动画
    $('.section2 button:nth-child(1)').click(() => {
        // 自定义动画
        // 第一个参数:要播放的动画属性,有些属性无法生效例如:transform background-color 等
        $box2.animate({
            marginLeft: 300,
            fontSize: 64
        }, 2000, 'linear', () => {
            // 动画播放结束的回调函数
            console.log('动画播放完了');
        })
    })

    // 渐变动画
    $('.section3 button:nth-child(1)').click(() => {
        // 渐变函数的第一个参数,可以指定动画播放的时长,单位是毫秒
        // 元素渐入
        $box3.fadeIn(3000)
    })
    $('.section3 button:nth-child(2)').click(() => {
        // 元素渐出
        $box3.fadeOut(5000)
    })
    $('.section3 button:nth-child(3)').click(() => {
        // 第一个参数:动画播放时长
        // 第二个参数:目标透明度
        // 渐变到指定透明度
        $box3.fadeTo(3000, 0.2)
    })
    $('.section3 button:nth-child(4)').click(() => {
        // 开关渐变
        // $box3.fadeToggle(2000, 'linear', ()=>{
        //     console.log('动画播放完成');
        // })

        $box3.fadeToggle({
            duration: 5000,
            easing: 'swing',
            step: (a)=>{
                console.log('step');
                console.log(a);
            }
        })
    })

    // 滑动动画
    $('.section4 button:nth-child(1)').click(() => {
        // 滑下
        $box4.slideDown()
    })
    $('.section4 button:nth-child(2)').click(() => {
        // 滑上
        $box4.slideUp()
    })
    $('.section4 button:nth-child(3)').click(() => {
        // 滑动开关
        $box4.slideToggle(5000)
    })
</script>

13.元素包裹

<script>
    // wrap wrapAll 函数作用是将指定元素用一段html内容包裹起来
    
    // 每一个元素都使用 div 来进行包裹
    // $('li').wrap('<div class="fs"></div>')

    // 所有的 li 元素用一个 div 进行包裹
    $('li').wrapAll('<div class="fs"></div>')

</script>

14.ready事件

<script>

    // 页面加载完成后触发一段自己的程序
    $().ready(() => {
        console.log('页面准备完成');
    })

    // $().ready() 的缩写
    $(function () {
        console.log('页面准备完成2');
    })

    // js api 的页面加载完成事件
    window.addEventListener('load', () => {
        console.log('window 页面加载完成');
    })

    // 文档准备状态发生变化事件
    document.addEventListener('readystatechange', ev => {
        // document.readyState 文档的准备状态
        // 当该状态变为 complete 时 代表文档加载完成
        if (document.readyState === 'complete') {
            console.log('文档加载完成');
        }
    })

</script>

15.读取和设置元素大小和位置

<script>

    const $box = $('.box')

    // 读取元素位置
    // position 查询元素相对于父元素的位置 不能赋值只能读值
    console.log($box.position());

    // offset 查询元素全局坐标
    console.log($box.offset());

    // offset 可以赋值
    $box.offset({ top: 200, left: 100 })

    // 所有查询元素大小的函数均可赋值
    // 查询元素的内容宽高
    console.log($box.width(300));
    console.log($box.height());

    // innerWidth 代表 width + padding
    console.log($box.innerWidth());
    // outerWidth 代表 width + padding + border
    console.log($box.outerWidth());
</script>

16.获取和设置滚动条的位置

<script>
    // 使用jquery设置滚动条位置
    // 前提是要找到哪个元素出现了滚动条
    let $html = $('html')

    $('.btn').click(() => {
        // 水平滚动条位置
        console.log($html.scrollLeft());
        // 竖直滚动条位置
        console.log($html.scrollTop());
    })

    // 赋值滚动条位置只需要在函数参数处填入距离参数就可以了
    $html.scrollLeft(500)
    $html.scrollTop(300)
</script>

17.ajax

<script>
    // 什么是 ajax?
    // async javascript and xml 缩写为 ajax
    // ajax 朴素的理解就是:异步的网络请求

    $('button').click(() => {
        // 发起 ajax 请求
        $.ajax({
            // 请求地址
            url: 'https://www.bilibili.com',
            // 请求方法
            method: 'get',
            // 请求参数
            data: { x: 1, y: 2 },
            // 请求成功的回调函数
            success: (data) => {
                console.log(data);
            },
            // 请求异常的回调函数
            error: (err) => {
                console.error(err);
            },
            complete: () => {
                console.log('无论请求成功还是失败,都会触发 complete');
            }
        })
    })
</script>

18.其他api(index、find)

<script>
    // index() 查询某个节点在集合中的索引

    let index = $('.box').index($('.box:nth-child(3)'))
    console.log(index);

    // find() 查询某个节点的后代节点
    let $span = $('.box-list').find('.box>span')
    console.log($span);

    // js api 的查询方法
    let boxList = document.querySelector('.box-list')
    // 查询boxList的子节点
    console.log(boxList.querySelector('.box>span'));

    // closest 查询最近的父节点
    console.log($span.closest('.box-list'));
</script>

三、canvas画布

什么是canvas?

canvas是浏览器提供的一个标签,该标签可以用来绘制图像。canvas我们通常称为画布

1.canvas的基础用法

在style里设置canvas的宽高样式时,其实是把画布拉伸到了这样的大小,像素点不变,会导致绘制的图像边缘模糊。
在canvas行内里设置的宽高样式,设置的真实像素点

<script>
    const canvas = document.querySelector('canvas')
    // 获取canvas标签的画布对象
    // 可以通过操作画布对象来进行绘画
    const ctx = canvas.getContext('2d')

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

</script>

总结:
使用canvas的步骤
1. 创建canvas标签
2. 给canvas标签设置 width height 属性
3. 通过js 获取canvas标签
4. 通过canvas标签获取context画布上下文(画布对象)
5. 通过context绘制画布

2.绘制矩形

实心矩形

<script>
    let canvas = document.querySelector('canvas')
    let context = canvas.getContext('2d')
    <!-- 设置颜色,每画一次设一次(如果颜色有变化) -->
    context.fillStyle = 'rgb(191,191,191)'
    <!-- 绘制矩形,参数分别是:横坐标、纵坐标、图像长、图像宽 -->
     context.fillRect(20,20,300,25)
     </script>

镂空矩形

<script>
    const canvas = document.querySelector('canvas')
    const ctx = canvas.getContext('2d')

    // 改颜色
    ctx.fillStyle = '#f00'
    // 镂空矩形
    // 参数和实心矩形相同
    ctx.strokeRect(300, 100, 200, 100)

    // 清空矩形, 用于清空画布
    ctx.clearRect(0, 0, 800, 600)
</script>

3.绘制文本

<script>
    const canvas = document.querySelector('canvas')
    const ctx = canvas.getContext('2d')

    // 修改字体大小和字体库
    ctx.font = '32px 华文琥珀'

    ctx.fillStyle = '#f00'

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


    ctx.strokeStyle = '#0f0'

    // 镂空文字
    // 参数和实心文本相同
    ctx.strokeText('祖国万岁!!', 200, 300)

</script>

4.画线

<script>
    const canvas = document.querySelector('canvas')
    const ctx = canvas.getContext('2d')


    // 设置颜色和线宽
    ctx.strokeStyle = '#ff0'
    ctx.lineWidth = 15

    // 画线分两个步骤:
    // 1. 描点(设置路径)
    // 2. 画线(将所描的点连接起来)

    // 步骤一
    // 使用 beginPath 开启路径
    ctx.beginPath()
    // 移动笔头但不会记录路径上的线条
    ctx.moveTo(400, 100)
    // 用线绘制到下一个点
    ctx.lineTo(200, 200)
    ctx.lineTo(600, 200)
    ctx.lineTo(400, 100)

    // 将路径封闭
    ctx.closePath()

    // 注意:beginPath在画新的路径的时候必须调用,closePath选择性调用


    // 步骤二
    // 为了显示图形需要调用以下函数
    // 将路径所包围的图形用纯色来填充
    // ctx.fill()
    // 将路径用镂空线条进行绘制
    ctx.stroke()


    ctx.strokeStyle = '#f00'

    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()
</script>

画线分为2个步骤:
1.描点(设置路径)
2.画线(将描的点连接起来)
使用beginPath开启路径

moveTo:把笔头移动到某个坐标,移动笔头但不会记录路径上的线条
lineTo:用线绘制到下一个点
closePath:将路径封闭
注意:不是必须得把路径封闭

5.fillStyle和strokeStyle

<script>
    let c = document.querySelector('canvas')
    let ctx = c.getContext('2d')

    // fillStyle 可以修改所有使用fill的函数所填充的颜色
    ctx.fillStyle = '#f00'

    ctx.fillRect(0, 0, 50, 50)

    ctx.beginPath()
    ctx.arc(250, 250, 200, (Math.PI / 180) * (-90), (Math.PI / 180) * (90))
    ctx.fill()

    // strokeStyle 可以修改所有stroke函数的描边颜色
    ctx.strokeStyle = 'violet'
    ctx.lineWidth = 10
    ctx.strokeRect(50, 0, 50, 50)

    ctx.beginPath()
    ctx.arc(250, 250, 200, (Math.PI / 180) * (90), (Math.PI / 180) * (270))
    ctx.stroke()
</script>

6.绘制图片

<script>
    // mdn: https://developer.mozilla.org/zh-CN/docs/Web/API/CanvasRenderingContext2D/drawImage

    // 语法:
    // ctx.drawImage(image, dx, dy);
    // ctx.drawImage(image, dx, dy, dWidth, dHeight);
    // ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
    // 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);
    // })



    // 动态生成图片进行绘图
    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)
</script>

8.canvas像素级颜色操作(灰度、反转色、黑白)

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <canvas class="src" width="220" height="140"></canvas>
    <br />
    <button>灰度</button>
    <button>反转</button>
    <button>黑白</button>
    <br />
    <canvas class="target" width="220" height="140"></canvas>
</body>
<script>
    const ctx1 = document.querySelector('.src').getContext('2d')
    const ctx2 = document.querySelector('.target').getContext('2d')
    const img = document.createElement('img')
    img.src = './img/an2.jpg'
    img.addEventListener('load', () => {
        ctx1.drawImage(img, 0, 0, img.width, img.height, 0, 0, 220, 140)
    })

    const btn1 = document.querySelector('button:nth-of-type(1)')
    const btn2 = document.querySelector('button:nth-of-type(2)')
    const btn3 = document.querySelector('button:nth-of-type(3)')

    // 灰度图
    btn1.addEventListener('click', () => {
        // 获取canvas中的图片数据
        // sx, sy: 截取canvas中图片的坐标
        // sw, sh: 截取图片的宽高
        // ctx.getImageData(sx, sy, sw, sh)
        let imageData = ctx1.getImageData(0, 0, 220, 140)

        // 灰度公式:g = r*0.299 + g*0.587 + b*0.114

        for (let i = 0; i < imageData.data.length; i += 4) {
            const color = imageData.data[i];
            // 将每个像素值赋值成灰度值则可以获取到灰度图

            // 计算灰度
            let g = imageData.data[i] * 0.299 + imageData.data[i + 1] * 0.587 + imageData.data[i + 2] * 0.114

            // rgb 赋值成灰度值
            imageData.data[i] = g
            imageData.data[i + 1] = g
            imageData.data[i + 2] = g
        }

        // 应用一个 imageData 数据
        // imageData: 通过getImageData获取到的图像像素点集合
        // dx, dy: 将图片渲染到canvas的坐标
        // ctx.putImageData(imageData, dx, dy)
        ctx2.putImageData(imageData, 0, 0)
    })

    // 反转色
    btn2.addEventListener('click', () => {
        let imageData = ctx1.getImageData(0, 0, 220, 140)
        for (let i = 0; i < imageData.data.length; i += 4) {
            // 反转色就是求rgb值得补值
            imageData.data[i] = 255 - imageData.data[i]
            imageData.data[i + 1] = 255 - imageData.data[i + 1]
            imageData.data[i + 2] = 255 - imageData.data[i + 2]
        }
        ctx2.putImageData(imageData, 0, 0)
    })
    // 黑白图
    btn3.addEventListener('click', () => {
        let imageData = ctx1.getImageData(0, 0, 220, 140)
        // 灰度得中间值
        let temp = 255 * 0.5
        for (let i = 0; i < imageData.data.length; i += 4) {
            // 求灰度值
            let g = imageData.data[i] * 0.299 + imageData.data[i + 1] * 0.587 + imageData.data[i + 2] * 0.114
            // 判断当前像素值得灰度值更趋近于黑色还是白色
            let color = g < temp ? 0 : 255
            // 赋值rgb为黑或白
            imageData.data[i] = color
            imageData.data[i + 1] = color
            imageData.data[i + 2] = color
        }
        ctx2.putImageData(imageData, 0, 0)
    })
</script>

</html>

四、多媒体标签、swiper和animate.css

查看媒体标签的方法: https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLMediaElement
参考 https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/video

1.video

属性:
width 标签宽度
height 标签高度
controls 控制面板
muted 静音
autoplay 自动播放
src 媒体源
preload 预载模式
loop 循环
poster 海报

<video height="300" src="./video/oceans.mp4" controls muted loop poster="./img/desktop.png"></video>
<!-- 使用自动播放+静音,能实现自动播放的效果 -->
<video height="300" src="./video/oceans.mp4" controls autoplay muted></video>

2.音频播放器

由于audio和video都属于HTMLMediaElement的实例
所以audio的所有使用方法和video一样
可以通过 instanceof 来判断一个对象是否是某个类型的实例
video instanceof HTMLMediaElement

<audio src="./audio/moon.mp3" controls loop></audio>

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

<audio controls>
        <!-- 数据源标签 -->
        <source src="./audio/a44.mp3">
        <source src="./audio/b44.mp3">
        <source src="./audio/c4.mp3">
    </audio>

3.自定义控制器

<body>
 <div>
        <button class="play">播放</button>
        <button class="pause">暂停</button>
        当前时间:<span class="current-time"></span>
        总时间:<span class="total-time"></span>
        <input class="inp" /><button class="go-to">跳转到此时间</button>
        <button class="v-up">音量+</button>
        <button class="v-down">音量-</button>
        <button class="muted">静音</button>
    </div>

    <!-- 可以通过以下网站自定义滑块样式
        http://danielstern.ca/range.css/?ref=css-tricks#/
    -->
    <input type="range" min="0" max="100" step="20" value="0"><span class="range-value">0</span>

    <br />
    <!-- picture -->
    <picture>
        <!-- source 标签中有多个待选项时,使用srcset规定资源路径 -->
        <!-- media 设置媒体查询 -->
        <!-- 媒体查询的顺序由大到小 -->
        <source srcset="./img/1.png" media="(min-width: 800px)">
        <source srcset="./img/2.png" media="(min-width: 600px)">
        <img width="500" src="./img/desktop.png">
    </picture>
</body>

<script>

    let inputRange = document.querySelector('input[type=range]')
    let rangeValue = document.querySelector('.range-value')

    inputRange.addEventListener('input', () => {
        rangeValue.textContent = inputRange.value
    })

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

    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

    // 播放
    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
    })

</script>

4.animate.css

动画必须添加 animate__animated
其次添加动画名称所代表的类名

<h1 class="animate__animated animate__bounceInDown">hello world</h1>

辅助类

<!-- 延迟 -->
<h1 class="animate__animated animate__bounceInDown animate__delay-2s">hello world</h1>

    <!-- 播放速度
        animate__slow	2s
        animate__slower	3s
        animate__fast	800ms
        animate__faster	500ms
    -->
  <h1 class="animate__animated animate__bounceInDown animate__slower">hello world</h1>

    <!-- 动画播放次数
        animate__repeat-1	1
        animate__repeat-2	2
        animate__repeat-3	3
        animate__infinite	infinite
    -->
<h1 class="animate__animated animate__bounceInDown animate__infinite">hello world</h1>

动画的叠加

只需要添加多级元素来播放不同的动画即可

<div class="animate__animated animate__fadeInUpBig">
        <h1 class="animate__animated animate__bounceInRight">hello world</h1>
    </div>

自定义动画

由于animate.css本质上是使用的 animation 样式播放的动画,所以可以手动强制修改 animation相关样式,来实现自定义

5.swiper.js

官网地址:https://swiperjs.com/
参考地址:https://www.swiper.com.cn/
swiper是什么?
swiper 是个专门用于播放滚动动画的工具

作用:用于制作滚动播放的播放器

使用思路

  1. swiper 安装好以后,进行布局
  2. 初始化一个 swiper 对象
  3. 按需要添加 swiper 模块

1.swiper布局

<body>
    <!-- swiper 布局 -->
    <!-- swiper节点是整个swiper的容器 -->
    <div class="swiper">
        <!-- swiper-wrapper 展示内容的包装器 -->
        <div class="swiper-wrapper">
            <!-- swiper-slide 每一个 swiper-slide 就是一个滑动块 -->
            <div class="swiper-slide">Slide 1</div>
            <div class="swiper-slide">Slide 2</div>
            <div class="swiper-slide">Slide 3</div>
        </div>
        <!-- 分页工具节点 -->
        <div class="swiper-pagination"></div>

        <!-- 导航按钮节点 -->
        <div class="swiper-button-prev"></div>
        <div class="swiper-button-next"></div>

        <!-- 滚动条节点 -->
        <div class="swiper-scrollbar"></div>
    </div>
</body>

2.swiper初始化配置

<script>
    // 初始化创建 swiper 对象
    // 第一个参数:代表swiper容器的选择器
    // 第二个参数:初始化配置项,是一个json对象

    // 初始化swiper https://swiperjs.com/get-started#initialize-swiper
    // 配置项参考地址:https://swiperjs.com/swiper-api#parameters
    const swiper = new Swiper('.swiper', {
        // 滚动方向
        direction: 'horizontal',
        // 循环
        loop: false,

        // 特效
        effect: 'coverflow',

        // allowSlideNext: false,

        // 分页模块
        pagination: {
            el: '.swiper-pagination',
        },

        // 导航模块
        navigation: {
            nextEl: '.swiper-button-next',
            prevEl: '.swiper-button-prev',
        },

        // 滚动条模块
        scrollbar: {
            el: '.swiper-scrollbar',
        },
    });
</script>

3.swiper事件

<script>
    // 事件: https://swiperjs.com/swiper-api#events
    const swiper = new Swiper('.swiper', {
        direction: 'horizontal',
        loop: false,
        effect: 'coverflow',
        pagination: {
            el: '.swiper-pagination',
        },
        navigation: {
            nextEl: '.swiper-button-next',
            prevEl: '.swiper-button-prev',
        },
        scrollbar: {
            el: '.swiper-scrollbar',
        },

        // 添加事件配置
        on: {
            // 当前激活索引发生变化事件
            activeIndexChange(swiper) {
                console.log('索引发生了变化');
                // swiper 实例对象
                console.log(swiper);
                // activeIndex 当前激活页的索引
                console.log(swiper.activeIndex);
            }
        }
    });


    // on off 绑定和解绑事件
    // 滑块发生变化且动画播放完成事件
    swiper.on('slideChangeTransitionEnd', (swiper) => {
        console.log('滑块变化,动画播放完成');
        console.log(swiper.activeIndex);
    })

    // 到达底部事件
    swiper.on('reachEnd', (swiper) => {
        console.log('已到达底部');
        console.log(swiper.activeIndex);
    })

    // 解绑事件
    swiper.off('slideChangeTransitionEnd')
</script>

4.swiper模块

<script>
    // 参考 https://swiperjs.com/swiper-api#modules
    const swiper = new Swiper('.swiper', {
        effect: 'cube',

        // 分页模块
        pagination: {
            el: '.swiper-pagination',
            bulletActiveClass: 'my-bullet-active'
        },

        // 导航模块
        navigation: {
            nextEl: '.swiper-button-next',
            prevEl: '.swiper-button-prev',
            // 按钮禁用后的样式
            lockClass: 'my-btn-disabled'
        },

        // 滚动条模块
        scrollbar: {
            el: '.swiper-scrollbar',
        },

        // 盒子特效
        cubeEffect: {
            shadowOffset: 300,
            shadowScale: 0.5
        }
    });
</script>

5.代码控制swiper

<script>
    // https://swiperjs.com/swiper-api#methods-and-properties

    const next = document.querySelector('.next')
    const pre = document.querySelector('.pre')
    const to = document.querySelector('.to')

    next.addEventListener('click', () => {
        // swiper.slideNext(speed, runCallbacks)
        // speed:毫秒为单位的动画播放时长
        // runCallbacks:一个bool值 用来表示是否触发过渡事件
        swiper.slideNext(3000, false)
    })

    pre.addEventListener('click', () => {
        // swiper.slidePrev(speed, runCallbacks)
        // speed:毫秒为单位的动画播放时长
        // runCallbacks:一个bool值 用来表示是否触发过渡事件
        swiper.slidePrev(3000, false)
    })

    to.addEventListener('click', () => {
        // swiper.slideTo(index, speed, runCallbacks)
        // index: 要滑动到的索引
        // speed:毫秒为单位的动画播放时长
        // runCallbacks:一个bool值 用来表示是否触发过渡事件
        swiper.slideTo(2, 5000, false)
    })

    const swiper = new Swiper('.swiper', {
        effect: 'cube',

        // 分页模块
        pagination: {
            el: '.swiper-pagination',
            bulletActiveClass: 'my-bullet-active'
        },

        // 导航模块
        navigation: {
            nextEl: '.swiper-button-next',
            prevEl: '.swiper-button-prev',
        },

        // 滚动条模块
        scrollbar: {
            el: '.swiper-scrollbar',
        },

        // 盒子特效
        cubeEffect: {
            shadowOffset: 300,
            shadowScale: 0.5
        }
    });

    swiper.on('slideChangeTransitionEnd', (swiper) => {
        console.log(swiper.activeIndex);
    })
</script>
  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-09-15 02:18:45  更:2022-09-15 02:19:44 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 -2025/1/17 3:47:09-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码