1、canvas 基础

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)移动到画布中心位置;为便于后续操作,一般会在移动画布前,保存原画布坐标,再之后需要在释放之前的原坐标。

20150416084222150.gif
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)

九、图形组合

目标图:先画在画布上的图,源图:后画在画布上的图
屏幕快照 2017-12-26 下午10.35.50.png

列:

    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);
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,902评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,037评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,978评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,867评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,763评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,104评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,565评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,236评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,379评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,313评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,363评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,034评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,637评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,719评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,952评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,371评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,948评论 2 341

推荐阅读更多精彩内容

  • 一:canvas简介 1.1什么是canvas? ①:canvas是HTML5提供的一种新标签 ②:HTML5 ...
    GreenHand1阅读 4,655评论 2 32
  • 一、canvas简介 1.1 什么是canvas?(了解) 是HTML5提供的一种新标签 Canvas是一个矩形区...
    Looog阅读 3,926评论 3 40
  • 一、canvas简介 1.1 什么是canvas?(了解) 是HTML5提供的一种新标签 Canvas是一个矩形区...
    J_L_L阅读 1,486评论 0 4
  • 一、简介 HTML5 中的定义:“它是依赖分辨率的位图画布,你可以在 canvas 上面绘制任何图形,甚至加载照片...
    destiny0904阅读 10,509评论 1 4
  • 最近身体轻松很多,早上还是要干呕几下,但是基本无影响。自从和明星兄办了游泳次卡,坚持每周都去游一次,一次水里游1个...
    携子之阅读 173评论 0 0