canvas
1、大小:不可直接在css样式里设,会导致canvans里面的图像变形
2、画布是一个透明色
3、画布的坐标无限大,可视区域为设置的大小
4、 坐标:X 轴向右,Y 轴向 下
一、canvas画线
一、获取上下文
<canvas id="canvas" width="400" height="400">
对不起,您的浏览器版本过低,点击<a href="javascript:void(0)">下载</a>
</canvas>
let canvas = document.getElementById('canvas'); // 获取节点
let ctx = canvas.getContext('2d'); // 获取上下文
二、新建一个路径(图层)
ctx.beginPath(); 新建图层(在之前的坐标基础上)
ctx.moveTo(20,10); 线:开始坐标
ctx.lineTo(20,350); 线:结束坐标
ctx.strokeStyle = '#000'; 颜色
ctx.lineWidth = 20; 线宽
ctx.lineCap = 'round'; 线帽
ctx.globalAlpha = 0.5 透明度
ctx.stroke(); 图形渲染到画布(笔触:线性)
二、canvas画闭合图形
context.stroke() --------------- 渲染线 (边框 )
context.fill() -------------------- 填充内容
closePath() -------------------- 自动闭合路径(形成闭合图形) 【注:与beginPath并不是一对
】
一、三角形 -- 收尾连线
ctx.clearRect(0,0,400,400); ------------- 清除画布
ctx.beginPath();
ctx.moveTo(100,0);
ctx.lineTo(0,200);
ctx.lineTo(200,200);
ctx.closePath(); 闭合路径
ctx.lineWidth = 2;
ctx.strokeStyle = 'pink'; 边框颜色
ctx.stroke(); 边框渲染
ctx.beginPath();
ctx.moveTo(300,0);
ctx.lineTo(400,200);
ctx.lineTo(200,200);
ctx.closePath();
ctx.fillStyle = 'red'; 填充颜色
ctx.fill(); 填充渲染
二、矩形 -- (rect)
两种实现方式
1、fillRect(左上角坐标 X , 左上角坐标 Y , 宽 , 高) 【或者 : strokeRect 】
2、 rect(左上角坐标 X , 左上角坐标 Y , 宽 , 高)
两种方法的区别
fillRect (strokeRect ) :不可用 isPointInPath 判断某个点是否在上下文图形内
rect :可通过 isPointInPath 判断某个点是否在上下文图形内
ctx.clearRect(0,0,400,400);
ctx.beginPath();
ctx.fillStyle = 'red';
ctx.fillRect(20,20,150, 100); 左上角坐标 X , 左上角坐标 Y , 宽 , 高
ctx.fill();
ctx.beginPath();
ctx.strokeStyle = 'yellow';
ctx.strokeRect(200,20,150,100); 左上角坐标 X , 左上角坐标 Y , 宽 , 高
ctx.stroke();
ctx.beginPath();
ctx.fillStyle = 'blue';
ctx.rect(20,200,150,100); 左上角坐标 X , 左上角坐标 Y , 宽 , 高
ctx.fill()
ctx.beginPath();
ctx.strokeStyle = 'green';
ctx.rect(200,200,150,100); 左上角坐标 X , 左上角坐标 Y , 宽 , 高
ctx.stroke();
三、画圆 arc (弧)
参数:arc ( 圆心坐标 X , 圆心坐标 Y , 半径 , 开始角度 , 结束角度 , 旋转方式[true(false)] )
默认顺时针(false), 其中:逆时针(true);
·
注:一般在画圆时,圆心位置放置在画布中心,会将画布的坐标系(0,0)移动到画布中心位置;为便于后续操作,一般会在移动画布前,保存原画布坐标,再之后需要在释放之前的原坐标。
ctx.clearRect(0, 0, 400, 400);
ctx.beginPath();
ctx.fillStyle = 'red';
ctx.arc(100, 100, 80, 0, 2 * Math.PI, false); 圆心坐标 X , 圆心坐标 Y , 半径 , 开始角度 , 结束角度 , 旋转方向
ctx.fill(); fill :填充渲染,圆
ctx.beginPath();
ctx.strokeStyle = 'yellow';
ctx.arc(300, 100, 80, 0, 1.5 * Math.PI, false);
ctx.stroke(); stroke:边框渲染,圆弧
三、判断某个点是否在图形里
if(ctx.isPointInPath(110,110)){
console.log('在图形内')
}else{
console.log('不在图形内')
}
四、字体
// 字体
ctx.beginPath();
ctx.moveTo(0,100);
ctx.lineTo(200,100);
ctx.moveTo(0,300);
ctx.lineTo(200,300);
ctx.moveTo(100,0);
ctx.lineTo(100,400);
ctx.stroke();
ctx.font = "normal 30px Arical"; 字体大小、样式
ctx.textBaseline = 'middle'; 垂直对齐方式
ctx.textAlign = 'center'; 水平对齐方式
ctx.fillText('你好世界',100,100); 文字内容:填充
var grd = ctx.createLinearGradient(0,0,500,500); 线性渐变 : 启始坐标 X , 启始坐标 Y , 结束坐标 X , 结束坐标 Y
var grd = ctx.createRadialGradient(250,250,100,250,250,200,250,250,250); 径向渐变:起始坐标 X , 起始坐标 Y , 半径 R , ...
grd.addColorStop(0,"blue");
grd.addColorStop(0.5,"red");
grd.addColorStop(1,"yellow");
ctx.strokeStyle = grd;
ctx.strokeText('你好世界',100,300); 文字内容:边框渲染
五、清除画布
【为使画布清除完全:一般在最开始保存状态(保存原坐标),清除画布之前 释放状态(释放原坐标)】
clearRect(0,0,500,500); 属性:开始坐标(x,y),结束坐标(x,y)
六、阴影 shadow
ctx.clearRect(0,0,400,400);
ctx.shadowColor = '#000'; 阴影颜色
ctx.shadowBlur = 6; 阴影模糊程度
ctx.shadowOffsetX = 5; 阴影偏移 X 轴
ctx.shadowOffsetY = 2; 阴影偏移 Y 轴
ctx.fillText('hellow',200,200);
七、图形变换
!!! 图形变换 -- 实际上并不是变换图形,变换的是坐标系;
在坐标系没有改变之前画的不受影响,之后的受影响;
一、平移
context.translate(100,100); 属性:移动的坐标(x,y)
二、旋转
context.rotate(Math.PI/4); 属性:旋转的角度 -- 正顺时针,负逆时针
三、缩放 -- 坐标系刻度改变
context.scale(0.5,2); 属性:缩放比例(x,y)
四、保存状态
1、由于图形变换是对坐标的变换,之后的图形也会受到影响。所以有时需要将未改变前的坐标进行保存。
2、注:
(1)、与restore是一对(多个时,释放状态时,就近取。先入后出【栈】)
(2)、save与restore是一一对应的,有多少save,就要有多少restore
代码
context.save(); // 保存状态 -- 再图形变换前,将原坐标保存,
context.restore(); // 释放状态 -- 释放之前保存的原坐标
八、贝塞尔曲线
一、贝塞尔曲线必须要一个开始点
context.moveTo(0,0);
二、二次贝塞尔曲线 (一个控制点)
context.quadraticCurveTo(400,0,400,400); // 一个控制点(x,y),结束点(x,y)
三、三次贝塞尔曲线 (2个控制点)
context.bezierCurveTo(400,0,0,400,400,400); // 两个控制点(x,y),结束点(x,y)
九、图形组合
目标图:先画在画布上的图,源图:后画在画布上的图列:
context.beginPath();
context.arc(100,100,100,0,Math.PI*2);
context.fillStyle = "pink";
context.fill();
context.globalCompositeOperation = "destination-over"
context.beginPath();
context.fillStyle = "aquamarine";
context.fillRect(100,100,200,200);
十、图片
一、定义图片、传地址
var img = new Image();
img.src = "a.jpg";
二、图片加载完后,将图片画入canvas
drawImage()
// 参数3 -- 图片对象,放入画布位置(x,y);
context.drawImage(img,0,0);
// 图片位置 参数5 -- 图片对象, 放入画布位置(x,y),图片大小(x,y) -- 图片可能会失帧
context.drawImage(img,0,0,100,100);
// 裁切图片 参数9 -- 图片对象,原图像上位置(x,y),原图裁切大小(x,y),放入画布位置(x,y),图片大小(x,y)
context.drawImage(img,0,0,100,100,0,0,100,100);
三、获取所有像素点
getImageData
1、获取的是每个图片的像素点,在实际应用中,获取位置的减少可以大大提升性能
2、每4个值代表一组,分别对应 rgba 的值
// 参数4:获取起始位置(x,y),获取结束位置(x,y)
var imageData = context.getImageData(0,0,500,500);
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 gray = (r+b+g)/3;
// 灰度处理 gray
//imageData.data[i] = 255 - gray;
//imageData.data[i+1] = 255 - gray;
//imageData.data[i+2] = 255 - gray;
// 反色处理
imageData.data[i] = 255 - r;
imageData.data[i+1] = 255 - g;
imageData.data[i+2] = 255 - b;
}
四、将改好的像素重新放到画布上
putImageData
// 参数3:更改后的像素点,图片位置(x,y)
context.putImageData(imageData,100,100);
十一、视屏
与图片一样,在视屏播放时,需要重汇像素dian
var video = document.getElementById("myVideo");
function act(){
// 将视屏放入canvas
context.beginPath();
context.drawImage(video,0,0);
// // 获取像素点
// var imageData = context.getImageData(0,0,canvas.width,canvas.height);
// for(var i=0;i<imageData.data.length;i+=4){
// imageData.data[i+1] = 0;
// imageData.data[i+2] = 0;
// }
// context.putImageData(imageData,0,0);
res = window.requestAnimationFrame(act);
}
act();
// 开关
function start(){
video.play();
act();
}
function pause(){
video.pause();
// 停止动画循环 -- 节约性能
cancelAnimationFrame(res);
}
十二、canvas 重汇函数 、停止重汇
requestAnimatinFrame (请求动画建造)
cancelAnimationFrame (取消动画建造)
1、其调取cpu,其性能取决于显卡的性能
2、比setInterval更加节约性能:在切到后台时,不会执行。而定时器会执行。
3、如果网页于后台或者影藏在iframe里,重绘频率可能会大大降低以提升性能和电池耐久度
var res = window.requestAnimationFrame(act); // 参数:要重新执行的函数,!!!不传参、不加()
cancelAnimationFrame(res); // 参数:之前调用的重构函数
十三、base64
由于某些系统中只能使用ASCII字符。Base64就是用来将非ASCII字符的数据转换成ASCII字符的一种方法
介绍 https://www.cnblogs.com/cuihongyu3503319/p/5564265.html
一、JavaScript获取base64
在 file文件改变时
var myFile = document.getElementById("myfile").files[0];
一、读取文件
var fileRead = new FileReader();
二、将文件读取为 URL
fileRead = readAsDataURL(myFile);
三、文件加载完毕
fileRead.onload = function(ev){
// 1、获取 base64
// 将图片直接编成字符串。图片的所有信息都在里面。可以直接赋值给src。
var base64 = ev.target.result;
// 2、图片放入页面
var img = new Image();
img.src = base64;
document.getElementsByTagName("body")[0].children(img);
}
二、canvas 转 base64
toDataURL
function sub(){
var base64 = canvas.toDataURL();
console.log(base64);
var img = new Image();
img.src = base64;
document.getElementsByTagName("body")[0].appendChild(img);
}