概述
一、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变换需要依序执行以下步骤:
- 搭建3d场景,在父元素上设置:transform-style: preserve-3d;
- 在父元素上设置透视距离:perspective: 100px;
- 给场景添加演员,给场景元素添加子元素
- 在子元素上使用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可以充当发起网络请求的客户端工具
安装
- 在官网上点击download进行下载
- cdn: 共享资源节点
- 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对象的方法有两种
- 使用 css 选择器
let $li = $(‘ul>li’)
- 使用 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> world')
// 相当于dom对象的innerHTML
$p.html('<span style="color: red">hello</span> 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 是个专门用于播放滚动动画的工具
作用:用于制作滚动播放的播放器
使用思路
- swiper 安装好以后,进行布局
- 初始化一个 swiper 对象
- 按需要添加 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>
最后
以上就是受伤皮皮虾为你收集整理的移动互联应用学习内容总结的全部内容,希望文章能够帮你解决移动互联应用学习内容总结所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复