canvas学习

2018-07-23  本文已影响17人  blossom_绽放

canvas....学前端的看到这个标签就会有一种高大上的感觉,因为这个标签出来的时候,项目大部分时候用于复杂交互,游戏等比较深入的领域,不学好canvas,都不好自称自己是合格的前端工程师....

一些注意点:

  1. Canvas是基于状态的绘制
  2. 设置canvas的大小只有2种方法,直接在标签中设置和通过js设置,其余都是无效的
  3. 每次变换要保存状态,变换结束读取状态

基础

// 获取绘制画布
let canvas = document.getElementById('canvas')
let context = canvas.getContext('2d') //获取画笔

//设置绘制图形
context.beginPath(); // Canvas是基于状态的绘制,所以每次绘制应该重设状态
context.moveTo(100, 100) //把笔尖放到100px 100px
context.lineTo(600, 600) // 从100,100移动到600,600
context.closePath() //绘制结束调用,自动闭合图形

// 设置绘制样式
context.lineWidth = 5 // 设置线宽5px
context.strokeStyle = '#AA394C' //设置颜色
context.fillStyle = "black"; //设置背景填充颜色是黑色

// 绘制
context.fill(); //填充
context.stroke() //画线

// 保存调用状态
context.save();
context.restore();
//一些js封装好的绘制函数
context.rect(x,y,width,height); //绘制矩形
context.fillRect(x,y,width,height)//直接填充出来一个矩形
context.strokeRect(x,y,width,height) //直接画一个矩形

线条

lineCap 定义上下文中线的两端端点,可以有以下 3 个值:

lineJoin 定义两条线相交产生的拐角,可将其称为连接。在连接处创建一个填充三角形,可以使用 lineJoin 设置它的基本属性:

颜色

除了直接设置颜色,还有渐变色的设置
渐变色的设置分2种:

填充的时候也可以填充纹理或者说就是设置图片背景

下面介绍api

//添加线性渐变渐变线
var grd = context.createLinearGradient(xstart,ystart,xend,yend);
// 为渐变线添加关键色(类似于颜色断点)
grd.addColorStop(stop,color); //stop传递0~1浮点数
// 应用渐变
context.fillStyle = grd;
context.strokeStyle = grd;
//例子:
 var grd = context.createLinearGradient(200,300,600,300);
        grd.addColorStop(0,"black");
        grd.addColorStop(0.5,"white");
        grd.addColorStop(1,"black");
        context.fillStyle = grd;
        context.fill();

//添加径向渐变渐变圆
var grd = context.createRadialGradient(x0,y0,r0,x1,y1,r1);
//为渐变线添加关键色(类似于颜色断点)
grd.addColorStop(stop,color)
context.fillStyle = grd;
context.strokeStyle = grd;
//例子:
 var grd = context.createRadialGradient(400,300,100,400,300,200);
        //添加颜色断点
        grd.addColorStop(0,"olive");
        grd.addColorStop(0.25,"maroon");
        grd.addColorStop(0.5,"aqua");
        grd.addColorStop(0.75,"fuchsia");
        grd.addColorStop(0.25,"teal");
        //应用渐变
        context.fillStyle = grd;
        context.fillRect(100,100,600,400);

// 填充纹理(背景图片)
context .createPattern(img,repeat-style) // 第一个参数是new Image(),或者canvas和video对象实例,第二个参数是重复方式
//例子
var pattern = context.createPattern(img, "repeat");
            context.fillStyle = pattern;
            context.fillRect(0,0,800,600);

弧度

  1. 标准圆弧 arc()
    context.arc(x,y,radius,startAngle,endAngle,anticlockwise)
    前面三个参数,分别是圆心坐标与圆半径。startAngle、endAngle使用的是弧度值(Math.PI) (上1.5* Math.PI,右0* Math.PI,下0.5Math.PI,左1Math.PI)
    anticlockwise 代表顺时针还是逆时针绘制,true逆时针,false顺时针,缺省值为false
// 例子,一个有弧度的矩形封装函数
    function drawRoundRect(cxt, x, y, width, height, radius){
        cxt.beginPath();
        cxt.arc(x + radius, y + radius, radius, Math.PI, Math.PI * 3 / 2);
        cxt.lineTo(width - radius + x, y);
        cxt.arc(width - radius + x, radius + y, radius, Math.PI * 3 / 2, Math.PI * 2);
        cxt.lineTo(width + x, height + y - radius);
        cxt.arc(width - radius + x, height - radius + y, radius, 0, Math.PI * 1 / 2);
        cxt.lineTo(radius + x, height +y);
        cxt.arc(radius + x, height - radius + y, radius, Math.PI * 1 / 2, Math.PI);
        cxt.closePath();
    }
  1. 切线画弧 arcTo()
    arcTo(x1,y1,x2,y2,radius)
    这个函数以给定的半径绘制一条弧线,圆弧的起点与当前路径的位置到(x1, y1)点的直线相切,圆弧的终点与(x1, y1)点到(x2, y2)的直线相切
  1. 二次贝塞尔曲线
    quadraticCurveTo(cpx,cpy,x,y)
    (cpx, cpy)是控制点,(x, y)是终止点,一般搭配moveTo设置一个初始点使用

  2. 三次贝塞尔曲线
    context.bezierCurveTo(cp1x,cp1y,cp2x,cp2y,x,y);
    常用来绘制波浪效果

变换

平移变换、旋转变换、缩放变换都属于坐标变换,或者说是画布变换。因此,缩放并非缩放的是图像,而是整个坐标系、整个画布!就像是对坐标系的单位距离缩放了一样,所以坐标和线条都会进行缩放

平移变换 translate()

// 直接上例子
context.translate(100,100); // 平移变换100,100
context.fillRect(100,100,200,100); //现在这个矩形在200,200的位置
// 有一个注意点: 如果平移后继续平移
context.translate(100,100);
context.fillRect(100,100,200,100);  //这时候是300,300,因为基于状态绘制的
//所以需要状态保存读取
context.save();
context.translate(200,200);
context.fillRect(100,100,200,100);
context.restore();

旋转变换 rotate()

rotate(deg)传入的是弧度Math.PI,已坐标系原点为圆心的顺时针旋转,所以使用rotate()前通常使用translates()平移坐标系确认圆心

缩放变换 scale()

scale(sx,sy)传入两个参数,分别是水平方向和垂直方向上对象的缩放倍数
需要注意的是:

  1. 缩放时,图像左上角坐标的位置也会对应缩放。
  2. 缩放时,图像线条的粗细也会对应缩放。

文本

// font参数值  所有都有默认值,具体设置查询相应文档
context.font = 
"[font-style] [font-variant] [font-weight] 
[font-size/line-height] [font-family]"

 //1. 使用`font`设置字体。
 context.font = "50px serif";
//2. 使用`fillStyle`设置字体颜色。
context.fillStyle = "#00AAAA";
//3. 使用`fillText()`方法显示填充字体。
context.fillText("《CANVAS--Draw on the Web》",50,300);
// 4. 使用`strokeText`方法显示文本字体
context.strokeText(String,x,y,[maxlen])

文本对齐
水平对齐与起始点的关系
context.textAlign="center|end|left|right|start";
垂直对齐与 基准线的关系
context.textBaseline="alphabetic|top|hanging|middle|ideographic|bottom";
文本度量
context.measureText(txt).width
度量文本长度,可以用来实现换行

阴影效果

创建阴影效果需要操作以下4个属性:

context.globalAlpha = 0.5设置全局透明度0-1之间,如果不想针对全局设置不透明度,就得在下次绘制前重置globalAlpha

裁剪

裁剪是对画布进行的,裁切后的画布不能恢复到原来的大小,所以记得saverestore状态

        // 来个例子
        //裁剪画布从(0,0)点至(50,50)的正方形
        context.rect(0,0,50,50);
        context.clip();

        //红色圆
        context.beginPath();
        context.strokeStyle = "red";
        context.lineWidth = 5;
        context.arc(100,100,100,0,Math.PI * 2,false);
        //整圆
        context.stroke();
        context.closePath();
      //只能显示(50,50)矩形里面的红色圆弧

绘制图像

这是一个非常重要的api,可以引入图像、画布、视频,并对其进行缩放或裁剪
一共有三种表现形式:

参数 描述
img 规定要使用的图像、画布或视频。
sx 可选。开始剪切的 x 坐标位置。
sy 可选。开始剪切的 y 坐标位置。
swidth 可选。被剪切图像的宽度。
sheight 可选。被剪切图像的高度。
x 在画布上放置图像的 x 坐标位置。
y 在画布上放置图像的 y 坐标位置。
width 可选。要使用的图像的宽度。(伸展或缩小图像)
height 可选。要使用的图像的高度。(伸展或缩小图像)

橡皮擦

context.clearRect(x,y,w,h) 清除指定矩形上的画布上的像素,xy为起始点,wh宽高

isPointInPath (x,y)接收两个参数,就是一个点的坐标值,用来判断指定的点是否在当前路径中。若是,则返回true。

上一篇下一篇

猜你喜欢

热点阅读