美文网首页
canvas学习

canvas学习

作者: blossom_绽放 | 来源:发表于2018-07-23 17:40 被阅读17次

    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 个值:

    • butt:默认值,端点是垂直于线段边缘的平直边缘。
    • round:端点是在线段边缘处以线宽为直径的半圆。
    • square:端点是在线段边缘处以线宽为长、以一半线宽为宽的矩形。

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

    • miter:默认值,在连接处边缘延长相接。miterLimit 是角长和线宽所允许的最大比例(默认是 10)。
    • bevel:连接处是一个对角线斜角。
    • round:连接处是一个圆。

    颜色

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

    • 线性渐变,基于2个端点之间渐变
    • 径向渐变,基于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.shadowColor:阴影颜色string。
    • context.shadowOffsetX:阴影x轴位移。正值向右,负值向左number。
    • context.shadowOffsetY:阴影y轴位移。正值向下,负值向上number。
    • context.shadowBlur:阴影模糊滤镜。数据越大,扩散程度越大number。

    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,可以引入图像、画布、视频,并对其进行缩放或裁剪
    一共有三种表现形式:

    • 三参数:context.drawImage(img,x,y)
    • 五参数:context.drawImage(img,x,y,width,height)
    • 九参数:context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height)
    参数 描述
    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。

    相关文章

      网友评论

          本文标题:canvas学习

          本文链接:https://www.haomeiwen.com/subject/uwbdmftx.html