zoukankan      html  css  js  c++  java
  • canvas学习之路--记录(一)

    前言:canvas作为html5出现的新标签,以前接触过一些,也写过一些小的demo,但没有实际去在项目中使用过,直到前段时间,我要写一个前端小游戏,由于当时时间匆忙就没使用canvas,整个项目全部是用html标签来充当游戏当中的元素,结构就是在一些特定手机上相当之卡,个人优化过之后,稍有好转,但依旧不满意,无奈项目紧急,只能事权轻重,先行将项目上线,不过只要有时间,还是将canvas搞懂,以后这种全用canvas写为好...下面进入本菜鸡学习canvas之路吧.(此为作者跟着html5与css3权威指南所学记录).

    一、绘制矩形

    1.首先要取得canvas元素: 可以用document.getElementById等方法取得canvas对象,后面需要调用这个对象提供的方法来进行图形绘制. 

    2.取得上下文: 进行图形绘制时,需要用到图形上下文,图形上下文是一个封装了很多绘图功能的对象,需要使用canvas对象的getContext方法来获得图形上下文. 其中将此方法的参数设为'2d';

    3.填充与绘制边框: 用canvas绘制图形的时候,有两种方式--填充(fill)与绘制边框(stroke).填充是指填满图形内部,绘制边框是指不填满图形内部,只绘制图形的外框.

    4.设定绘图样式: 在进行图形绘制的时候,首先要设定好绘图的样式(style),然后调用有关方法进行图形的绘制.所谓绘图的样式,主要是针对图形的颜色而言的,但是并不限于图形的颜色.

      fillStyle属性--填充的样式,在该属性中填入填充的颜色值

      strokeStyle--图形边框的样式,在该属性中填入边框的颜色值

    5.指定线宽: 使用图形上下文对象的lineWidth属性设置图形边框的宽度,在绘制图形的时候,任何直线都可以通过lineWidth属性来指定直线的宽度

    6.指定颜色值: 绘图时填充的颜色或边框的颜色分别通过fillStyle属性和strokeStyle属性来指定,颜色值可使用颜色名(如:red),或十六进制颜色值(如:#f00),或rgb、rgba函数来指定颜色

    7.绘制矩形: 分别使用fillRect方法与strokeRect方法来填充矩形会绘制矩形边框,这两个方法的定义如下所示

      context.fillRect(x,y,width,height)

      context.strokeRect(x,y,width,height)

      这里的context指的是图形上下文对象,这两个方法使用同样的参数,x是指矩形起点的横坐标,y是指矩形七点的纵坐标,坐标原点为canvas画布的最左上角,width是指矩形的长度,height是指矩形的高度

     绘制图形代码如下:

    function draw (obj) {
        var $myCanvas = document.getElementById(obj);  //canvas对象
        if ($myCanvas == null) return false;
        var $ctx = $myCanvas.getContext('2d');   //获取canvas对象图形上下文
        $ctx.fillStyle = '#f00';
        $ctx.fillRect(50,50,100,100);
        $ctx.strokeStyle = '#ff0';
        $ctx.lineWidth = 10;
        $ctx.strokeRect(50,50,100,100);
    }

    此外,还有一个clearRect方法,该方法将擦除掉矩形区域内的图形,使矩形区域内的图形全部变成透明,如:context.clearRect(x,y,width,height),方法与上面的类似.

    二、使用路径

    获取到图形上下文之后,执行如下步骤

    开始创建路径-->创建图形的路径-->路径创建完成之后,关闭路径-->设定绘制样式,调用绘制方法,绘制路径.

    就是先用路径勾勒图形轮廓,然后设置颜色,进行绘制

    1.开始创建路径

    使用图形上下文对象的beginPath方法,如context.beginPath();

    该方法不适用参数,通过调用该方法开始路径的创建(注:每次开始创建时都要调用beginPath函数)

    2.创建圆形路径

    创建圆形路径时,需要使用图形上下文对象的arc方法. 如:context.arc(x,y,radius,startAngle,endAngle,anticlockwise).

    该方法使用六个参数,x为绘制圆形的圆点横坐标,y为绘制圆形的圆点纵坐标,radius为圆形半径,strartAngle为开始角度,endAngle为结束角度,anticlockwise为是否按照顺时针方向进行绘制

    arc方法不仅可以用来绘制圆形,也可以用来绘制圆弧,因此必须指定开始角度和结束角度.aniticlockwise参数是一个布尔值,值为true时,按顺时针绘制,值为false时,按逆时针进行绘制.

    3.关闭路径

    路径创建完成后,使用图形上下文对象的closePath方法将路径关闭.如:context.closePath();

    将路径关闭之后,仅仅是路径创建工作完成了,这时还没有真正绘制任何图形.

    4.设定绘制样式,进行图形绘制.

    如:context.fillStyle = 'rgba(255,0,0,0.25)';   context.fill();

    使用创建好的路径绘制图形:  指定绘制样式(fillStyle,strokeStyle)-->使用fill(或stroke)方法进行'填充图形'(或绘制图形边框),因为路径已经决定了图形的大小,所以就不需要在该方法中是哟红参数来指定图形的大小了.

    注意:如果在绘制路径的时候,不执行创建路径语句和关闭路径语句,则以前绘制的路径会一直存在,这时,如果再使用fill()或则stroke()时,会重复绘制先前的图形,进行重叠,如果绘制样式中有透明度设置,则最先绘制的图形颜色会最深

    function draw (obj) {
        var $myCanvas = document.getElementById(obj);
        if ($myCanvas == null) return false;
        var $ctx = $myCanvas.getContext('2d');
        $ctx.fillStyle = 'rgba(0,0,0,0.3)';
        $ctx.fillRect(0,0,400,300);
        $ctx.strokeStyle = 'rgb(0,0,0)';
        $ctx.lineWidth = 1;
        $ctx.strokeRect(0,0,400,300);
        
        $ctx.beginPath();
        $ctx.arc(0,0,150,0,2*Math.PI,true);
        $ctx.closePath();
        $ctx.fillStyle = 'rgba(255,0,0,0.5)';
        $ctx.fill();
    }

    三、moveTo与lineTo

    绘制直线时,一般会用到moveTo和lineTo两种方法,功能如下:

    moveTo

      moveTo方法的作用是将光标移动到指定款坐标点,绘制直线的时候以这个坐标点为起点,如:moveTo(x,y),该方法使用两个参数--x表示指定坐标点的横坐标,y表示指定坐标点的纵坐标

    lineTo

      lineTo方法在moveTo方法中指定的直线起点与参数中指定的直线终点之间绘制一条直线,如lineTo(x,y),使用方法和moveTo(x,y)的方法一样,使用该方法之后,光标自动移动到lineTo方法的参数所指定的直线终点

    因此,在创建路径时,需要使用moveTo方法将光标移动到指定的直线起点,然后使用lineTo方法在直线起点和直线终点之间创建路径,然后将光标移动到直线终点,在下一次使用lineTo方法的时候,会以当前光标所在坐标点为直线起点,并在下一次用lineTo方法指定的直线终点之间创建路径,它会不断重复这个过程,来完成复杂图形的路径绘制.

    如下:

    function draw (obj) {
        var $myCanvas = document.getElementById(obj);
        if ($myCanvas == null) return false;
        var $ctx = $myCanvas.getContext('2d');
        $ctx.fillStyle = '#eef';
        $ctx.fillRect(0,0,400,300);
        var n = 0,
            dx = 150,
            dy = 150,
            s = 100;
        $ctx.beginPath();
        $ctx.fillStyle = 'rgb(100,250,100)';
        $ctx.strokeStyle = 'rgb(0,0,100)';
        var x = Math.sin(0),
            y = Math.cos(0),
            dig = Math.PI / 15 * 11;
        for (var i = 0; i < 30; i++) {
            var x = Math.sin(i * dig),
                y = Math.cos(i * dig);
            $ctx.lineTo(dx + x * s, dy + y * s);
        }
        $ctx.closePath();
        $ctx.fill();
        $ctx.stroke();
    }

    除此之外,还有使用bezierCurveTo绘制曲线(有兴趣可以自己去研究,本人太菜,加上感觉用不上这么高大上的东西,就不做笔记了)
    四、绘制渐变图形

    1.绘制线性渐变

    前面使用的fillStyle方法在填充时不但可以指定填充的颜色,同时,使用该方法也可以用来指定填充的对象.

    这里,可以来看一下渐变,首先是最简单的两点之间的线性渐变.

    绘制线性渐变时,需要用到LinearGradient对象.使用图形上下文对象的createLinearGradient方法创建该对象.如:context.createLinearGradient(xStart,yStart,xEnd,yEnd);

    该方法有四个参数,xStart-->渐变起点的横坐标,yStart-->渐变起点的纵坐标,xEnd-->渐变终点的横坐标,yEnd-->渐变终点的纵坐标.

    通过该方法,创建了一个使用两个坐标点的LinearGradient对象,而渐变的颜色则使用addColorStop方法进行设定,该方法的如:context.addColorStop(offset,color);

    该方法可以追加渐变的颜色.该方法使用两个参数--offset和color.

    offset为所设定的颜色离开渐变起始点的偏移量,改参数的值是一个范围在0到1之间的浮点值,渐变起点的偏移量为0,渐变结束点的偏移量为1.color为绘制时使用的颜色.

    例:

    function draw (obj) {
        var $myCanvas = document.getElementById(obj);
        if ($myCanvas == null) return false;
        var $ctx = $myCanvas.getContext('2d');
        var g1 = $ctx.createLinearGradient(0,0,0,300);
        g1.addColorStop(0,'#ff0');
        g1.addColorStop(1,'#0ff');
        $ctx.fillStyle = g1;
        $ctx.fillRect(0,0,400,300);
        $ctx.fill();
        var g2 = $ctx.createLinearGradient(0,0,300,0);
        g2.addColorStop(0,'rgba(255,0,0,0.5)');
        g2.addColorStop(1,'rgba(0,0,255,0.5)');
        $ctx.fillStyle = g2;
        for (var i = 1; i <= 10; i++) {
            $ctx.beginPath();
            $ctx.arc(i * 20,i*20,i*10,0,Math.PI*2,true);
            $ctx.closePath();
            $ctx.fill();
        }
    }

    2.绘制径向渐变

    使用图形上下文对象的createRadialGradient方法绘制径向渐变,如:context.createRadialGradient(xStart,yStart,radiusStart,xEnd,yEnd,radiusEnd);

    该方法有两个函数:xStart-->渐变开始圆的圆心横坐标,yStart-->渐变开始圆的圆心纵坐标,radiusStart-->渐变开始圆的半径,xEnd-->渐变结束圆的圆心横坐标,yEnd-->渐变结束圆的圆心纵坐标,radiusEnd-->渐变结束圆的半径

    在这个方法中,分别指定了两个圆的大小和半径,从第一个圆的圆心处向外进行扩散渐变,一直扩散到第二个圆的外轮廓处.

    设定渐变颜色的方法则与线性渐变相同

    function draw (obj) {
        var $myCanvas = document.getElementById(obj);
        if ($myCanvas == null) return false;
        var $ctx = $myCanvas.getContext('2d');
        var g1 = $ctx.createRadialGradient(400,0,0,400,0,400);
        g1.addColorStop(0,'#ff0');
        g1.addColorStop(1,'#0ff');
        $ctx.fillStyle = g1;
        $ctx.fillRect(0,0,400,300);
        $ctx.fill();
    }

    五、绘制变形图形

    默认情况下,canvas画布的最左上角对应坐标原点(0,0).如果对这个坐标使用变换处理,就可以实现图形的变形处理了,对坐标的变换处理,有三种方式:平移、扩大、旋转

    平移:

      使用图形上下文对象的translate方法移动坐标轴原点,如context.translate(x,y); ----x表示将坐标轴原点向右移动多少个单位,默认情况下为像素,y表示将坐标轴原点向下移动多少单位.

    扩大:

      使用图形上下文对象的scale方法将图形放大,如:context.scale(x,y); ----x表示水平方向的放大倍数,y表示垂直方向的放大倍数.(注:当需要将图形缩小的时候,可以将其参数值设置为0-1之间的小数即可)

    旋转:

      使用图形上下文对象的rotate方法将图形进行旋转,如:context.rotate(angle); ----angle表示旋转角度,旋转中心是坐标轴的原点,以顺时针方向进行旋转(注:如需逆时针进行旋转,将angle设定为负数即可)

    代码示例:

    function draw (obj) {
        var $myCanvas = document.getElementById(obj);
        if ($myCanvas == null) return false;
        var $ctx = $myCanvas.getContext('2d');
        $ctx.fillStyle = '#eef';
        $ctx.fillRect(0,0,400,300);
        $ctx.translate(200,50);
        $ctx.fillStyle = 'rgba(255,0,0,0.25)';
        for (var i = 0; i < 50; i++) {
            $ctx.translate(25,25);
            $ctx.scale(0.95,0.95);
            $ctx.rotate(Math.PI/10);
            $ctx.fillRect(0,0,100,50);
        }
    }

    坐标变换与路径的结合使用:必须先另写一个创建路径的函数,然后再坐标变换的同时调用该函数

    代码示例:

    function draw (obj) {
        var $myCanvas = document.getElementById(obj);
        if ($myCanvas == null) return false;
        var $ctx = $myCanvas.getContext('2d');
        $ctx.fillStyle = '#eef';
        $ctx.fillRect(0,0,400,300);
        $ctx.translate(200,50);
        for (var i = 0; i < 50; i++) {
            $ctx.translate(25,25);
            $ctx.scale(0.95,0.95);
            $ctx.rotate(Math.PI/10);
            create5Star($ctx);
            $ctx.fill();
        }
    }
    function create5Star (context) {
        var n = 0,
            dx = 100,
            dy = 0,
            s = 50;
        context.beginPath();
        context.fillStyle = 'rgba(255,0,0,0.5)';
        var x = Math.sin(0),
            y = Math.cos(0),
            dig = Math.PI/5*4;
        for (var i = 0; i < 5; i++) {
            var x = Math.sin(i*dig),
                y = Math.cos(i*dig);
            context.lineTo(dx+x*s,dy+y*s);
        }
        context.closePath();
    }

    接下来还有矩阵变换,其中首先涉及到变换矩阵,这个矩阵是专门用来实现图形变形的,它与坐标系一起配合使用,以达到变形的目的,当图形上下文被创建完毕时,事实上也创建了一个默认的变换矩阵,如果不对这个变换矩阵进行修改,那么接下来绘制的图形将以画布的最左上角为坐标原点绘制图形,绘制出来的图形也不经过缩放、变形的处理,如果对这个变换矩阵进行修改,那么情况则完全不一样了.

    使用图形上下文对象的transform方法修改变换矩阵,如:context.transform(m11,m12,m21,m22,dx,dy);这里面的m11,m12,m21,m22四个参数涉及到矩阵乘法的,这里不过多介绍(实际上是差不多都丢给老师了)

    实际上上面提到的translate,scale,rotate可以对transform进行代替.(太难了,有点研究不透了,结束!)

  • 相关阅读:
    koa 放置 前台打包dist 目录
    tomcat startup.bat 包含springboot的输出 里面乱码的解决方案
    base64 转文件上传
    4时4态 加被动 例句:I will have been being done
    软件推荐 Notable / 现改用 Vnote 了
    [win10] 开始-设置 / 右键-显示设置 / 右键个性化 等都不好使了。。 ms-settings:display
    viewui tree 自定义化(源码copy出来改动)#添加 获取selected 解决方案
    idea 暂存 Stash Changes Git/Repository/Stash Changes 恢复暂存 UnStash Changes
    vm 虚拟机总是蓝屏 移除打印机和声卡 移除这俩硬件 (大文件用飞秋传输)
    docker中mysql 汉字乱码,显示问号
  • 原文地址:https://www.cnblogs.com/fbzs/p/7111353.html
Copyright © 2011-2022 走看看