绘制渐变

前言

绘制一条线段 让这个线段的宽度是10 颜色是蓝色

var canvas = document.getElementById('myCanvas');
var cxt = canvas.getContext('2d');
cxt.lineWidth = 10;//设置线宽
cxt.strokeStyle = 'blue';//设置线的颜色
cxt.beginPath();//闭合上一次路径
cxt.moveTo(100,100);//绘制线条开始路径
cxt.lineTo(300,300);//绘制线条结束路径
cxt.stroke();//绘制线条

如上:我们矩形,圆形和线条的时候都是绘制单一颜色的,那么canvas这个元素给我们提供了两个方式来绘制渐变

基础知识

线性渐变

  1. cxt.createLinearGradient(200,100,300,300);创建线性渐变
  2. cxt.createLinearGradient(开始渐变X方向,开始渐变Y方向,结束渐变X方向,结束渐变Y方向);

  3. 两个直线确定一条直线(渐变的开始和结束) 这个直线就是渐变的方向

径向渐变

  1. cxt.createRadialGradient(250,200,10,200,200,80); 创建径向渐变
  2. cxt.createRadialGradient(内部圆心的X方向,内部圆心的Y方向,内部圆心的半经,外部圆的X方向,外部圆的Y方向,外部圆的半经,);

  3. 先添加里层的圆 在添加外部的圆

cxt.createLinearGradient和cxt.createLinearGradient方法创建线性渐变和径向渐变,返回结果是一个颜色对象,然后颜色对象上面有一个addColorStop方法来添加颜色的终止点,在让画笔的颜色应用于颜色对象即可

添加渐变的颜色终止点

颜色对象上面的addColorStop方法来添加渐变的终止点

添加渐变的颜色终止点(也可以写多个) ,0-1表示的是渐变起点-渐变终点

  1. color.addColorStop(0,'red'); 添加颜色的终止点

  2. color.addColorStop(渐变的范围,渐变的颜色);

  3. addColorStop :add(添加) color(颜色) stop(停止的点)

让画笔的颜色应用渐变对象

  1. cxt.fillStyle = color; 让实心矩形应用渐变对象
  2. cxt.strokeStyle = color; 让空心矩形应用渐变对象

线性渐变

var canvas = document.getElementById('myCanvas');
var cxt = canvas.getContext('2d');
//创建线性渐变 返回结果是一个颜色对象
var color = cxt.createLinearGradient(200, 100, 300, 300);
//添加渐变颜色的终止点
color.addColorStop(0,'red');
color.addColorStop(0.5,'green');
color.addColorStop(1,'blue');
//让画笔应用于线性渐变对象
cxt.fillStyle = color;
//绘制一个线性渐变的矩形
cxt.fillRect(200,100,200,200);

通过画笔上面的createLinearGradient方法来创建一个线性渐变,然后这个返回结果是一个颜色对象,颜色对象上面的addColorStop方法来创建渐变颜色的终止点,然后在让画笔颜色应用于这个渐变对象,在通过fillRect方法绘制一个带有线性渐变的矩形

径向渐变 

var canvas = document.getElementById('myCanvas');
var cxt = canvas.getContext('2d');
//创建线性渐变 返回结果是一个颜色对象
var color = cxt.createRadialGradient(250, 200, 10, 200, 200, 80);
//先添加里层的圆 在添加外部的圆
//添加颜色的终止点 在直径方向发生渐变
color.addColorStop(0, 'red');
color.addColorStop(1, 'blue');
//让画笔应用于线性渐变对象
cxt.fillStyle = color;
//绘制一个线性渐变的矩形
cxt.fillRect(100,100,200,200);

通过画笔上面的createRadialGradient方法来创建一个径向渐变,然后这个返回结果是一个颜色对象,颜色对象上面的addColorStop方法来创建渐变颜色的终止点(先添加里层的圆 在添加外部的圆,添加颜色的终止点 在直径方向发生渐变),然后在让画笔颜色应用于这个渐变对象,在通过fillRect方法绘制一个带有径向渐变的矩形

绘制图片和视频

前言

在H5中canvas的功能是很强大的,他不仅仅能绘制矩形,圆形,线条,曲线,文字,那他还可以绘制图片和视频

绘制图片(基础知识)

绘制图片

  1. cxt.drawImgae(图片节点,x,y,w,h) 绘制图片

  2. cxt.drawImage(绘制图片的节点,距离画布的X方向绘制图片,距离画布的Y方向绘制图片,绘制图片的宽度,绘制图片的高度)

裁切图片

  1. cxt.drawImage(图片节点,sx,sy,sw,sh,x,y,w,h) 裁剪图片
  2. 从图片的左上角开始裁切  裁切的起点sx,sy  裁切的区域是sw*sh
  3. 从画布的左上角开始绘制  绘制的起点x,y    绘制的区域是w*h

cxt.drawImage(裁剪图片的节点,要裁剪图片的水平距离,要裁剪图片的竖直距离,要裁剪图片的宽度,要裁剪图片的高度,要绘制图片的水平方向(距离画布),要绘制图片的竖直方向(距离画布),要绘制图片的宽度,绘制图片的高度)

前四个数值是开始裁剪图片的区域 后四个数值是绘制图片的区域

绘制图片

绘制图片:获取到canvas元素,在通过getContext方法获取到canvas上面的2d画笔

然后通过 new Image()的方法创建img节点(用new Image方式创建的节点跟用document.createElement方式创建节点完全一致)

在通过img节点上面的src属性添加图片的路径(这一步表示向本地请求资源是异步代码),然后给img注册onload事件(等图片资源加载完毕触发事件处理函数) ,然后在通过画笔上面的drawImage方法画出整张图片

var canvas = document.getElementById('myCanvas');
var cxt = canvas.getContext('2d');
//创建img节点
var oImg = new Image();
//等图片请求完在赋值给节点上面的src(会下载这张图片)
oImg.src = '1.png';
//等图片加载完毕触发onload事件
oImg.onload = function(){cxt.drawImage(oImg,0,0,canvas.width,canvas.height)
}

剪切图片

剪切图片:剪切图片方法和绘制图片的方法一样,只不是剪切图片drawImage方法上面接收的参数比绘制图片多

剪切图片接收的参数:

  • cxt.drawImage(图片节点,sx,sy,sw,sh,x,y,w,h)
  • 从图片的左上角开始裁切  裁切的起点sx,sy  裁切的区域是sw*sh
  • 从画布的左上角开始绘制  绘制的起点x,y    绘制的区域是w*h
var canvas = document.getElementById('myCanvas');
var cxt = canvas.getContext('2d');
//创建img节点
var oImg = new Image();
//等图片请求完在赋值给节点上面的src(会下载这张图片)
oImg.src = '1.png';
//等图片加载完毕触发onload事件
oImg.onload = function(){cxt.drawImage(oImg, 400, 200, 560, 470, 100, 100, 200, 500);
}

绘制视频(基础知识)

  1. cxt.drawImage(视频节点,x,y,w,h)  绘制视频
  2. cxt.drawImage(视频节点,绘制视频的水平方向,绘制视频的竖直方向,绘制视频的宽度,绘制视频的高度)

绘制图片和绘制视频都是通过drawImage方法来绘制的,但是对于绘制静止的视频来说就是相当于图片

在视频中每一帧的事件是13毫秒,这是视频播放的最快的速度

我们绘制视频有两种方法

video 是一个资源 必须等到该资源下载完成才能够绘制视频(这一步是在向本地请求视频资源)是异步代码

第一种方法(常用)

在循环定时器里面用drawImage方法绘制视频

因为浏览器最快的时间间隔是13毫秒,然后我们通过循环计时器每13毫秒绘制出一个视频画面,这样就不会出现视频播放留白现象了

var canvas = document.getElementById('myCanvas');
var cxt = canvas.getContext('2d');
//获取视频节点
var video = document.querySelector('video');
//video 是一个资源 必须等到该资源下载完成才能够绘制视频
//每隔13ms  就绘制视频中的一帧(视频中的某一个画面)
setInterval(function(){cxt.drawImage(video,0,0,500,500);
},13);//浏览器最快的时间间隔是13毫秒

第二种方法(不推荐)

给视频节点添加oncanplay事件里面用drawImage方法绘制视频

因为视频也是个资源,有可能这个视频资源体积太大导致短时间加载不出来,这就导致了视频在此之间留白现象,给视频节点注册一个onload事件表示 当可以播放视频在绘制视频

但是这样有一个缺点:那就是只能绘制出来某一个视频画面

var canvas = document.getElementById('myCanvas');
var cxt = canvas.getContext('2d');
//获取视频节点
var video = document.querySelector('video');
//video 是一个资源 必须等到该资源下载完成才能够绘制视频
video.oncanplay = function(){cxt.drawImage(video,0,0,500,400)
}

以上方法绘制视频就不会出现视频留白现象了

画布变换

前言

canvas这个元素向我们提供了四种让画布变换的方式,能让我们更好的完成canvas中的某些特效

基础知识

  1. cxt.save()  保留上次的画布状态 常用
  2. cxt.restore() 释放上次保存的画布状态 常用

  3. cxt.translate(距离画布水平方向,距离画布竖直方向)  设置绘制图形的起点位置 常用

  4. cxt.rotate(角度) 让画布旋转 Math.PI = 180°

  5. cxt.scale(水平方向缩放,竖直方向缩放); 让画布缩放

我们在绘制图形的时候,不管在上面情况下都是基于画布的左上角来绘制的

绘制两条线段(用translate方法设置图形的起点位置)

var canvas = document.getElementById('myCanvas');
var cxt = canvas.getContext('2d');
//绘制一条线段
cxt.beginPath();
cxt.moveTo(100,100);
cxt.lineTo(300,100);
cxt.closePath();
cxt.stroke();
//绘制另一条线段
cxt.beginPath();
cxt.moveTo(50,50);
cxt.lineTo(200,50);
cxt.closePath();
cxt.stroke();

上面绘制的两条线段都是基于画布左上角0,0位置开始绘制的,那该怎么更改绘制图形的起点位置呢

var canvas = document.getElementById('myCanvas');
var cxt = canvas.getContext('2d');
//绘制第一条线段
cxt.beginPath();
//设置绘制图形的起点位置
// cxt.translate(画布的水平方向,画布的竖直方向);
//现在画的所有的点都是基于 50 50 这个位置起点画出
cxt.translate(50,50);
cxt.moveTo(100,100);
cxt.lineTo(100,200);
cxt.closePath();
cxt.stroke();
//绘制第二条线段
cxt.beginPath();
cxt.moveTo(100,100);
cxt.lineTo(200,100);
cxt.closePath();
cxt.stroke();

这样开始绘制图形路径之前用translate方法先设置图形的起点位置,以后绘制图片都是以50,50这个点画出了

绘制所有图形的参考点是50 50 这个位置(如下)

var canvas = document.getElementById('myCanvas');
var cxt = canvas.getContext('2d');
cxt.beginPath();
cxt.translate(50,50);
cxt.arc(0,0,30,0,Math.PI*2);
cxt.stroke();

那该怎么让一个图形基于50 50 这个点绘制 ,让另一个图形基于 0 0 这个点绘制呢

解决方案(用cave保留画布的状态,在用restore释放保存画布的状态)

当画笔开始画的时候用cave方法保留上一次画布的初始状态(在translate之前保留画布的状态),然后在到画下一个图形的时候用restore方法释放当前保留画布的状态

代码如下

var canvas = document.getElementById('myCanvas');
var cxt = canvas.getContext('2d');
//一旦执行save那么画笔的初始状态就会被保留
cxt.save();//保留上一次画布的状态
cxt.beginPath();
//设置绘制图形的起点位置
cxt.translate(50,50);
cxt.moveTo(100,100);
cxt.lineTo(100,200);
cxt.closePath();
cxt.stroke();
//释放上一次保留画布的状态
cxt.restore();//从0 0 起点开始绘制图形
cxt.beginPath();
cxt.arc(30,30,30,0,Math.PI*2);
cxt.stroke();

注意:有save保存上一次画布的状态必须有restore释放上一次画布的状态

使用translate设置绘制图形的起点位置,就要先保留一下画布的状态(save保留画布的状态)在释放(restore释放画布的状态)

绘制画布的主流还是要以画布的左上角为参考的

那该怎么让一张画布旋转和缩放呢

var canvas = document.getElementById('myCanvas');
var cxt = canvas.getContext('2d');
cxt.beginPath();
//让画布旋转
//cxt.rotate(角度(Math.PI=180°));
cxt.rotate(Math.PI/6);
//缩放画布
cxt.scale(1.5,1.5);
cxt.moveTo(250,250);
cxt.lineTo(250,100);
cxt.closePath();
cxt.stroke();

使用rotate方法可以让画布旋转,使用scale方法可以让画布缩放

使用translate改变参考做时钟的指针比较简单(代码如下)都是基于250,250这个点展开的绘制

var canvas = document.getElementById('myCanvas');
var cxt = canvas.getContext('2d');
cxt.translate(250, 250);
function needle(needle) {cxt.beginPath();cxt.strokeStyle = needle.color;cxt.lineWidth = needle.linewidth;cxt.rotate(needle.rotate);cxt.moveTo(0, 0);cxt.lineTo(0, -needle.line);cxt.stroke();
}
//绘制时针
needle({color: 'blue',linewidth: 4,rotate: Math.PI / 2,line: 150,
})
//绘制分针
needle({color: 'green',linewidth: 3,rotate: Math.PI / 3,line: 100,
})
//绘制秒钟
needle({color: 'red',linewidth: 2,rotate: Math.PI / 5,line: 50,
})

制作马赛克

前言

什么是马赛克?

马赛克是指将影像特定区域的色阶细节劣化并造成色块打乱的效果,让人看不清具体的画面。

因为马赛克这种模糊看上去有一个个的小格子组成,便形象的称这种画面为马赛克。其目的通常是使之无法辨认。

基础知识

创建某一个区域的像素点

  1. cxt.createImageData(w,h)  创建w*h的区域来存储像素点
  2. cxt.createImageData(存储像素点的宽度,存储像素点的高度)

获取某一个区域的像素点

  1. cxt.getImageData(x,y,w,h)  从x,y点开始获取w*h区域的像素点
  2. cxt.getImageData(距离画布水平方向获取像素,距离画布竖直方向获取像素,获取画布像素的宽度,获取画布像素的高度)

填充某一个区域的像素点

  1. cxt.putImageData(数据,x,y)  从x,y点开始往画布里填充数据 put(丢)

  2. cxt1.putImageData(颜色数据,从画布的X轴方向丢数据, 从画布的Y轴看书方向丢数据)

制作马赛克

我们在制作马赛克的时候需要两个canvas标签(如下)

HTML部分

<canvas id="canvas" width="500" height="400"></canvas>
<canvas id="canvas1" width="500" height="400"></canvas>

CSS部分

<style>*{margin:0;padding:0;}canvas{display: block;border: 2px solid blue;margin: 50px auto;}
</style>

一个canvas标签是填充原图像的,而另一个canvas标签是填充马赛克图像的

第一步:获取两个canvas元素和画笔

//获取原图的canvas元素和画笔
var canvas1 = document.getElementById('canvas1');
var cxt1 = canvas1.getContext('2d');
//获取马赛克图的canvas元素和画笔
var canvas2 = document.getElementById('canvas2');
var cxt2 = canvas2.getContext('2d');
console.log(canvas1,canvas2)

第二步:在通过canvas的方式把第一个canvas标签绘画出来一张图片

//获取原图的canvas元素和画笔
var canvas1 = document.getElementById('canvas1');
var cxt1 = canvas1.getContext('2d');
//获取马赛克图的canvas元素和画笔
var canvas2 = document.getElementById('canvas2');
var cxt2 = canvas2.getContext('2d');//绘制图片
//创建img节点
var oImg = new Image();
//把img节点的src属性赋值
oImg.src = '1.png';//请求图片数据(异步代码)
//等图片加载完成触发onload事件的回调函数
oImg.onload = function(){//画出图片cxt1.drawImage(this,0,0,500,400);//draw(画)
}

当前图片是宽500px,高400px,那就是当前图片是500*400个像素拼出来的一张图片

然后在通过getImageData方式获取画布中某个区域的像素点(代码如下)

然后返回结果是一个对象,是一个图片像素数据对象

var imgaeData = cxt.getImageData(0, 0, 500, 400);//获取图片数据

图片像素数据对象里面的data属性存储了你图片的真正的数据(图片中的500*400像素点组成了这个data数据)

他是以水平方向500个像素点 竖直方向400个像素点 拼接出来了一张图片

然后获取图片的像素点的颜色,通过rgba形式来表示的(rgba(r,g,b,a)就是相当于一个像素点有四个数据)

500*400 = 200000个像素点 200000*4 = 800000 所以一张图片是以800000万个数据组成的

800000个颜色数据 以rgba四个数据是一个像素点的形式展现出来 (一个像素点有4个颜色数据)

注意:

在这里面的rgba颜色值表现是形式是把 最后一项透明度分成0-255来表示的

rgba(0-255, 0-255,0-255, 0-255)

制作马赛克的思路

让图片以10个像素的固定颜色形式填充的图片

让第一个像素点的 r值 g值 b值 a值 到第十个像素点 的rgba值一样 以此类推

完整制作马赛克代码(操作像素)

<script>//获取原图的canvas元素和画笔var canvas1 = document.getElementById('canvas1');var cxt1 = canvas1.getContext('2d');//获取马赛克图的canvas元素和画笔var canvas2 = document.getElementById('canvas2');var cxt2 = canvas2.getContext('2d');//绘制图片//创建img节点var oImg = new Image();//把img节点的src属性赋值oImg.src = '1.png';//请求图片数据(异步代码)//等图片加载完成触发onload事件的回调函数oImg.onload = function(){//画出图片cxt1.drawImage(this,0,0,500,400);//draw(画)//获取图片数据var imgaeData = cxt1.getImageData(0, 0, 500, 400);/*马赛克 4(rgba的个数)*10(每10个像素是一样的rgab值) = 40(每40循环一次)每十个像素点的 r g b a值都一样0-10 r g a b 都一样11-20 r g a b 都一样21-30 r g a b 都一样*/var num = 40;for(var i=0;i<imgaeData.data.length;i+=num){//每隔4个点(rgba)就再次跟新下一个点的值for (var j = 1; j < num / 4; j++) {imgaeData.data[i + 4 * j] = imgaeData.data[i];imgaeData.data[i + 1 + 4 * j] = imgaeData.data[i + 1];imgaeData.data[i + 2 + 4 * j] = imgaeData.data[i + 2];imgaeData.data[i + 3 + 4 * j] = imgaeData.data[i + 3];};};//追加图片数据cxt2.putImageData(imgaeData, 0, 0);};
</script>

创建像素

通过createImageData方法来创建500*400的一个区域的像素点,在通过for循环循环遍历图片数据对象中的data属性,并且往里面循环追加随机数并且向下取整,然后通过putImageData方法往整个画布内部添加像素点

var canvas = document.getElementById('canvas1');
var cxt = canvas.getContext('2d');//创建像素点
//自定义一个空的图片像素数据对象
var imageData = cxt.createImageData(500 , 400);
//500*400 = 200000 个像素点有已rgab来表示 200000 *4 = 800000 //当前是我们认为创建的一个像素点是没有任何像素的
//随机生成像素点
for(var i=0;i<imageData.data.length;i++){imageData.data[i] = Math.floor(Math.random() * 256);
}
//追加图片数据
cxt.putImageData(imageData,0,0)

H5canvas(渐变,绘制图片和视频,画布变换,制作马赛克)相关推荐

  1. 中间视频上下图片的视频效果怎么制作

    上下是图片文字,中间是视频的效果非常常见,是主流的竖屏视频呈现方式,也可称为背景填充效果.那么这样的效果,该如何实现呢?下面随小编一起来学习一下. 当视频是竖屏时 在视频剪辑高手的"剪辑视频 ...

  2. canvas - drawImage()方法绘制图片不显示的问题

    canvas有个很强大的api是drawImage()(w3c): 他的主要功能就是绘制图片.视频,甚至其他画布等. 问题: 慕名赶来,却一脚踩空,低头一看,地上一个大坑. 事情是这样的,在我看完w3 ...

  3. 如何用手机快捷设计品牌宣传的海报图片和视频

    随着移动互联网的普及,越来越多的品牌宣传企划活动方案,都需要用到各种精美的海报图片和宣传视频,这对企划工作来说是一个耗时又耗精力的工作,并且还不一定能做出风格迥异的作品. 得益于人工智能技术的进步,现 ...

  4. android音频开发6,Android 音视频开发(一) : 通过三种方式绘制图片

    想要逐步入门音视频开发,就需要一步步的去学习整理,并积累.本文是音视频开发积累的第一篇. 对应的要学习的内容是:在 Android 平台绘制一张图片,使用至少 3 种不同的 API,ImageView ...

  5. 安卓音视频开发(1)—— 三种方式绘制图片

    作为应届生,刚入职公司,现在想从零开始学习一个全新的领域--音视频开发,仅此记录一下. ImageView绘制图片 这种常规的绘制图片方式,简单粗暴. String pathName = Enviro ...

  6. canvas在舞台上点击后图片旋转_View绘制系列(10)Canvas基础变换

    Canvas基础变换 前面学习了Canvas相关的一些绘制方法,不知道大家发现没?我们都是根据左上角(0,0)点算出来新的坐标,然后再绘制,这样明显不符合我们平常基于坐标原点绘制的习惯,那么我们能不能 ...

  7. 抖音短视频APP开发通过三种方式绘制图片

    (一)ImageView绘制图片 (1)将图片分别放入mipmap-hdpi.assets (2)布局文件: <?xml version="1.0" encoding=&qu ...

  8. 音视频开发之旅(一)三种方式绘制图片

    在android开发中我们最常使用的绘制图片的方式就是ImageView,设置src.那么有没有其他方案可以实现图片的绘制呐? 三种方案 通过Imageview设置setImageBitmap fin ...

  9. 音视频开发(一):三种方式绘制图片

    在android开发中我们最常使用的绘制图片的方式就是ImageView,设置src.那么有没有其他方案可以实现图片的绘制呐? 三种方案 通过Imageview设置setImageBitmap fin ...

最新文章

  1. Java线程之join
  2. 关于一致性hash详细
  3. 图解反向代理和正向代理。
  4. ucos iii学习笔记——为什么选择ucos iii
  5. SQL基础【十一、分页 limit top rownum】
  6. JVM内存溢出分析-实战JVM(二)
  7. 【计算机网络】子网划分步骤
  8. 利用顺序栈解决括号匹配问题(c++)-- 数据结构
  9. Pr 入门教程,如何倾斜移位效果?
  10. 详细图解MySQL(win7x64 5.7.16版本)下载、安装、配置与使用
  11. 创龙基于Xilinx Kintex-7系列高性价比FPGA开发板SMA端子、电源接口和拔码开关
  12. python操作mysql批量插入
  13. jenkins with ant 和 invoke ant
  14. python如何提取奇数_Python 获取奇数和偶数
  15. ORA-28547 连接服务器失败
  16. 微信局域网测试环境搭建方法
  17. 为什么要学习Linux?
  18. 阿里云验证码与通知短信
  19. “无聊猿” BAYC 的内忧与外患
  20. 2017-07-06:大神

热门文章

  1. 卸载安装软件或VC运行库时,遇到错误1714、错误1624、错误1612、错误0x80070643的解决方法
  2. scala 模式匹配
  3. 小学计算机教师证面试题目,2018上半年小学信息技术教师资格证面试试题(精选)第二批...
  4. 新手入门指南之玩转蓝桥云课
  5. [转载]儿童画教学-理论篇_我是亲民_新浪博客
  6. InstructGLM:基于ChatGLM-6B在指令数据集上进行微调
  7. CSS 取消input的上下箭头
  8. 截取数组的方法slice()/splice()
  9. Elasticsearch学习(十九)Elasticsearch8 搭建集群自动生成https证书
  10. 这些老外的开源技术养活了一票国产软件