canvas学习(一)

简介:

canvas是html5最重要的元素,提供了一个画布的功能,有强大的图形处理能力

思维导图

canvas标签添加

要使用canvas,首先要在body中添加上canvas标签

canvas标签是一块默认300*150大小的画布

画布宽高设置:

使用canvas标签的属性,width及height直接在行间设置

此处注意:不要用css样式去改画布大小,这个会导致画布中的图像被拉伸

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

画布css样式

画布的其他css样式可以正常设置

canvas标签中的内容
canvas标签中的内容是(包括标签)只有在不支持此效果的低版本浏览器中才会显示的;在高版本浏览器中不会显示出来

<canvas id="canvas1" width="800" height="500">
    只是一个canvas标签,然而你看不到
</canvas>

获取canvas标签及上下文

canvas标签使用js正常dom节点的获取方法获取

var canvas = document.getElementById('canvas1');

上下文是记录canvas执行命令语句的地方,获取如下,后面的参数现在只有2d可选

var context = canvas.getContext('2d');

canvas坐标系

左上角是00点,x轴正方向向右,y轴正方向向下

样式设置

边框设置:context.strokeStyle
填充设置:context.fillStyle
线宽设置:context.lineWidth

context.strokeStyle = "red";
context.lineWidth = 2;
context.fillStyle = 'yellow';

绘制图形

绘制命令
  1. 边框式绘制:context.stroke();
  2. 填充式绘制:context.fill();
新建路径beginPath()

这个方法代表重新开始一段路径,也可以理解为新建一个图层
这个的方法之后执行的绘制动作,不会执行到这个方法之前的命令

context.beginPath();
绘制直线:
  1. 设置画笔开始位置:context.moveTo(x,y)
  2. 设置画笔结束位置:context.lineTo(x,y)
  3. 线段两边圆角:context.lineCap = "round"

context.strokeStyle = "red";
context.lineWidth = 2;
context.moveTo(100,100);
context.lineTo(500,100);
context.stroke();
绘制三角:方法就是绘制3条直线

绘制多条连续线段时,不必每次重新定义起始点
画笔会停在上一段线段的终点,并默认为下一次绘制的起始点

context.strokeStyle = "red";
context.lineWidth = 2;

context.moveTo(10,10);
context.lineTo(10,110);
context.lineTo(110,110);
context.lineTo(10,10);
context.stroke();

注意,此处用绘制直线的方法,进行图形的绘制时;直线封闭处会出现瑕疵,不会完全闭合



闭合方法:context.closePath()

加上上面的闭合命令后,闭合处的瑕疵就会被修复
这个方法会自动将起点与末点相连,所以不必再将路径回到起始点

context.strokeStyle = "red";
context.lineWidth = 2;

context.beginPath();
context.moveTo(10,10);
context.lineTo(10,110);
context.lineTo(110,110);
context.closePath();  //封闭路径后最后一个点就不用定义了
context.stroke();

绘制矩形

定义矩形:context.rect(x,y,w,h);

  1. x:起始位置x坐标(矩形左上角)
  2. y:起始位置y坐标(矩形左上角)
  3. w:矩形宽
  4. h:矩形高

直接绘制:省去了定义矩形的步骤,按照定义的样式直接填充或描边

context.fillRect(x,y,w,h)
context.strokeRect(x,y,w,h)

橡皮擦功能:clearRect(x,y,w,h)

  1. 擦除矩形范围之内的内容
  2. 常用来擦除整个画布以实现动画效果
图形绘制方式

边框式绘制:

context.strokeStyle = "red";
context.lineWidth = 2;
context.rect(150,150,200,100);
context.stroke();

填充式绘制:

context.fillStyle = 'yellow';
context.rect(150,150,200,100);
context.fill();
填充+描边同时使用注意:

这两个效果同时使用时,先后顺序的不同会导致效果的差异

一般是在填充后再去描边,如下效果

context.strokeStyle = "red";
context.lineWidth = 2;
context.rect(150,150,200,100);
context.fill();
context.stroke();

如果是描边后再填充的话,填充效果会遮挡一半的边框

//线宽被遮挡一半
context.strokeStyle = "red";
context.lineWidth = 2;
context.rect(150,150,200,100);
context.stroke();
context.fill();
绘制弧形

常用方法:context.arc(x,y,r,θ1,θ2,boolean)

  1. x:中心点x坐标
  2. y:中心点y坐标
  3. r:圆半径
  4. θ1:起始角度
  5. θ2:结束角度
  6. 布尔值:false逆时针(默认),true顺时针

//画弧线
context.strokeStyle = "red";
context.lineWidth = 2;
context.arc(300,100,100,0,Math.PI/2,true)
context.stroke();
//画圆
context.beginPath();
context.arc(300,200,100,0,Math.PI*2,true)
context.stroke();
绘制文字

设置文字样式:context.font = 'italic size family'

  1. italic:斜体
  2. size:字体大小
  3. family:字体

设置文字内容:context.strokeText("text",x,y)

  1. "text":中文字内容
  2. x:起始x坐标
  3. y:起始y坐标

context.lineWidth = 1;
context.strokeStyle = "green";
context.font = "italic 150px arial"
context.strokeText("我是文字",50,200);
渐变样式

线性渐变:createLinearGradient(x1,y1,x2,y2)

  1. x1/y1:渐变起始位置坐标
  2. x2/y2:渐变结束位置坐标

径向渐变:createRadiusGradient(x1,y1,r1,x2,y2,r2)

  1. x1/y1:渐变起始圆的圆心位置坐标
  2. r1:渐变起始圆半径
  3. x2/y2:渐变结束圆的圆心位置坐标
  4. r2:渐变结束圆半径

渐变颜色设置:addColorStop(%,"color");

  1. %:渐变进度,用[0,1]之间的数字表示
  2. "color":每个渐变阶段的颜色

var linearGradient = context.createLinearGradient(100,300,800,500);

linearGradient.addColorStop(0,"red");
linearGradient.addColorStop(0.4,"yellow");
linearGradient.addColorStop(0.8,"green");
linearGradient.addColorStop(1,"blue");

context.fillStyle = linearGradient;

context.font = "italic 150px arial"
context.fillText("我是文字",50,200);
绘制阴影

阴影颜色:shadowColor = "color";
阴影模糊度:shadowblur = number;
阴影偏移X:shadowOffsetX = number;
阴影偏移Y:shadowOffsetY = number;

context.shadowColor = "black";
context.shadowBlur = 20;
context.shadowOffsetX = 10;
context.shadowOffsetY = 5;

context.strokeRect(100,100,100,100);

坐标变换

相关例子可以看我的另一篇博客canvas钟表效果
坐标系平移:translate(x,y)
  1. 即是将坐标系的00点变换到(x,y)位置
坐标系旋转:rotate(θ)
  1. 将坐标系旋转θ度
  2. θ > 0时顺时针旋转,θ < 0时逆时针旋转
坐标系缩放:scale(x,y)
  1. 将坐标系x方向放大x倍
  2. 将坐标系y方向放大y倍

注意:因为坐标系在经过变换之后,之后重新绘制的图形都会以这个新的坐标系为参考;所以在绘制的时候会非常的麻烦

解决方案如下:

save():保存当前坐标系

restore():读取保存的坐标系

  1. 每次在进行坐标系变换之前,先使用save()将原始坐标系保存下来
  2. 在进行变换之后,再使用restore()将坐标系恢复为初始坐标系
  3. 每个restore()对应相应的一个save(),所以在全局中保存一次随后无限restore()的做法是无效的

绘制贝塞尔曲线/二次曲线

相关例子可以看我另一篇博客canvas随拖动变化的贝塞尔曲线
先用moveTo(x,y)设置起始点坐标
贝塞尔曲线:bezierCurveTo(cpx1,cpy1,cpx2,cpy2,dx,dy)
  1. cpx1/xpy1:控制点1坐标
  2. cpx2/xpy2:控制点2坐标
  3. dx/dy:终点坐标
二次曲线quadraticCurveTo(cpx,cpy,dx,dy)
  1. cpx/xpy:控制点坐标
  2. dx/dy:终点坐标

context.beginPath();
context.moveTo(300,100);
//贝塞尔曲线
context.bezierCurveTo(200,100,300,300,200,300);
context.stroke()

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

推荐阅读更多精彩内容

  • 一:canvas简介 1.1什么是canvas? ①:canvas是HTML5提供的一种新标签 ②:HTML5 ...
    GreenHand1阅读 4,661评论 2 32
  • 一、canvas简介 1.1 什么是canvas?(了解) 是HTML5提供的一种新标签 Canvas是一个矩形区...
    Looog阅读 3,935评论 3 40
  • 一、canvas简介 1.1 什么是canvas?(了解) 是HTML5提供的一种新标签 Canvas是一个矩形区...
    J_L_L阅读 1,492评论 0 4
  • --绘图与滤镜全面解析 概述 在iOS中可以很容易的开发出绚丽的界面效果,一方面得益于成功系统的设计,另一方面得益...
    韩七夏阅读 2,710评论 2 10
  • 书中代码示例效果展示:Core HTML5 Canvas Examples 基础知识 canvas元素 canva...
    szu_bee阅读 2,803评论 2 28