【学习前端第四十课】HTML5的多媒体技术

HTML5的多媒体技术

音频audio

<audio src="" controls></audio>
<!-- 或 -->
<audio>
	<source src="">
</audio>
属性

1、controls 是否再页面上显示控制器,它是一个单属性

2、autoplay 是否自动播放,它是一个单属性

3、currentSrc 是当前音频标签中src属性

4、currentTime 当前音乐的播放的进度时间,以秒为单位

5、duration 当前音乐的总时长,以秒为单位

6、ended 当前音频是否已经播放完毕,它会触发一个onended事件

7、loop 是否单曲循环,它也是一个单属性

8、muted 当前音频是否是静音,它也是一个单属性

9、networkState 当前网络链接状况:0表示空,1表示正在加载,2表示正在加载元数据,3表示已经加载了第一帧,4表示加载完成

10、volume 代表当前音频的音量,他是数字为值,范围是0-1之间

11、playbackRate 代表播放的速率,默认值是1

12、paused 代表当前音频是否处于暂停状态,他是一个单属性

13、readyState 表示当前音频的准备状态,媒体是否已经就绪(可以播放了),0表示数据不可用,1表示可以显示当前帧,2表示可以开始播放,3表示媒体可以从头播放到尾了

14、preload 预加载,三个属性值,metadata元数据,none不加载,auto自动

注意:

上面所有的单属性在作为DOM对象的属性的时候,值都由 true 或false来表示

事件

音频标签支持0级和2级事件

1、oncanplay 当音频已经在加载,并且可以开始播放了的时候触发的事件

2、onended 当音频播放结束时触发的事件,如果你设置了单曲循环loop,则这个事件永远不会触发

3、onloadeddata 媒体加载第一帧的时候触发

4、onplay 当音频播放的时候触发

5、onpause 当音频暂停的时候触发

6、onratechange 当音频播放的速率发生变化的时候触发

7、ontimeupdate 当音频播放的时候更新时间的时候触发,只要处于播放状态,这个事件会一直触发

8、volumechange 当volume属性值和muted属性值发生变化的时候触发

9、waiting 当前播放网络音频的时候,网络情况比较差,需要等待加载的时候(通俗的说就时缓冲的时候),会触发这个事件

方法

1、play()让当前视频播放

2、pause( ) 让当前视频暂停

案例

制作一个简易的音乐播放器,带有一个CD封面,当播放时CD封面转动,暂停时CD封面停止转动

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<link rel="stylesheet" href="./font_11gathc5v9d/iconfont.css">
		<style>
			*{
				padding:0;
				margin:0;
			}
			ul,ol{
				list-style:none;
			}
			a{
				text-decoration: none;
				color:#333;
			}
			img{
				vertical-align: middle;
				border:none;
			}
			.img-box{
				position: relative;
				width:90px;
				height:90px;
				display:flex;
				align-items: center;
				justify-content: center;
				animation: img-box-anli 15s linear infinite paused;
			}
			.img-box>img{
				border-radius:50%;
				position: absolute;
			}
			.img-box>span{
				position: absolute;
				font-size:30px;
				color:#fff;
			}
			@keyframes img-box-anli{
				to{
					transform: rotate(1turn);
				}
			}
		</style>
	</head>
	<body>
		<audio src="assets/这条街.mp3" controls="controls" id="bgm"></audio>
		<div class="img-box">
			<img src="img/1.jpg" alt="">
			<span class="iconfont icon-bofang"></span>
		</div>
		<script type="text/javascript">
			var bgm = document.querySelector("#bgm");
			var imgBox = document.querySelector(".img-box");
			
			//当音乐播放的时候切CD封面上面的图标
			bgm.addEventListener("play",function(){
				imgBox.children[1].classList.remove("icon-bofang");
				imgBox.children[1].classList.add("icon-zanting");
				imgBox.style.animationPlayState = "running";
			})
			bgm.addEventListener("pause",function(){
				imgBox.children[1].classList.remove("icon-zanting");
				imgBox.children[1].classList.add("icon-bofang");
				imgBox.style.animationPlayState = "paused";
			})
			imgBox.addEventListener("click",function(){
				if(bgm.paused){
					//当执行了play方法就会触发play事件
					bgm.play();
				}else{
					//当执行了pause方法就会触发pause事件
					bgm.pause();
				}
			})
		</script>
	</body>
</html>
在以上案例的基础上添加进度条

以下的代码是在以上案例的基础上添加的,注意甄别!!!!!!!

<style>
.progress-box{				
    display: flex;
    width:500px;
    justify-content: space-between;
    align-items: center;
}
.progress{
    height:10px;
    flex:1;
    border:solid 1px #000;
    margin:0 15px;
    background-image: linear-gradient(to right,red,red);
    background-repeat: no-repeat;
    background-size:0% 100%;
}
</style>

<div class="progress-box">
    <span class="current-time">00:00</span>
    <div class="progress"></div>
    <span class="duration-time">04:30</span>
</div>

<script>
function line(event){
    event = event || window.event;
    bgm.currentTime = event.offsetX / this.clientWidth * bgm.duration;
}
progress.addEventListener("click",line);

//在进度条上拖放
progress.addEventListener("mousedown",function(){
    progress.addEventListener("mousemove",line);
    progress.addEventListener("mouseup",function(){
        progress.removeEventListener("mousemove",line);
    })
})
</script>
再在以上的案例基础上再添加歌词

以下的代码是在以上案例的基础上添加的,注意甄别!!!!!!!

<style>
.lrc-box{
    width:fit-content;
    margin:auto;
    position: relative;
}
.lrctext1{
    font-size:48px;
    width:fit-content;
    position: absolute;
    left:0;
    top:0;
    z-index:-1;
}
.lrctext{
    font-size:48px;
    width:fit-content;
    background-image:linear-gradient(to right,red,red);
    background-repeat: no-repeat;
    -webkit-background-clip: text;
    color:transparent;
    background-size:0 100%;
}
</style>
<div class="lrc-box">
    <div class="lrctext">歌词再这里</div>
    <div class="lrctext1">歌词再这里</div>
</div>

<script>
//lrcArr匹配所有的歌词文字
var lrcArr = musicLrc.match(/(?<=\[\d{2}:\d{2}\.\d{3}\]).*/g);

//timeArr匹配所有的时间节点
var timeArr = [];
var regLrcTime = /\[(\d{2}):(\d{2}\.\d{3})\]/g;
//temp用来存放每次匹配到的返回的时间字段
var temp = "";
while((temp = regLrcTime.exec(musicLrc)) != null){
    var second = temp[1] * 60 + +temp[2];
    timeArr.push(second);
}

var lrcText = document.querySelector(".lrctext");
//每当播放时间更新的时候触发
bgm.addEventListener("timeupdate",function(){
    //for循环并不是为了批量做一些事情,而是只为了获得到一个i作为索引使用
    for(var i = 0; i < timeArr.length;i++){
        //通过判断时长数组调出时间与当前正在播放的时间做比较获得到当前歌曲所播放的时间因对的歌词的索引
        if(timeArr[i] > this.currentTime){
            break;
        }
    }
    //因为break的执行是再递增之后,所以获得到的索引会比我们实际需要的大1,所以减去1
    if(i != 0){
        i--;
    }
    //把i作为索引调出对应的歌词
    var lrc = lrcArr[i];
    lrcText.innerText = lrc;
    lrcText.nextElementSibling.innerText = lrc;

    //计算歌词的进度条
    if(i == timeArr.length - 1){
        var total = this.duration - timeArr[i];
    }else{
        var total = timeArr[i+1] - timeArr[i];
    }
    //当前歌词已经唱了多长
    var already = this.currentTime - timeArr[i];
    //计算百分比
    var percent = already / total * 100 + "%";
    lrcText.style.backgroundSize = percent + " 100%";
})
</script>

视频video

<video src="" width="500" height="300" controls id="v1"></video>

视频与音频十分相似,基本可以说是一模一样的用法,维度多了一些属性和方法

1、poster 视频海报

2、 requestFullScreen() 视频全屏播放

3、exitFullScreen() 退出全屏播放

4、requestPictureInPicture() 视频开始画中画播放

5、exitPictureInPicture() 退出画中画播放

针对video生产的HTML5的原生的视频播放器可以直接播放的视频格式非常少

video原生支持的视频格式

video/mp4

video/ogg

video/webm

以上三种视频格式除了mp4可以是一个主流格式之外,其他可以支持的格式非常的不常见,所以为了更好的使用视频功能,我们在实际开发过程一般都是使用一些第三方的视频播放器库

比较常用到的两种视频播放器库

1、videojs

2、aliplayer 这是一个阿里云框架中提供的一个服务

我们主要来看videojs

videojs

video.js是一个通过的在网页上嵌入视频播放器的库文件,video.js自动检测浏览器对HTML5的支持情况,如果不支持HTML5则自动转为使用Flash播放器

引入文件

<link rel="stylesheet" href="css/video-js.css">
<script src="js/video.js" type="text/javascript" charset="utf-8"></script>
加入video标签
<video width="800" height="500" poster="img/1.png" controls="controls" >
    <source src="video/01.mp4" type="video/mp4">
</video>

poster:是视频的缩略图,也就是未播放的时候现实的图片

controls :向用户现实播放器控件

获取需要控制的video标签
<script type="text/javascript">
    var player = videojs("v1");
</script>

通过video.js通过的videojs方法获取到需要控制的video标签

给控制的video标签添加样式
<video width="800" height="500" poster="img/1.png" controls="controls" id="v1" class="video-js vjs-default-skin" >
    <source src="video/01.mp4" type="video/mp4">
</video>

给video标签添加上videojs提供的样式,让它进行显示

播放按钮默认显示在左上,如果想显示在正中间可以是用 vjs-big-play-centered

通过上面的操作我们就可以获得到一个由videojs控制的播放器

videojs全局函数

video.js会为我们提供一个全局函数videojs 这个函数可以传入三个参数,在上面的操作步骤中我们就使用videojs这个全局函数只不过是传了一个参数

参数1: 填写video标签的id属性值,从而获取到需要控制的video标签

参数2: 配置项,传入一个对象,当获取到video的控制之后,我们可以通过配置项来设置播放器进行操作

参数3: 回调函数

常用配置项

autoplay: false, //自动播放
controls: true,  //显示底部控制栏
width:300,       //设置播放器显示宽度
height:300,      //设置播放器显示高度
loop: false,     //设置视频是否循环播放
muted: false,    //设置视频是否静音
poster: "",      //设置视频封面海报
src: "",         //设置播放器的视频源
techOrder: ['html5','flash'], //使用播放器的顺序,这里说名优先使用html5播放器,如果不支持使用flash播放器
plugins: {},    //插件
//sources: [{src:'',type:'video/mp4'}] ,//设置cource标签的属性
aspectRatio: "16:9",  //设置视频的宽高比
fluid: "false",       //是否自适应布局
preload: ""           //预加载   ‘auto‘ 自动;’metadata‘ 元数据信息 ,比如视频长度,尺寸等;‘none‘ 不预加载任何数据,直到用户开始播放才开始下载
常用事件

videojs为我们提供了一个它自己用于绑定事件的方法 on()

player.on("suspend",function(){
	console.log("延迟下载");
});

player.on("loadstart",function(){
	console.log("客户端开始请求数据的");
})

player.on("progress",function(){
	console.log("客户端开始请求数据的");
})

player.on("abort",function(){
	console.log("客户端主动终止下载的时候");
})

player.on("error",function(){
	console.log("请求数据是遇到错误");
})

player.on("stalled",function(){
	console.log("网络失速");
})

player.on("play",function(){
	console.log("开始播放")
})

player.on("pause",function(){
	console.log("暂停")
})

player.on("loadedmetadata",function(){
	console.log("成功获取资源长度");
})

player.on("loadeddata",function(){
	console.log("渲染播放画面")
})

player.on("waiting",function(){
	console.log("等待数据")
})

player.on("playing",function(){
	console.log("开始回放")
})

player.on("canplay",function(){
	console.log("可以开始播放")
})

player.on("canplaythrough",function(){
	console.log("可以播放,并且全部加载完毕")
})

player.on("seeking",function(){
	console.log("寻找中");
})

player.on("seeked",function(){
	console.log("寻找完毕")
})

player.on("timeupdate", function(){
	console.log("播放时间改变时")
})

player.on("ended",function(){
	console.log("播放结束")
})

player.on("retechange",function(){
	console.log("改变播放速度")
})

player.on("durationchange",function(){
	console.log("资源长度改变");
})

player.on("volumechange",function(){
	console.log("音量改变")
})
常用方法

其实这些方法的作用就时对播放器的属性进行设置,或者设置播放器的属性,所以说跟我们之前讲过的音频对象的属性调用其实差不多

play() 播放

pasue() 暂停

currentTime() 获取播放进度,可以通过传参来设置当前的播放进度

duration() 获取总时长,注意,这个方法在flash播放器下是无效的

volume() 获取当前播放器的音量,可以通过传参来设置当前播放器的音量

width() 获取当前播放器的宽度 ,传参可以设置当前播放器的宽度

height() 获取当前播放器的高度,传参可以设置当前播放器的高度

我们所使用的这些第三方库文件其实就是一个SDK

SDK(soft Development kit)软件开发工具包

软件开发工具包实际上就是一个已经做好的库文件,我们只需要引入这个库文件到我们的页面当中,我们就可以直接使用别人已经写好的功能,而不需要我们自己来编写功能,而SDK其实就是一种封装思维的体现,在这个工具包内,别人会把功能直接封装成一个函数,我们只需要直接调用传参即可,不需要理解其内部的功能结构,这样可以帮助我们快速进行程序开发,那么我们今天就接触到了第一个SDK工具包videojs

CDN(cloud/content delivery network) 云分发网络

CDN是为SDK的传播提供服务的一个云平台,我们可以通过一个网络地址,直接获取到一个SDK在自己的项目当中使用,而这个SDK的分发功能就是CDN提供的

base64格式

base64是一种加密的数据,它不可以直接阅读,常用于HTTP网络传输,在计算机当中所有的文件都可以使用base64的格式去表示,它需要借助HTML5中新出一个API,这个接口提供了一个构造函数 FileReader

FileReader

FileReader 对象允许web应用程序异步读取存储在用户计算机上面的文件(或原始数据缓冲区)的内容,在使用 fileBlob 对象执行要读取的文件

<img src="" alt="" class="img1">
<input type="file" id="file" onchange="fileChange(this)">

<script type="text/javascript">
function fileChange(ele){
    var img1 = document.querySelector(".img1");
    if(ele.files.length > 0){
        //说明它有文件
        var file = ele.files[0];
        //判断一下数据类型
        var reg = /^image\/(jpe?g|gif|png|bmp)$/;
        if(reg.test(file.type)){
            //说明它是一个图片文件,然后将这个图片文件转换成base64的格式
            var fileReader = new FileReader();
            fileReader.readAsDataURL(file);
            fileReader.onload = function(){
                img1.src = fileReader.result;
            }
        }
    }
}

</script>

代码分析:这里我们通过封装思维制作了一个用来加密等待上传的图片文件的一个方法,并且将这个图片进行预览,整个逻辑过程,就是通过表单的上传文件功能,先将需要上传的文件通过input标签获取到其文件路径,然后将该input标签作为DOM对象获取,在获取的表单DOM对象中有一个files属性,这个属性内容获取的就是当前input获取到的等待上传的文件信息,然后,我们通过files属性(类数组)将需要上传的文件信息调出赋值给一个方法体内生变的变量file,从而将需要上传的文件信息单独拿出来进行临时储存,然后再通过HTML5新增的FileReader接口方法,new一个接口对象,使用该接口对象中的 readAsDataURL 放法将获取到file变量中的文件信息传入到对象对象内进行加密处理,最后被加密的文件数据就是在接口对象的 result 属性中存储下来,供我们使用

注意:如果要加密上传的文件不是图片类型的文件需要修改方法体内的正则表达式

接着我们再来结合上面的内容进行一点拓展,我们之前制作的音乐播放器只能播放我们直接写好在代码内的音乐,现在结合上传讲的内容,我们来完成一个通过选择音频文件来进行播放的操作

在上面的代码中,我们使用的type="file" 来选择文件,但是这个文件选择框它不能设置样式,所以我们先可以单独设置一个按钮去完成

<audio controls="controls" id="bgm"></audio>
<hr>
<input type="file" style="display: none;" id="f1" onchange="fileChange(this)">
<button type="button" class="btn" onclick="chooseMusic()">选择音乐</button>
<script type="text/javascript">
    function chooseMusic(){
        var f1 = document.querySelector("#f1");
        f1.click();
    }

    function fileChange(ele){
        if(ele.files.length > 0){
            var file = ele.files[0];
            var reg = /^audio\/mpeg$/;
            if(reg.test(file.type)){
                var fileReader = new FileReader();
                fileReader.readAsDataURL(file);
                //文件读取完毕,会触发onload事件
                fileReader.onload = function(){
                    var base64Str = fileReader.result;
                    var bgm = document.querySelector("#bgm");
                    bgm.src = base64Str;
                }
            }
        }
    }
</script>

video调用摄像头

<video width="500" height="500" controls id="v1"></video>
<hr>
<button type="button" id="btn1" onclick="openCamera()">开启摄像头</button>
<script type="text/javascript">
    function openCamera(){
        navigator.getUserMedia({
            //video代表视频
            video: true,
            //audio代表音频
            audio: false
        },function(stream){
            //成功回调函数
            console.log("成功");
            var v1 = document.querySelector("#v1");
            //将这个流赋值给v1
            v1.srcObject = stream;
            v1.play();
        },function(error){
            //失败回调函数
            console.log("失败了");
            console.log(error);
        })
    }
</script>

画布

画布是HTML5新出的一个标签,它指在用户能够在页面上面完成任意的绘画效果,它有2D平面绘画和3D立体绘画。我们前端程序员可以把画布看成是一个模拟的屏幕,在这个屏幕可以显示任何东西

画布创建
<canvas width="500" height="400" id="c1"></canvas>

注意:画布不能在css里面设置width/height,如果要设置宽高只能在html标签的属性中设置

画布的创建非常简单,它就是一个标签,但是如果我们想在上面绘画,则需要一个画布对象,这个对象我们也叫绘画上下文对象

var c1 = document.querySelector("#c1");
//得到画笔,画笔也叫绘画上下文
var ctx = c1.getContext("2d");

我们通过上面的方法 getContext('2d') 来获取画布的2D绘画上下文,有了画布和画笔我们就可以开始画了

我们在绘画之前要分清楚两件事,在2D绘画中,绘画的行为只有两种

1、描边 stroke 描边出来的东西一定事空心的

2、填充 fill 填充出来的东西一定事实心的

常用的属性和方法

1、font 用于设置字体的大小样式

2、strokeStyle 设置描边的颜色

3、fillStyle 设置填充的颜色

4、beginPath() 开始一个新路径,相当于一个提笔的操作

5、moveTo(x,y) 将比移动到某一个坐标,不画线

6、lineTo(x,y) 画一条线到某一个坐标

7、lineWidth 描边线条的粗细

8、lineCap 线条末端的形状,butt 方头 ,round 圆头 ,square

9、closePath() 闭合路径,把开始和结束的点链接起来

10、stroke() 描边方法,可以将一条路径描边

11、fill() 填充方法,把闭合的路径进行内部填充

12、arc(x,y,radius,start,end,direction) 画一个圆,画圆的时候,它是以弧度为单位在画,从3点种方法开始,默认是顺时针

var c1 = document.querySelector("#c1");
var ctx = c1.getContext("2d");
//第一步:提笔
ctx.beginPath();
//第二步:确定一个落笔的起点位置
ctx.moveTo(0,0);
//第三步:画一条线
ctx.lineTo(100,100);
//第四步:描边
ctx.stroke();
//第五步:拿一根粗点的笔
ctx.beginPath();
ctx.lineWidth = 5;
ctx.strokeStyle = "#FF0000";
ctx.moveTo(100,100);
ctx.lineTo(200,100);
ctx.stroke();
绘画矩形

1、rect(x,y,width,height) 绘制一个矩形路径,然后再调用 stroke() 描边或 fill() 填充

2、strokeRect(x,y,width,height) 绘制一个带描边的矩形,一次成型

3、fillRect(x,y,width,height) 填充一个矩形,一次成型

4、clearRect(x,y,width,height) 清除一个矩形区域

绘制图像

在画布里面绘制图片分为静态绘制和动态绘制

绘制图片使用方法 drawImage(img,x,y,width,height)

静态绘制
<img src="img/1.png" id="img1" alt="">
<hr>
<canvas id="c1" width="300" height="200"></canvas>
<script type="text/javascript">
    var c1 = document.querySelector("#c1");
    var ctx = c1.getContext("2d");

    //静态绘制
    var img1 = document.querySelector("#img1");
    img1.onload = function(){
        ctx.drawImage(img1,50,50,300,200)
    }
</script>

1、静态绘制是页面上面已经存在这个图片,然后我们获取这个图片之后,使用drawImage方法来绘制图片

2、绘制图片的时候一定要等图片的onload完成(也就是说要等图片加载完)

重点:静态绘制最重要的一个点就是可以实现视频的截屏

案例一:使用静态绘制实现视频截图并下载

<p>静态绘制一定是绘制一个已经存在的东西</p>
<video src="video/01.mp4" width="400" height="400" id="v1" controls="controls"></video>
<hr>
<canvas id="c1" width="400" height="400"></canvas>
<hr>
<button type="button" onclick="takePhoto()">截图</button>
<script type="text/javascript">
    var v1 = document.querySelector("#v1");
    var c1 = document.querySelector("#c1");
    var ctx = c1.getContext("2d");
    function takePhoto(){
        //将视频里面的画面绘制到画布上面
        ctx.drawImage(v1,0,0,400,400);
        //将画布的信息转为base64, dataURL就是base64格式
        var base64Str = c1.toDataURL("image/png");
        var a = document.createElement("a");
        a.href = base64Str;
        //<a href="image/xxxx.png"></a>
        a.download = "截图.png";
        a.click();
    }
</script>
案例二,摄像头截图
<video id="v1" width="400" height="400"></video>
<canvas id="c1" width="400" height="400"></canvas>
<button type="button" onclick="openCamera()">打开摄像头</button>
<button type="button" onclick="takePhoto()">拍照</button>
<script type="text/javascript">
    var v1 = document.querySelector("#v1");
    var c1 = document.querySelector("#c1");
    var ctx = c1.getContext("2d");

    function openCamera(){
        navigator.getUserMedia({
            video:true,
            audio:false
        },function(stream){
            v1.srcObject = stream;
            v1.play();
        },function(error){
            console.log(error)
        })
    }

    function takePhoto(){
        ctx.drawImage(v1,0,0,400,400);
        var base64Str = c1.toDataURL("image/png");
        var a = document.createElement("a");
        a.href = base64Str;
        a.download = "摄像头接头.png";
        a.click();
    }
</script>
动态绘制

就是实时的创建我们需要绘制的素材,然后再去绘制

<canvas id="c1" width="400" height="400"></canvas>
<script type="text/javascript">
    var c1 = document.querySelector("#c1");
    var ctx = c1.getContext("2d");

    // var img = document.createElement("img");
    var img = new Image();
    img.src = "img/1.png";
    img.addEventListener("load",function(){
        ctx.drawImage(img,0,0,300,200);
    })
</script>

代码分析:

1、在上面的代码中,我们动态的创建一个图片,然后将这个图片 onload 之后再去绘制

2、我们图片的创建可以使用 document.createElement("img") 也可以使用 new Image() 来完成

渐变设置

渐变再之前的css里面我们已经接触过了,现在在canvas当中也有渐变,它主要是线性渐变和径向渐变

使用线性渐变

var c1 = document.querySelector("#c1");
var ctx = c1.getContext("2d");
ctx.strokeRect(100,100,300,50);
//创建线性渐变
var gradient = ctx.createLinearGradient(100,100,400,150);
gradient.addColorStop(0,"red");
gradient.addColorStop(0.5,"orange");
gradient.addColorStop(1,"blue");
ctx.fillStyle = gradient;
ctx.fillRect(100,100,300,50);
径向渐变
var c1 = document.querySelector("#c1");
var ctx = c1.getContext("2d");
//创建径向渐变
ctx.strokeRect(100,200,200,200);
var gradient = ctx.createRadialGradient(200,300,50,200,300,100); //前三个渐变开始的圆心坐标+半径,后三个渐变结束的圆心+半径
gradient.addColorStop(0,"red");
gradient.addColorStop(1,"blue");
ctx.fillStyle = gradient;
ctx.fillRect(100,200,200,200)
绘制文字

1、strokeText()描边文字

2、fillText() 填充文字

3、textAlign 设置文字的水平对齐,它的值 start/center/end 左中右三个位置

4、textBaseline 设置文字的垂直对齐,默认是基线,还有 top/middle/bottom 上中下三个位置

变换

1、translate(x,y) 移动画布的起点位置

2、rotate(angle) 它是以弧度为单位,对画布进行旋转

配置的保存与还原

1、save() 将当前的配置保存起来,配置进入栈操作

2、restore() 将配置栈里面的配置进行出栈操作,还原配置

var c1 = document.querySelector("#c1");
var ctx = c1.getContext("2d");

ctx.font = "32px 微软雅黑";
ctx.fillStyle = "black";
ctx.fillText("第一次",0,50);
ctx.save();  //保存之前的画笔配置,配置入栈

ctx.font = "16px 宋体";
ctx.fillStyle = "red";
ctx.fillText("第二次",0,100);
ctx.save(); //保存之前的画笔配置,配置入栈

ctx.font = "48px 华文楷体";
ctx.fillStyle = "blue";
ctx.fillText("第三次",0,150);

//-----------------------------------------------------
ctx.restore();  //将之前的配置出栈
ctx.fillText("第四次",0,250);

ctx.restore(); //将之前的配置出栈
ctx.fillText("第五次",0,300);

ctx.restore();
ctx.fillText("第六次",0,350);

ctx.restore();
ctx.fillText("第七次",0,400);
使用图像数据

在canvas的画布上面,图像的数据是可以转换base64的,但是还可以使用另外一种数值来表示,这个数值就是rgba,我们可以通过画布来获取图像上面的原始数据(rgba数据)

1、ctx.getImageData() 在画布上获取图像数据

2、ctx.putImageData() 将一个图像数据放置到画布上面

<img src="img/1.jpg" id="img1" alt="">
<hr>
<canvas id="c1" ></canvas>
<script type="text/javascript">
    var c1 = document.querySelector("#c1");
    var ctx = c1.getContext("2d");
    var img1 = document.querySelector("#img1");
    img1.addEventListener("load",function(){
        c1.height = img1.clientHeight;
        c1.width = img1.clientWidth;
        ctx.drawImage(img1,0,0,img1.clientWidth,img1.clientHeight);
        //开始获取图像数据
        var imageData = ctx.getImageData(0,0,c1.width,c1.height);
        console.log(imageData);
        for(var i = 0;i < imageData.data.length;i += 4){
            var r = imageData.data[i];
            var g = imageData.data[i+1];
            var b = imageData.data[i+2];
            var avg = parseInt((r + g + b) / 3);
            imageData.data[i] = avg;
            imageData.data[i+1] = avg;
            imageData.data[i+2] = avg;
        }
        //将改好的图像数据再放回到画布里面去
        ctx.putImageData(imageData,0,0);
    })
</script>

代码分析:

1、进行静态绘制,将图片绘制到画布当中,这部会使用到 drawImage方法

2、获取到画布中的图像数据,这步会使用到 getImageData方法

3、将获取到的所有的rgba数据中rgb部分的值进行修改,这步会用到图像数据中的 data 属性

4、把修改好的数据在放回到画布中去,这步会用到 putImageData 方法

刮刮乐效果模拟

<style>
*{
    padding:0;
    margin:0;
}
.box{
    height:50px;
    box-sizing: border-box;
    display:flex;
    justify-content: center;
    align-items: center;
    position: relative;
    margin-top:300px;
    border:solid 1px #000;
}
.result-text{
    font-size:28px;
}
#c1{
    position:absolute;
    left:0;
    top:0;			
}
</style>
<div class="box">
    <div class="result-text"></div>
    <canvas id="c1"></canvas>
</div>
<script type="text/javascript">
    var resultText = document.querySelector(".result-text");
    var resultArr = ["一等奖","二等奖","三等奖","谢谢回顾"];
    //生产一个0-99之间的随机数
    var temp = parseInt(Math.random() * 100);
    if(temp < 70){
        resultText.innerText = resultArr[3];
    }else if(temp < 85){
        resultText.innerText = resultArr[2];
    }else if(temp < 95){
        resultText.innerText = resultArr[1];
    }else if(temp < 100){
        resultText.innerText = resultArr[0];
    }
    var box = document.querySelector(".box");
    var c1 = document.querySelector("#c1");
    c1.width = box.clientWidth;
    c1.height = box.clientHeight;
    var ctx = c1.getContext("2d");
    ctx.fillStyle = "#aaa";
    ctx.fillRect(0,0,c1.width,c1.height);

    c1.addEventListener("mousedown",function(event){
        event = event || window.event;
        if(event.button === 0){
            c1.addEventListener("mousemove",c1MouseMove);
        }
    })
    function c1MouseMove(event){
        event = event || window.event;
        ctx.clearRect(event.offsetX,event.offsetY,4,4);
    }
    c1.addEventListener("mouseup",function(){
        c1.removeEventListener("mousemove",c1MouseMove);
    })
</script>

代码分析:

1、先确定获奖概率

2、将画布盖在奖项信息的上面

3、在画布上绘制一个填充矩形将获奖信息掩盖

4、给画布绑定事件使用 clearRect() 来清除覆盖在上面的矩形


这节课内容有点多,坚持看完就已经很厉害了
静下心来,静能养神,静可生慧。

  • 10
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值