canvas_canvas- - CSDN
canvas 订阅
《canvas》是从2005年10月3日开始放映的24集日本动画,由F&C ZEXCS制作发行,讲述了拥有超人的绘画天分的男主角的故事。 展开全文
《canvas》是从2005年10月3日开始放映的24集日本动画,由F&C ZEXCS制作发行,讲述了拥有超人的绘画天分的男主角的故事。
信息
外文名
Canvas
制作·发行
F&C ZEXCS
放映日期
2005年10月3日
日文名
虹色のスケッチ
国    家
日本
总共集数
24
canvas剧情简介
拥有超人的绘画天分的男主角,却因某事故无法再次执起画笔,只能委身于某所大学,担任美术课的顾问。受男主角指导走向绘画之路的女主角,却因目睹双亲车祸身亡的现场,而在作画中无法使用红色。青梅竹马的女伴,可是高中时代的告白,却遭到男主角的拒绝,现在她又重新闯入了男主角的生活。 偶然的再会…… 三人之间,会发生什么?爱的前路,会走向哪里?
收起全文
  • web前端:Canvas 基础(一)

    0.前言

    最近忙里偷闲,来写写文章。

    ————-我是华丽的分割线————–

    终于把这篇文章写完了,关于本文,针对读者主要是之前从未接触过 Canvas的同学。当然,你要学 canvas 一定要有 JS 基础啦。

    其次就是,因为前前后后耽误了两天时间,可能在书写和描述中出现一些小的纰漏,请各位读者老爷见谅。

    最后,也希望这篇文章能够对迷茫的你产生一些帮助,感谢。

    1. canvas 简介


    1.1 canvas 是什么?

    是HTML5中重要的元素,和audio、video元素类似完全不需要任何外部插件就能够运行.

    Canvas中文翻译就是”画布”.它提供了强大的图形的处理功能(绘制,变换,像素处理…)。

    但是需要注意,canvas 元素本身并不绘制图形,它只是相当于一张空画布。

    如果开发者需要向 canvas 上绘制图形,则必须使用 JavaScript 脚本进行绘制。

    1.2 canvas 能够做什么?

    • 基础图形的绘制
    • 文字的绘制
    • 图形的变形和图片的合成
    • 图片和视频的处理
    • 动画的实现
    • 小游戏的制作

    1.3 支持的浏览器

    大多数现代浏览器都是支持Canvas的,比如 Firefox, safari, chrome, opera的最近版本以及IE9都支持.

     IE8及以下不支持HTML5,但是我们可以进行提示用户更新到最新的版本

    1.4 关于canvas 标签的基本概念

    在 HTML 页面上定义 canvas 元素与定义其他普通元素并无任何不同,它吃了可以指定 id, style ,class ,hidden 等通用属性之外,还可以设置 width 和 height 两个属性。

    为什么要特意去说这个呢?

    咱们在 章节 2.2 中详细去说明。

    除此之外,我们在网页中定义 canvas 元素之后,它只是一张空白的画布,想要在画布上绘画,一定要经过下面几步。

    1. 获取 canvas 元素对应的 DOM 对象,这必须是一个 canvas 对象
    2. 调用 canvas 对象的 getContext( ) 方法,该方法返回一个 canvasRenderingContext2D 对象,该对象可以绘制图形。
    3. 调用 canvasRenderingContext2D 对象的方法进行绘图。

    那么我们就来开始我们的canvas 实战,来看看 canvas 该如何会绘制图形。

    2.canvas 实战


    2.1 查看当前浏览器对 canvas 的支持情况

    我们在上面也说明了,我们的一些浏览器是不支持 canvas 的,这个时候我们应该怎么去做呢?

    这时候我们可以直接在 canvas 标签之间去书写内容,这么做的好处是当你的浏览器不支持 canvas 的时候,我们可以去展示标签之间的内容,具体如下。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
        <style type="text/css">
            html,body{
                margin: 0px;
            }
            canvas{
                background: #ccc;
            }
        </style>
    </head>
    <body>
        <canvas>
            我们在设置 canvas 之前需要首先监测用户电脑是否支持 canvas
        </canvas>
    </body>
    </html>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    既然已经创建完成了具体的内容,那我们现在可以看见了么?

    我们虽然没有给定 canvas 的宽度和高度,但是实际上我们的canvas 在页面中是可见的

    需要注意,canvas 默认样式的宽度和高度 是 300px * 150px.

    即使我们不去设置具体的宽度和高度,它也是可以显示的。

    <!DOCTYPE html>
    <html lang="en">
    <head>
     <meta charset="UTF-8">
     <title>Document</title>
     <style type="text/css">
      html,body{
       margin: 0px;
      }
      canvas{
       background: #ccc;
      }
     </style>
    </head>
    <body>
     <canvas>
      我们在设置 canvas 之前需要首先监测用户电脑是否支持 canvas
     </canvas>
    </body>
    </html>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    2.png

    那我们该如何去修改画布的默认大小呢?

    2.2 修改 Canvas 的画布

    按照我们正常的思路来说,我们会直接去使用 canvas_1.style.width = "500px"; 来去修改我们的 canvas 的宽度,但是这样真的对么?

    答案当然是否定的,canvas 相当于是一张图片,如果我们设置 <canvas width="500" height="500">.

    这样写相当于图片的实际大小是 500 * 500.

    但是,假如我们这样去书写。

    <canvas style="width:500px;height:500px;">

    这样实际是把 canvas 默认的 300 * 150 的图片强行拉伸为 500px * 500px 了,所以这样会导致我们的内容被强行缩放,从而导致问题。

    <!DOCTYPE html>
    <html lang="en">
    <head>
     <meta charset="UTF-8">
     <title>Document</title>
     <style type="text/css">
      html,body{
       margin: 0px;
      }
      canvas{
       background: #ccc;
      }
     </style>
    </head>
    <body>
     <canvas id="canvas_1">
      我们在设置 canvas 之前需要首先监测用户电脑是否支持 canvas
     </canvas>
    </body>
    <script type="text/javascript">
     var canvas_1 = document.getElementById("canvas_1");
     // 设置宽度和高度,但是这种写法会造成额外的问题
     // 画布会拉伸
     // canvas_1.style.width = "500px";
     // canvas_1.style.height = "500px";
    
     // 所以推荐写法
     // 1.使用内联样式表
     // 2.去使用点(.)
     canvas_1.width = "500"; //注意,不要加 px
     canvas_1.height = "500";
    
    </script>
    </html>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    2.3 获取绘制环境

    我们在上面已经设置了我们的画布的大小,但是存在一个问题。

    我们还没有找到我们的画布呀!~

    要是我们连具体的画布都没有,我们又该向哪里去绘画呢?

    实际上我们可以通过 var ctx = canvas_1.getContext("2d"); 来去获取到我们的绘制环境。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
        <canvas id="canvas_1" width="500" height="400" style="box-shadow: 0 0 20px black;">
            当前浏览器不支持 canvas
        </canvas>
    </body>
    <script type="text/javascript">
    
        // 获取 canvas 元素对应的 DOM 对象
        var canvas_1 = document.getElementById("canvas_1");
    
        // 获取在 canvas 上绘图的 canvasRenderingContent2D 对象
        var ctx = canvas_1.getContext("2d");
    
        // 打印一下,查看是否能够显示具体环境
        console.log(ctx);
    
    </script>
    </html>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    假如打印成功,我们应该可以在浏览器中的 console 中查看到我们的画布具体信息。

    3.png

    但是请注意,getContext("2d"); 中一定是2d而不是2D,否则不会生效。

    2.4 绘制的坐标轴

    既然我们已经能够获取到我们具体的画布了,那我们是不是开始绘制了呀。

    先等等,我们首先先来分析一个问题,就是我们绘制图形的时候,以这个一个区域,我们应该从哪里开始,设置的数值又应该从哪里开始呢?这时候你就应该去想一想,是不是存在这么一个坐标轴,可以根据这个坐标轴来书写我们的数值呢?

    Paste_Image.png

    请注意,横轴向右是正,纵轴向下是正

    2.5 绘制直线

    我们既然要画一条直线,我们是不是至少应该有这么几个条件呢?

    • 线的起点
    • 线的终点
    • 线的颜色
    • 线的宽度

    所以我们接下来,就需要开始我们的代码书写了。

    我们该如何去进行绘制呢?

    我们需要一些工具,需要具体的方法。

    方法 说明
    beginPath() 开始定义路径
    closePath() 关闭前面定义的路径
    moveTo(float x,float y) 把 canvas 的当前路径的结束点移动到 x, y 对应的点
    lineTo(float x,float y) 把 canvas 的当前路径从当前结束点连接到 x , y 对应的点

    需要注意,moveTo 可以简单理解为,把当前绘制图像的起点设置为某一特定坐标,而 lineTo 则是将当前的起点和你想要设置的那个点之间连接起来。

    而 beginPath 是表示开始定义路径,不会产生特殊的效果。而 closePath 除了表示关闭当前定义的路径之外,还会有一个特殊的作用,就是可以将当前绘制图形的最后一个点和我们绘制图形开始的点进行连接,这一点咱们在章节2.6 中详细去看一下。当然,如果你只需要画一条线,不去加beginPath 和 closep 你的内容实际也是可以出来的,但是推荐加上。

    这个时候我们可以来运行一下,看看效果是否能够出来。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
        <div>
            <canvas id="canvas_1" width="1000" height="500" style="box-shadow: 0px 0px 20px black;">
                当前浏览器不支持 canvas
            </canvas>
        </div>
    </body>
    <script type="text/javascript">
        // 获取 canvas 元素对应的 DOM 对象
        var canvas_1 = document.getElementById("canvas_1");
    
        // 获取在 canvas 上绘图的 canvasRenderingContent2D 对象
        var ctx = canvas_1.getContext("2d");
    
        // 打印一下,查看是否能够显示具体环境
        console.log(ctx);
    
        // 开始绘制
        ctx.beginPath();
    
        //设置绘制起点
        ctx.moveTo(0,0);
    
        //设置绘制下一个点
        ctx.lineTo(700,400);
    
        //结束绘制
        ctx.closePath();
    
    </script>
    </html>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    发现了什么?我们的图形什么都没有出来呀,鹏哥你是不是坑我们呀?

    怎么可能,我那么帅气。

    效果没出来,只是因为 你已经把你的画笔的颜料,要画什么样的线条,全部都想好了,可是你往你的画布上绘画了么?

    没有对吧,所以咯,我们还需要有其他的方法去进行配合。

    - -
    fill() 填充 canvas 当前路径
    stroke() 填充 canvas 当前路径绘制边框

    这个时候我们添加上我们的 stroke() 之后,我们就发现我们的线条出现了。

    可是这条线一直是灰色的呀,好丑,我们想要自己去修改我们的线,该怎么做呢?

    - -
    fillStyle() 设置填充 canvas 路径所使用的填充风格
    strokeStyle() 设置绘制 canvas 路径的填充风格

    他们两个都支持三个属性值。

    1. 符合颜色格式的字符串值,表示使用纯色填充
    2. CanvasGradient,表明使用渐变填充
    3. CanvasPattern,表明使用位图填充

    这几个值,咱们在后续的课程中会去详细说明,在当前不去做更多阐述。

    除此之外,我们还可以设置一下线的宽度。

    - -
    lineWidth() 设置笔触线条的宽度

    这样我们就可以画出一些我们想要的线条的样式了。

    Paste_Image.png

    2.6 绘制三角形

    我们已经创建了这一条线段,那么我们平常开发中不会仅仅让你去绘制一条线吧,最起码我们需要会绘制出一个小的三角形吧。

    这时候我们就需要再去绘制两条线了。

    怎么去添加线呢?lineTo对吧。

    这个时候我们再去绘制一条线。

        //设置绘制起点
        ctx.moveTo(100,100);
    
        //设置绘制下一个点
        ctx.lineTo(700,400);
    
        //设置绘制下一个点
        ctx.lineTo(400,100);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    这时候神奇的事情发生了,我们的三角形直接就出现了,可是我们仅仅绘制了两条线呀。

    Paste_Image.png

    这是因为,我们在绘制图形的时候,是不是设置了一个方法?

    还记得上面对 closePath 的描述么?

        //结束绘制
        ctx.closePath();
    • 1
    • 2

    这时因为当我们结束绘制的,电脑会自动将你设置的线段自动连接起来。

    Paste_Image.png

    这个时候我们应该有两个想法了。

    1. 我们可以用这个特性去做一个长方形或者多边形等。

    2. 我们需要给我们的方块内部设置一个颜色。

    那么我们首先来说一下,如何设置一个背景颜色。

    这时候我们需要使用填充。

        // 设置填充样式
        ctx.fillStyle = "green";
    
        // 填充当前视图
        ctx.fill();
    • 1
    • 2
    • 3
    • 4
    • 5

    这个时候我们就能看见,我们的背景颜色就已经成功填充了。

    Paste_Image.png

    当然,我的审美一直很特立独行,所以各位小伙伴也不要在意太多细节啦,科科。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
        <div>
            <canvas id="canvas_1" width="1000" height="500" style="box-shadow: 0px 0px 20px black;">
                当前浏览器不支持 canvas
            </canvas>
        </div>
    </body>
    <script type="text/javascript">
    
        // 获取 canvas 元素对应的 DOM 对象
        var canvas_1 = document.getElementById("canvas_1");
    
        // 获取在 canvas 上绘图的 canvasRenderingContent2D 对象
        var ctx = canvas_1.getContext("2d");
    
        // 打印一下,查看是否能够显示具体环境
        console.log(ctx);
    
        // 开始绘制
        ctx.beginPath();
    
        //设置绘制起点
        ctx.moveTo(100,100);
    
        //设置绘制下一个点
        ctx.lineTo(700,400);
    
        //设置绘制下一个点
        ctx.lineTo(400,100);
    
        //设置绘制下一个点
        ctx.lineTo(600,500);
    
        //结束绘制
        ctx.closePath();
    
        //设置线的宽度
        ctx.lineWidth = 10;
    
        //设置绘制的样式
        ctx.strokeStyle = "red";
    
        //绘制点之间的线路
        ctx.stroke();
    
        // 设置填充样式
        ctx.fillStyle = "green";
    
        // 填充当前视图
        ctx.fill();
    
        // 注意:所有的绘制相应属性全部应该放在 closePath 之前
    
    </script>
    </html>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61

    除此之外,还有一个需要注意的点,就是我们现在的图形是不是角度都是非常尖锐的?

    那我们是不是可以把这个效果修改一下,改的圆滑一点呢?

    这时候再来跟大家说另外一个属性。

    - -
    lineJoin 设置返回所创建边角的类型,当两条线交汇时。

    通过这个属性,我们就可以去修改我们图形的拐角的样式了,这个样式里面存在三个属性。需要注意一点,你去设置边角的样式,一定要设置在你的绘制矩形框之前,否则效果是不会出现的。

    - -
    bevel 创建斜角
    round 创建圆角
    miter 默认,创建尖角

    miter.png

    round.png

    bevel.png

    这时候我们的效果就已经全部出现了。

    那么大家可以去尝试制作一下下图的内容。

    Paste_Image.png

    2.7 绘制矩形

    不知道小伙伴们有没有将上面的内容成功设置出来呢?

    如果出来了,我们发现一个非常坑爹的情况,他喵的每设置一次都需要专门去计算这个内容的对应数值么?

    不能这么坑爹吧,所以这个时候我们要去学习另外一个方法。

    - -
    strokeRect(float x,float y,float width,float height) 绘制一个矩形边框
    fillRect(float x,float y,float width,float height) 填充一个矩形边框

    有了这两个方法,我们的矩形绘制就非常方便啦。

    那么我们来尝试一下。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
        <div>
            <h2>绘制矩形</h2>
            <canvas id="canvas_1" width="1000" height="500" style="box-shadow: 0px 0px 20px black;">
                当前浏览器不支持 canvas
            </canvas>
        </div>
    </body>
    <script type="text/javascript">
        // 获取 canvas 元素对应的 DOM 对象
        var canvas_1 = document.getElementById("canvas_1");
    
        // 获取在 canvas 上绘图的 canvasRenderingContent2D 对象
        var ctx = canvas_1.getContext("2d");
    
        // 设置填充颜色
        ctx.fillStyle = '#f00';
        // 填充一个矩形
        ctx.fillRect(30,20,120,60);
    
        // 设置填充颜色
        ctx.fillStyle = '#ff0';
        // 填充一个矩形
        ctx.fillRect(80,60,120,60);
    
        // 设置填充颜色
        ctx.strokeStyle = '#00f';
        // 填充一个矩形
        ctx.strokeRect(30,130,120,60);
        // 设置线条宽度
        ctx.lineWidth = 20;
    
        // 设置线条宽度
        ctx.lineJoin = "round";
        // 设置填充颜色
        ctx.strokeStyle = '#0ff';
        // 填充一个矩形
        ctx.strokeRect(80,160,120,60);
    
    
        // 设置线条宽度
        ctx.lineJoin = "bevel";
        // 设置填充颜色
        ctx.strokeStyle = '#f0f';
        // 填充一个矩形
        ctx.strokeRect(130,190,120,60);
    
    
        ctx.storke();
    
    </script>
    </html>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58

    Paste_Image.png

    2.8 绘制字符串

    我猜现在很多小伙伴都在想,我们可以绘制线条,可以绘制多边形,还可以绘制矩形了,那么接下来是不是要开始学习绘制圆形呢?

    当然不是,因为绘制圆形设计到的内容比较多,咱们放在下一篇文章中来书写。

    今天咱们就先来看一下,我们该如何去绘制我们的字符串。

    在绘制字符串之前同样需要跟大家说这么几个方法。

    - -
    fillText(String Text, float x, float y, [float maxWidth]) 填充字符串
    strokeText(String Text, float x, float y, [float maxWidth]) 绘制字符串边框

    同时我们既然设置了字符串的内容,我们是不是还需要去对我们字符串的对齐方式什么的去做一做设置呢?

    - -
    textAlign 设置绘制字符串的水平对齐方式(start、end、left、right、center等)
    textBaseAlign 设置绘制字符串的垂直对齐方式(top、hanging、middle、alphabetic、idecgraphic、bottom 等)

    了解了这些具体的方法,那我们再来看一下,我们该如何去设置我们的字符串内容。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
        <div>
            <h2>绘制文字</h2>
            <canvas id="canvas_1" width="1000" height="500" style="box-shadow: 0px 0px 20px black;">
                当前浏览器不支持 canvas
            </canvas>
        </div>
    </body>
    <script type="text/javascript">
        // 获取 canvas 元素对应的 DOM 对象
        var canvas_1 = document.getElementById("canvas_1");
    
        // 获取在 canvas 上绘图的 canvasRenderingContent2D 对象
        var ctx = canvas_1.getContext("2d");
    
        ctx.fillStyle = '#00f';
        ctx.font = 'italic 50px 隶书';
        ctx.textBaseline = 'top';
    
        //填充字符串
        ctx.fillText('汪先生真是帅',0,0);
        ctx.strokeStyle = 'f0f';
        ctx.font = 'bold 45px 宋体';
    
        // 绘制字符串的边框
        ctx.strokeText('汪先生我爱你',0,50,200);
    
    </script>
    </html>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35


    2.9 设置阴影

    我们在之前学习 HTML 的过程中,跟大家说过,我们的阴影可以简单分为两种,盒阴影和文字阴影,那在我们的画布中,是否也存在这么一个东西,能够为我们的文字去设置一个阴影呢?

    当然有,要不我也不会专门去提这个事情,对吧。

    我们学习设置阴影,同样要使用这么几个属性。

    - -
    shadowBlur 设置阴影的模糊程度。该值是一个浮点数,该数值越大,阴影的模糊程度也就越大。
    shadowColor 设置阴影的颜色。
    shadowOffsetX 设置阴影在 X 方向的偏移
    shadowOffsetY 设置阴影在 Y 方向的偏移

    那么我们接下来,一起来看看我们该如何去设置阴影。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
        <div>
            <h2>绘制文字</h2>
            <canvas id="canvas_1" width="1000" height="500" style="box-shadow: 0px 0px 20px black;">
                当前浏览器不支持 canvas
            </canvas>
        </div>
    </body>
    <script type="text/javascript">
        // 获取 canvas 元素对应的 DOM 对象
        var canvas_1 = document.getElementById("canvas_1");
    
        // 获取在 canvas 上绘图的 canvasRenderingContent2D 对象
        var ctx = canvas_1.getContext("2d");
    
        // 设置阴影的模糊程度
        ctx.shadowBlur = 5.6;
    
        // 设置阴影的颜色
        ctx.shadowColor = '#222';
    
        // 设置阴影在 X,Y 方向的偏移
        ctx.shadowOffsetX = 10;
        ctx.shadowOffsetY = -6;
    
        ctx.fillStyle = '#00f';
        ctx.font = 'italic 50px 隶书';
        ctx.textBaseline = 'top';
    
        //填充字符串
        ctx.fillText('汪先生真是帅',0,0);
        ctx.strokeStyle = 'f0f';
        ctx.font = 'bold 45px 宋体';
    
        // 绘制字符串的边框
        ctx.strokeText('汪先生我爱你',0,50,200);
    
    </script>
    </html>
    展开全文
  • 一、canvas简介&amp;amp;lt;canvas&amp;amp;gt; 是 HTML5 新增的,一个可以使用脚本(通常为JavaScript)在其中绘制图像的 HTML 元素。它可以用来制作照片集或者制作简单(也不是那么简单)的动画,甚至可以进行...

    一、canvas简介

    <canvas>HTML5 新增的,一个可以使用脚本(通常为JavaScript)在其中绘制图像的 HTML 元素。它可以用来制作照片集或者制作简单(也不是那么简单)的动画,甚至可以进行实时视频处理和渲染。

    ​ 它最初由苹果内部使用自己MacOS X WebKit推出,供应用程序使用像仪表盘的构件和 Safari 浏览器使用。 后来,有人通过Gecko内核的浏览器 (尤其是MozillaFirefox),OperaChrome和超文本网络应用技术工作组建议为下一代的网络技术使用该元素。

    Canvas是由HTML代码配合高度和宽度属性而定义出的可绘制区域。JavaScript代码可以访问该区域,类似于其他通用的二维API,通过一套完整的绘图函数来动态生成图形。

    ​ Mozilla 程序从 Gecko 1.8 (Firefox 1.5)开始支持 <canvas>, Internet Explorer 从IE9开始<canvas> 。Chrome和Opera 9+ 也支持 <canvas>

    二、Canvas基本使用

    2.1 <canvas>元素

    <canvas id="tutorial" width="300" height="300"></canvas>
    

    <canvas>看起来和<img>标签一样,只是 <canvas> 只有两个可选的属性 width、heigth 属性,而没有 src、alt 属性。

    ​ 如果不给<canvas>设置widht、height属性时,则默认 width为300、height为150,单位都是px。也可以使用css属性来设置宽高,但是如宽高属性和初始比例不一致,他会出现扭曲。所以,建议永远不要使用css属性来设置<canvas>的宽高。

    ###替换内容

    ​ 由于某些较老的浏览器(尤其是IE9之前的IE浏览器)或者浏览器不支持HTML元素<canvas>,在这些浏览器上你应该总是能展示替代内容。

    ​ 支持<canvas>的浏览器会只渲染<canvas>标签,而忽略其中的替代内容。不支持 <canvas> 的浏览器则 会直接渲染替代内容。

    用文本替换:

    <canvas>
        你的浏览器不支持canvas,请升级你的浏览器
    </canvas>
    

    <img> 替换:

    <canvas>
        <img src="./美女.jpg" alt=""> 
    </canvas>
    

    结束标签</canvas>不可省

    <img>元素不同,<canvas>元素需要结束标签(</canvas>)。如果结束标签不存在,则文档的其余部分会被认为是替代内容,将不会显示出来。

    2.2 渲染上下文(Thre Rending Context)

    <canvas>会创建一个固定大小的画布,会公开一个或多个 渲染上下文(画笔),使用 渲染上下文来绘制和处理要展示的内容。

    ​ 我们重点研究 2D渲染上下文。 其他的上下文我们暂不研究,比如, WebGL使用了基于OpenGL ES的3D上下文 (“experimental-webgl”) 。

    var canvas = document.getElementById('tutorial');
    //获得 2d 上下文对象
    var ctx = canvas.getContext('2d');
    

    2.3 检测支持性

    var canvas = document.getElementById('tutorial');
    
    if (canvas.getContext){
      var ctx = canvas.getContext('2d');
      // drawing code here
    } else {
      // canvas-unsupported code here
    }
    

    2.4 代码模板

    <html>
    <head>
        <title>Canvas tutorial</title>
        <style type="text/css">
            canvas {
                border: 1px solid black;
            }
        </style>
    </head>
    <canvas id="tutorial" width="300" height="300"></canvas>
    </body>
    <script type="text/javascript">
        function draw(){
            var canvas = document.getElementById('tutorial');
            if(!canvas.getContext) return;
          	var ctx = canvas.getContext("2d");
          	//开始代码
            
        }
        draw();
    </script>
    </html>
    

    2.5 一个简单的例子

    绘制两个长方形。

    <html>
    <head>
        <title>Canvas tutorial</title>
        <style type="text/css">
            canvas {
                border: 1px solid black;
            }
        </style>
    </head>
    <canvas id="tutorial" width="300" height="300"></canvas>
    </body>
    <script type="text/javascript">
        function draw(){
            var canvas = document.getElementById('tutorial');
            if(!canvas.getContext) return;
            var ctx = canvas.getContext("2d");
            ctx.fillStyle = "rgb(200,0,0)";
          	//绘制矩形
            ctx.fillRect (10, 10, 55, 50);
    
            ctx.fillStyle = "rgba(0, 0, 200, 0.5)";
            ctx.fillRect (30, 30, 55, 50);
        }
        draw();
    </script>
    </html>
    

    三、绘制形状

    3.1 栅格(grid)和坐标空间

    ​ 如下图所示,canvas元素默认被网格所覆盖。通常来说网格中的一个单元相当于canvas元素中的一像素。栅格的起点为左上角(坐标为(0,0))。所有元素的位置都相对于原点来定位。所以图中蓝色方形左上角的坐标为距离左边(X轴)x像素,距离上边(Y轴)y像素(坐标为(x,y))。

    ​ 后面我们会涉及到坐标原点的平移、网格的旋转以及缩放等。

    3.2 绘制矩形

    <canvas> 只支持一种原生的 图形绘制:矩形。所有其他图形都至少需要生成一种路径(path)。不过,我们拥有众多路径生成的方法让复杂图形的绘制成为了可能。

    canvast 提供了三种方法绘制矩形:

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

      绘制一个填充的矩形

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

      绘制一个矩形的边框

    3. clearRect(x, y, widh, height)

      清除指定的矩形区域,然后这块区域会变的完全透明。

    说明:

    ​ 这3个方法具有相同的参数。

    x, y:指的是矩形的左上角的坐标。(相对于canvas的坐标原点)

    width, height:指的是绘制的矩形的宽和高。

    function draw(){
        var canvas = document.getElementById('tutorial');
        if(!canvas.getContext) return;
        var ctx = canvas.getContext("2d");
        ctx.fillRect(10, 10, 100, 50);  //绘制矩形,填充的默认颜色为黑色
        ctx.strokeRect(10, 70, 100, 50);  //绘制矩形边框
        
    }
    draw();
    

    ctx.clearRect(15, 15, 50, 25);
    

    

    四、绘制路径(path)

    ​ 图形的基本元素是路径。

    ​ 路径是通过不同颜色和宽度的线段或曲线相连形成的不同形状的点的集合。

    ​ 一个路径,甚至一个子路径,都是闭合的。

    使用路径绘制图形需要一些额外的步骤:

    1. 创建路径起始点
    2. 调用绘制方法去绘制出路径
    3. 把路径封闭
    4. 一旦路径生成,通过描边或填充路径区域来渲染图形。

    下面是需要用到的方法:

    1. beginPath()

      新建一条路径,路径一旦创建成功,图形绘制命令被指向到路径上生成路径

    2. moveTo(x, y)

      把画笔移动到指定的坐标(x, y)。相当于设置路径的起始点坐标。

    3. closePath()

      闭合路径之后,图形绘制命令又重新指向到上下文中

    4. stroke()

      通过线条来绘制图形轮廓

    5. fill()

      通过填充路径的内容区域生成实心的图形

    4.1 绘制线段

    function draw(){
        var canvas = document.getElementById('tutorial');
        if (!canvas.getContext) return;
        var ctx = canvas.getContext("2d");
        ctx.beginPath(); //新建一条path
        ctx.moveTo(50, 50); //把画笔移动到指定的坐标
        ctx.lineTo(200, 50);  //绘制一条从当前位置到指定坐标(200, 50)的直线.
        //闭合路径。会拉一条从当前点到path起始点的直线。如果当前点与起始点重合,则什么都不做
        ctx.closePath();
        ctx.stroke(); //绘制路径。
    }
    draw();
    

    4.2 绘制三角形边框

    function draw(){
        var canvas = document.getElementById('tutorial');
        if (!canvas.getContext) return;
        var ctx = canvas.getContext("2d");
        ctx.beginPath();
        ctx.moveTo(50, 50);
        ctx.lineTo(200, 50);
        ctx.lineTo(200, 200);
      	ctx.closePath(); //虽然我们只绘制了两条线段,但是closePath会closePath,仍然是一个3角形
        ctx.stroke(); //描边。stroke不会自动closePath()
    }
    draw();
    

    4.3 填充三角形

    function draw(){
        var canvas = document.getElementById('tutorial');
        if (!canvas.getContext) return;
        var ctx = canvas.getContext("2d");
        ctx.beginPath();
        ctx.moveTo(50, 50);
        ctx.lineTo(200, 50);
        ctx.lineTo(200, 200);
       
        ctx.fill(); //填充闭合区域。如果path没有闭合,则fill()会自动闭合路径。
    }
    draw();
    

    4.4 绘制圆弧

    有两个方法可以绘制圆弧:

    1. arc(x, y, r, startAngle, endAngle, anticlockwise):

      (x, y)为圆心,以r为半径,从 startAngle弧度开始到endAngle弧度结束。anticlosewise是布尔值,true表示逆时针,false表示顺时针。(默认是顺时针)

      注意:

      1. 这里的度数都是弧度。
      2. 0弧度是指的x轴正方形
      radians=(Math.PI/180)*degrees   //角度转换成弧度
      
    2. arcTo(x1, y1, x2, y2, radius):

      根据给定的控制点和半径画一段圆弧,最后再以直线连接两个控制点。

    圆弧案例1:

    function draw(){
        var canvas = document.getElementById('tutorial');
        if (!canvas.getContext) return;
        var ctx = canvas.getContext("2d");
        ctx.beginPath();
        ctx.arc(50, 50, 40, 0, Math.PI / 2, false);
        ctx.stroke();
    }
    draw();
    

    圆弧案例2:

    function draw(){
        var canvas = document.getElementById('tutorial');
        if (!canvas.getContext) return;
        var ctx = canvas.getContext("2d");
        ctx.beginPath();
        ctx.arc(50, 50, 40, 0, Math.PI / 2, false);
        ctx.stroke();
    
        ctx.beginPath();
        ctx.arc(150, 50, 40, 0, -Math.PI / 2, true);
        ctx.closePath();
        ctx.stroke();
    
        ctx.beginPath();
        ctx.arc(50, 150, 40, -Math.PI / 2, Math.PI / 2, false);
        ctx.fill();
    
        ctx.beginPath();
        ctx.arc(150, 150, 40, 0, Math.PI, false);
        ctx.fill();
    
    }
    draw();
    

    圆弧案例3:

    function draw(){
        var canvas = document.getElementById('tutorial');
        if (!canvas.getContext) return;
        var ctx = canvas.getContext("2d");
        ctx.beginPath();
        ctx.moveTo(50, 50);
      	//参数1、2:控制点1坐标   参数3、4:控制点2坐标  参数4:圆弧半径
        ctx.arcTo(200, 50, 200, 200, 100);
        ctx.lineTo(200, 200)
        ctx.stroke();
        
        ctx.beginPath();
        ctx.rect(50, 50, 10, 10);
        ctx.rect(200, 50, 10, 10)
        ctx.rect(200, 200, 10, 10)
        ctx.fill()
    }
    draw();
    

    arcTo方法的说明:

    ​ 这个方法可以这样理解。绘制的弧形是由两条切线所决定。

    ​ 第 1 条切线:起始点和控制点1决定的直线。

    ​ 第 2 条切线:控制点1 和控制点2决定的直线。

    其实绘制的圆弧就是与这两条直线相切的圆弧。

    4.5 绘制贝塞尔曲线

    4.5.1 什么是贝塞尔曲线

    ​ 贝塞尔曲线(Bézier curve),又称贝兹曲线或贝济埃曲线,是应用于二维图形应用程序的数学曲线。

    ​ 一般的矢量图形软件通过它来精确画出曲线,贝兹曲线由线段与节点组成,节点是可拖动的支点,线段像可伸缩的皮筋,我们在绘图工具上看到的钢笔工具就是来做这种矢量曲线的。

    ​ 贝塞尔曲线是计算机图形学中相当重要的参数曲线,在一些比较成熟的位图软件中也有贝塞尔曲线工具如PhotoShop等。在Flash4中还没有完整的曲线工具,而在Flash5里面已经提供出贝塞尔曲线工具。

    ​ 贝塞尔曲线于1962,由法国工程师皮埃尔·贝塞尔(Pierre Bézier)所广泛发表,他运用贝塞尔曲线来为汽车的主体进行设计。贝塞尔曲线最初由Paul de Casteljau于1959年运用de Casteljau演算法开发,以稳定数值的方法求出贝兹曲线。

    一次贝塞尔曲线(线性贝塞尔曲线)

    ​ 一次贝塞尔曲线其实是一条直线。

    二次贝塞尔曲线

    三次贝塞尔曲线

    4.5.2 绘制贝塞尔曲线

    绘制二次贝塞尔曲线

    quadraticCurveTo(cp1x, cp1y, x, y):

    说明:

    ​ 参数1和2:控制点坐标

    ​ 参数3和4:结束点坐标

    function draw(){
        var canvas = document.getElementById('tutorial');
        if (!canvas.getContext) return;
        var ctx = canvas.getContext("2d");
        ctx.beginPath();
        ctx.moveTo(10, 200); //起始点
        var cp1x = 40, cp1y = 100;  //控制点
        var x = 200, y = 200; // 结束点
        //绘制二次贝塞尔曲线
        ctx.quadraticCurveTo(cp1x, cp1y, x, y);
        ctx.stroke();
        
        ctx.beginPath();
        ctx.rect(10, 200, 10, 10);
        ctx.rect(cp1x, cp1y, 10, 10);
        ctx.rect(x, y, 10, 10);
        ctx.fill();
        
    }
    draw();
    

    绘制三次贝塞尔曲线

    bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)

    说明:

    ​ 参数1和2:控制点1的坐标

    ​ 参数3和4:控制点2的坐标

    ​ 参数5和6:结束点的坐标

    function draw(){
        var canvas = document.getElementById('tutorial');
        if (!canvas.getContext) return;
        var ctx = canvas.getContext("2d");
        ctx.beginPath();
        ctx.moveTo(40, 200); //起始点
        var cp1x = 20, cp1y = 100;  //控制点1
        var cp2x = 100, cp2y = 120;  //控制点2
        var x = 200, y = 200; // 结束点
        //绘制二次贝塞尔曲线
        ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);
        ctx.stroke();
    
        ctx.beginPath();
        ctx.rect(40, 200, 10, 10);
        ctx.rect(cp1x, cp1y, 10, 10);
        ctx.rect(cp2x, cp2y, 10, 10);
        ctx.rect(x, y, 10, 10);
        ctx.fill();
    
    }
    draw();
    

    五、添加样式和颜色

    ​ 在前面的绘制矩形章节中,只用到了默认的线条和颜色。

    ​ 如果想要给图形上色,有两个重要的属性可以做到。

    1. fillStyle = color

      设置图形的填充颜色

    2. strokeStyle = color

      设置图形轮廓的颜色

    备注:

    1. `color` 可以是表示 `css` 颜色值的字符串、渐变对象或者图案对象。
    2. 默认情况下,线条和填充颜色都是黑色。
    3. 一旦您设置了 `strokeStyle` 或者 `fillStyle` 的值,那么这个新值就会成为新绘制的图形的默认值。如果你要给每个图形上不同的颜色,你需要重新设置 `fillStyle` 或 `strokeStyle` 的值。
    

    fillStyle

    function draw(){
      var canvas = document.getElementById('tutorial');
      if (!canvas.getContext) return;
      var ctx = canvas.getContext("2d");
      for (var i = 0; i < 6; i++){
        for (var j = 0; j < 6; j++){
          ctx.fillStyle = 'rgb(' + Math.floor(255 - 42.5 * i) + ',' +
            Math.floor(255 - 42.5 * j) + ',0)';
          ctx.fillRect(j * 50, i * 50, 50, 50);
        }
      }
    }
    draw();
    

    strokeStyle

    <script type="text/javascript">
        function draw(){
            var canvas = document.getElementById('tutorial');
            if (!canvas.getContext) return;
            var ctx = canvas.getContext("2d");
            for (var i = 0; i < 6; i++){
                for (var j = 0; j < 6; j++){
                    ctx.strokeStyle = `rgb(${randomInt(0, 255)},${randomInt(0, 255)},${randomInt(0, 255)})`;
                    ctx.strokeRect(j * 50, i * 50, 40, 40);
                }
            }
        }
        draw();
        /**
         作者:李振超      4 Jun 2017 12:12
         返回随机的 [from, to] 之间的整数(包括from,也包括to)
         */
        function randomInt(from, to){
            return parseInt(Math.random() * (to - from + 1) + from);
        }
    
    </script>
    

    Transparency(透明度)

    globalAlpha = transparencyValue

    ​ 这个属性影响到 canvas 里所有图形的透明度,有效的值范围是 0.0 (完全透明)到 1.0(完全不透明),默认是 1.0。

    globalAlpha 属性在需要绘制大量拥有相同透明度的图形时候相当高效。不过,我认为使用rgba()设置透明度更加好一些。

    line style

    1. lineWidth = value

    线宽。只能是正值。默认是1.0

    起始点和终点的连线为中心,上下各占线宽的一半

    ctx.beginPath();
    ctx.moveTo(10, 10);
    ctx.lineTo(100, 10);
    ctx.lineWidth = 10;
    ctx.stroke();
    
    ctx.beginPath();
    ctx.moveTo(110, 10);
    ctx.lineTo(160, 10)
    ctx.lineWidth = 20;
    ctx.stroke()
    

    ###2. lineCap = type

    线条末端样式。

    共有3个值:

    1. butt:线段末端以方形结束

    2. round:线段末端以圆形结束

    3. square:线段末端以方形结束,但是增加了一个宽度和线段相同,高度是线段厚度一半的矩形区域。

      var lineCaps = ["butt", "round", "square"];
      
      for (var i = 0; i < 3; i++){
          ctx.beginPath();
          ctx.moveTo(20 + 30 * i, 30);
          ctx.lineTo(20 + 30 * i, 100);
          ctx.lineWidth = 20;
          ctx.lineCap = lineCaps[i];
          ctx.stroke();
      }
      
      ctx.beginPath();
      ctx.moveTo(0, 30);
      ctx.lineTo(300, 30);
      
      ctx.moveTo(0, 100);
      ctx.lineTo(300, 100)
      
      ctx.strokeStyle = "red";
      ctx.lineWidth = 1;
      ctx.stroke();
      

    3. lineJoin = type

    同一个path内,设定线条与线条间接合处的样式。

    共有3个值round, bevelmiter

    1. round

      通过填充一个额外的,圆心在相连部分末端的扇形,绘制拐角的形状。 圆角的半径是线段的宽度。

    2. bevel

      在相连部分的末端填充一个额外的以三角形为底的区域, 每个部分都有各自独立的矩形拐角。

    3. miter(默认)

      通过延伸相连部分的外边缘,使其相交于一点,形成一个额外的菱形区域。

    function draw(){
        var canvas = document.getElementById('tutorial');
        if (!canvas.getContext) return;
        var ctx = canvas.getContext("2d");
    
        var lineJoin = ['round', 'bevel', 'miter'];
        ctx.lineWidth = 20;
    
        for (var i = 0; i < lineJoin.length; i++){
            ctx.lineJoin = lineJoin[i];
            ctx.beginPath();
            ctx.moveTo(50, 50 + i * 50);
            ctx.lineTo(100, 100 + i * 50);
            ctx.lineTo(150, 50 + i * 50);
            ctx.lineTo(200, 100 + i * 50);
            ctx.lineTo(250, 50 + i * 50);
            ctx.stroke();
        }
    
    }
    draw();
    

    4. 虚线

    setLineDash 方法和 lineDashOffset 属性来制定虚线样式. setLineDash 方法接受一个数组,来指定线段与间隙的交替;lineDashOffset属性设置起始偏移量.

    function draw(){
        var canvas = document.getElementById('tutorial');
        if (!canvas.getContext) return;
        var ctx = canvas.getContext("2d");
        
        ctx.setLineDash([20, 5]);  // [实线长度, 间隙长度]
        ctx.lineDashOffset = -0;
        ctx.strokeRect(50, 50, 210, 210);
    }
    draw();
    

    备注:

    getLineDash():返回一个包含当前虚线样式,长度为非负偶数的数组。

    六、绘制文本

    绘制文本的两个方法

    canvas 提供了两种方法来渲染文本:

    1. fillText(text, x, y [, maxWidth])

      在指定的(x,y)位置填充指定的文本,绘制的最大宽度是可选的.

    2. strokeText(text, x, y [, maxWidth])

      在指定的(x,y)位置绘制文本边框,绘制的最大宽度是可选的.

    var ctx;
    function draw(){
        var canvas = document.getElementById('tutorial');
        if (!canvas.getContext) return;
        ctx = canvas.getContext("2d");
        ctx.font = "100px sans-serif"
        ctx.fillText("天若有情", 10, 100);
        ctx.strokeText("天若有情", 10, 200)
    }
    draw();
    

    给文本添加样式

    1. font = value

      当前我们用来绘制文本的样式。这个字符串使用和 CSS font属性相同的语法. 默认的字体是 10px sans-serif

    2. textAlign = value

      文本对齐选项. 可选的值包括:start, end, left, right or center. 默认值是 start

    3. textBaseline = value

      基线对齐选项,可选的值包括:top, hanging, middle, alphabetic, ideographic, bottom。默认值是 alphabetic。

    4. direction = value

      文本方向。可能的值包括:ltr, rtl, inherit。默认值是 inherit。

    七、绘制图片

    ​ 我们也可以在canvas上直接绘制图片。

    7.1 由零开始创建图片

    创建<img>元素

    var img = new Image();   // 创建一个<img>元素
    img.src = 'myImage.png'; // 设置图片源地址
    

    脚本执行后图片开始装载

    绘制img

    //参数1:要绘制的img  参数2、3:绘制的img在canvas中的坐标
    ctx.drawImage(img,0,0); 
    

    注意:

    ​ 考虑到图片是从网络加载,如果 drawImage 的时候图片还没有完全加载完成,则什么都不做,个别浏览器会抛异常。所以我们应该保证在 img 绘制完成之后再 drawImage

    var img = new Image();   // 创建img元素
    img.onload = function(){
      ctx.drawImage(img, 0, 0)
    }
    img.src = 'myImage.png'; // 设置图片源地址
    

    7.2 绘制 img 标签元素中的图片

    img 可以 new 也可以来源于我们页面的 <img>标签

    <img src="./美女.jpg" alt="" width="300"><br>
    <canvas id="tutorial" width="600" height="400"></canvas>
    <script type="text/javascript">
        function draw(){
            var canvas = document.getElementById('tutorial');
            if (!canvas.getContext) return;
            var ctx = canvas.getContext("2d");
            var img = document.querySelector("img");
            ctx.drawImage(img, 0, 0);
        }
        document.querySelector("img").onclick = function (){
            draw();
        }
    
    </script>
    

    第一张图片就是页面中的<img>标签

    7.3 缩放图片

    drawImage() 也可以再添加两个参数:

    drawImage(image, x, y, width, height)

    ​ 这个方法多了2个参数:widthheight,这两个参数用来控制 当像canvas画入时应该缩放的大小。

    ctx.drawImage(img, 0, 0, 400, 200)
    

    7.4 切片(slice)

    drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)

    ​ 第一个参数和其它的是相同的,都是一个图像或者另一个 canvas 的引用。

    其他8个参数:

    ​ 前4个是定义图像源的切片位置和大小,

    ​ 后4个则是定义切片的目标显示位置和大小。

    八、状态的保存和恢复

    Saving and restoring state是绘制复杂图形时必不可少的操作。

    save()和restore()

    saverestore 方法是用来保存和恢复 canvas 状态的,都没有参数。

    Canvas 的状态就是当前画面应用的所有样式和变形的一个快照。

    1. 关于 save()

      Canvas状态存储在栈中,每当save()方法被调用后,当前的状态就被推送到栈中保存。一个绘画状态包括:

    • 当前应用的变形(即移动,旋转和缩放)

    • strokeStyle, fillStyle, globalAlpha, lineWidth, lineCap, lineJoin, miterLimit, shadowOffsetX, shadowOffsetY, shadowBlur, shadowColor, globalCompositeOperation 的值

    • 当前的裁切路径(clipping path

      可以调用任意多次 save方法。(类似数组的push())

    1. 关于restore()

      每一次调用 restore 方法,上一个保存的状态就从栈中弹出,所有设定都恢复。(类似数组的pop())

    var ctx;
    function draw(){
        var canvas = document.getElementById('tutorial');
        if (!canvas.getContext) return;
        var ctx = canvas.getContext("2d");
    
        ctx.fillRect(0, 0, 150, 150);   // 使用默认设置绘制一个矩形
        ctx.save();                  // 保存默认状态
    
        ctx.fillStyle = 'red'       // 在原有配置基础上对颜色做改变
        ctx.fillRect(15, 15, 120, 120); // 使用新的设置绘制一个矩形
    
        ctx.save();                  // 保存当前状态
        ctx.fillStyle = '#FFF'       // 再次改变颜色配置
        ctx.fillRect(30, 30, 90, 90);   // 使用新的配置绘制一个矩形
    
        ctx.restore();               // 重新加载之前的颜色状态
        ctx.fillRect(45, 45, 60, 60);   // 使用上一次的配置绘制一个矩形
    
        ctx.restore();               // 加载默认颜色配置
        ctx.fillRect(60, 60, 30, 30);   // 使用加载的配置绘制一个矩形
    }
    draw();
    

    九、变形

    9.1 translate

    translate(x, y)

    ​ 用来移动 canvas原点到指定的位置

    translate方法接受两个参数。x 是左右偏移量,y 是上下偏移量,如右图所示。

    在做变形之前先保存状态是一个良好的习惯。大多数情况下,调用 restore 方法比手动恢复原先的状态要简单得多。又如果你是在一个循环中做位移但没有保存和恢复canvas 的状态,很可能到最后会发现怎么有些东西不见了,那是因为它很可能已经超出 canvas 范围以外了。

    ​ 注意:translate移动的是canvas的坐标原点。(坐标变换)

    var ctx;
    function draw(){
        var canvas = document.getElementById('tutorial1');
        if (!canvas.getContext) return;
        var ctx = canvas.getContext("2d");
        ctx.save(); //保存坐原点平移之前的状态
        ctx.translate(100, 100);
        ctx.strokeRect(0, 0, 100, 100)
        ctx.restore(); //恢复到最初状态
        ctx.translate(220, 220);
        ctx.fillRect(0, 0, 100, 100)
    }
    draw();
    

    9.2 rotate

    rotate(angle)

    ​ 旋转坐标轴。

    ​ 这个方法只接受一个参数:旋转的角度(angle),它是顺时针方向的,以弧度为单位的值。

    ​ 旋转的中心是坐标原点。

    var ctx;
    function draw(){
      var canvas = document.getElementById('tutorial1');
      if (!canvas.getContext) return;
      var ctx = canvas.getContext("2d");
    
      ctx.fillStyle = "red";
      ctx.save();
    
      ctx.translate(100, 100);
      ctx.rotate(Math.PI / 180 * 45);
      ctx.fillStyle = "blue";
      ctx.fillRect(0, 0, 100, 100);
      ctx.restore();
    
      ctx.save();
      ctx.translate(0, 0);
      ctx.fillRect(0, 0, 50, 50)
      ctx.restore();
    }
    draw();
    

    9.3 scale

    scale(x, y)

    ​ 我们用它来增减图形在 canvas 中的像素数目,对形状,位图进行缩小或者放大。

    scale方法接受两个参数。x,y分别是横轴和纵轴的缩放因子,它们都必须是正值。值比 1.0 小表示缩 小,比 1.0 大则表示放大,值为 1.0 时什么效果都没有。

    ​ 默认情况下,canvas 的 1 单位就是 1 个像素。举例说,如果我们设置缩放因子是 0.5,1 个单位就变成对应 0.5 个像素,这样绘制出来的形状就会是原先的一半。同理,设置为 2.0 时,1 个单位就对应变成了 2 像素,绘制的结果就是图形放大了 2 倍。

    9.4 transform(变形矩阵)

    transform(a, b, c, d, e, f)

    a (m11)

    ​ Horizontal scaling.

    b (m12)

    ​ Horizontal skewing.

    c (m21)

    ​ Vertical skewing.

    d (m22)

    ​ Vertical scaling.

    e (dx)

    ​ Horizontal moving.

    f (dy)

    ​ Vertical moving.

    var ctx;
    function draw(){
        var canvas = document.getElementById('tutorial1');
        if (!canvas.getContext) return;
        var ctx = canvas.getContext("2d");
        ctx.transform(1, 1, 0, 1, 0, 0);
        ctx.fillRect(0, 0, 100, 100);
    }
    draw();
    

    十、合成

    ​ 在前面的所有例子中、,我们总是将一个图形画在另一个之上,对于其他更多的情况,仅仅这样是远远不够的。比如,对合成的图形来说,绘制顺序会有限制。不过,我们可以利用 globalCompositeOperation 属性来改变这种状况。

    globalCompositeOperation = type

        var ctx;
        function draw(){
            var canvas = document.getElementById('tutorial1');
            if (!canvas.getContext) return;
            var ctx = canvas.getContext("2d");
            
            ctx.fillStyle = "blue";
            ctx.fillRect(0, 0, 200, 200);
    
            ctx.globalCompositeOperation = "source-over"; //全局合成操作
            ctx.fillStyle = "red";
            ctx.fillRect(100, 100, 200, 200);
        }
        draw();
    
    </script>
    

    注:下面的展示中,蓝色是原有的,红色是新的。

    type `是下面 13 种字符串值之一:

    ##1. source-over(default)

    这是默认设置,新图像会覆盖在原有图像。

    ##2. source-in

    仅仅会出现新图像与原来图像重叠的部分,其他区域都变成透明的。(包括其他的老图像区域也会透明)

    ##3. source-out

    仅仅显示新图像与老图像没有重叠的部分,其余部分全部透明。(老图像也不显示)

    ##4. source-atop

    新图像仅仅显示与老图像重叠区域。老图像仍然可以显示。

    ##5. destination-over

    新图像会在老图像的下面。

    ##6. destination-in

    仅仅新老图像重叠部分的老图像被显示,其他区域全部透明。

    ##7. destination-out

    仅仅老图像与新图像没有重叠的部分。 注意显示的是老图像的部分区域。

    ##8. destination-atop

    老图像仅仅仅仅显示重叠部分,新图像会显示在老图像的下面。

    ##9. lighter

    新老图像都显示,但是重叠区域的颜色做加处理

    ##10. darken

    保留重叠部分最黑的像素。(每个颜色位进行比较,得到最小的)

    blue: #0000ff

    red: #ff0000

    所以重叠部分的颜色:#000000

    ##11. lighten

    保证重叠部分最量的像素。(每个颜色位进行比较,得到最大的)

    blue: #0000ff

    red: #ff0000

    所以重叠部分的颜色:#ff00ff

    ##12. xor

    重叠部分会变成透明

    ##13. copy

    只有新图像会被保留,其余的全部被清除(边透明)

    #十一、裁剪路径

    clip()

    ​ 把已经创建的路径转换成裁剪路径。

    ​ 裁剪路径的作用是遮罩。只显示裁剪路径内的区域,裁剪路径外的区域会被隐藏。

    ​ 注意:clip()只能遮罩在这个方法调用之后绘制的图像,如果是clip()方法调用之前绘制的图像,则无法实现遮罩。

    var ctx;
    function draw(){
        var canvas = document.getElementById('tutorial1');
        if (!canvas.getContext) return;
        var ctx = canvas.getContext("2d");
    
        ctx.beginPath();
        ctx.arc(20,20, 100, 0, Math.PI * 2);
        ctx.clip();
        
        ctx.fillStyle = "pink";
        ctx.fillRect(20, 20, 100,100);
    }
    draw();
    

    十二、动画

    动画的基本步骤

    1. 清空canvas

      再绘制每一帧动画之前,需要清空所有。清空所有最简单的做法就是clearRect()方法

    2. 保存canvas状态

      如果在绘制的过程中会更改canvas的状态(颜色、移动了坐标原点等),又在绘制每一帧时都是原始状态的话,则最好保存下canvas的状态

    3. 绘制动画图形

      这一步才是真正的绘制动画帧

    4. 恢复canvas状态

      如果你前面保存了canvas状态,则应该在绘制完成一帧之后恢复canvas状态。

    控制动画

    我们可用通过canvas的方法或者自定义的方法把图像会知道到canvas上。正常情况,我们能看到绘制的结果是在脚本执行结束之后。例如,我们不可能在一个 for 循环内部完成动画。

    也就是,为了执行动画,我们需要一些可以定时执行重绘的方法。

    一般用到下面三个方法:

    1. setInterval()
    2. setTimeout()
    3. requestAnimationFrame()

    ##案例1:太阳系

    let sun;
    let earth;
    let moon;
    let ctx;
    function init(){
        sun = new Image();
        earth = new Image();
        moon = new Image();
        sun.src = "sun.png";
        earth.src = "earth.png";
        moon.src = "moon.png";
    
        let canvas = document.querySelector("#solar");
        ctx = canvas.getContext("2d");
    
        sun.onload = function (){
            draw()
        }
    
    }
    init();
    function draw(){
        ctx.clearRect(0, 0, 300, 300); //清空所有的内容
        /*绘制 太阳*/
        ctx.drawImage(sun, 0, 0, 300, 300);
    
        ctx.save();
        ctx.translate(150, 150);
    
        //绘制earth轨道
        ctx.beginPath();
        ctx.strokeStyle = "rgba(255,255,0,0.5)";
        ctx.arc(0, 0, 100, 0, 2 * Math.PI)
        ctx.stroke()
    
        let time = new Date();
        //绘制地球
        ctx.rotate(2 * Math.PI / 60 * time.getSeconds() + 2 * Math.PI / 60000 * time.getMilliseconds())
        ctx.translate(100, 0);
        ctx.drawImage(earth, -12, -12)
    
        //绘制月球轨道
        ctx.beginPath();
        ctx.strokeStyle = "rgba(255,255,255,.3)";
        ctx.arc(0, 0, 40, 0, 2 * Math.PI);
        ctx.stroke();
    
        //绘制月球
        ctx.rotate(2 * Math.PI / 6 * time.getSeconds() + 2 * Math.PI / 6000 * time.getMilliseconds());
        ctx.translate(40, 0);
        ctx.drawImage(moon, -3.5, -3.5);
        ctx.restore();
    
        requestAnimationFrame(draw);
    }
    

    ##案例2:模拟时钟

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <style>
            body {
                padding: 0;
                margin: 0;
                background-color: rgba(0, 0, 0, 0.1)
            }
            
            canvas {
                display: block;
                margin: 200px auto;
            }
        </style>
    </head>
    <body>
    <canvas id="solar" width="300" height="300"></canvas>
    <script>
        init();
    
        function init(){
            let canvas = document.querySelector("#solar");
            let ctx = canvas.getContext("2d");
            draw(ctx);
        }
    
        function draw(ctx){
            requestAnimationFrame(function step(){
                drawDial(ctx); //绘制表盘
                drawAllHands(ctx); //绘制时分秒针
                requestAnimationFrame(step);
            });
        }
        /*绘制时分秒针*/
        function drawAllHands(ctx){
            let time = new Date();
    
            let s = time.getSeconds();
            let m = time.getMinutes();
            let h = time.getHours();
            
            let pi = Math.PI;
            let secondAngle = pi / 180 * 6 * s;  //计算出来s针的弧度
            let minuteAngle = pi / 180 * 6 * m + secondAngle / 60;  //计算出来分针的弧度
            let hourAngle = pi / 180 * 30 * h + minuteAngle / 12;  //计算出来时针的弧度
    
            drawHand(hourAngle, 60, 6, "red", ctx);  //绘制时针
            drawHand(minuteAngle, 106, 4, "green", ctx);  //绘制分针
            drawHand(secondAngle, 129, 2, "blue", ctx);  //绘制秒针
        }
        /*绘制时针、或分针、或秒针
         * 参数1:要绘制的针的角度
         * 参数2:要绘制的针的长度
         * 参数3:要绘制的针的宽度
         * 参数4:要绘制的针的颜色
         * 参数4:ctx
         * */
        function drawHand(angle, len, width, color, ctx){
            ctx.save();
            ctx.translate(150, 150); //把坐标轴的远点平移到原来的中心
            ctx.rotate(-Math.PI / 2 + angle);  //旋转坐标轴。 x轴就是针的角度
            ctx.beginPath();
            ctx.moveTo(-4, 0);
            ctx.lineTo(len, 0);  // 沿着x轴绘制针
            ctx.lineWidth = width;
            ctx.strokeStyle = color;
            ctx.lineCap = "round";
            ctx.stroke();
            ctx.closePath();
            ctx.restore();
        }
        
        /*绘制表盘*/
        function drawDial(ctx){
            let pi = Math.PI;
            
            ctx.clearRect(0, 0, 300, 300); //清除所有内容
            ctx.save();
    
            ctx.translate(150, 150); //一定坐标原点到原来的中心
            ctx.beginPath();
            ctx.arc(0, 0, 148, 0, 2 * pi); //绘制圆周
            ctx.stroke();
            ctx.closePath();
    
            for (let i = 0; i < 60; i++){//绘制刻度。
                ctx.save();
                ctx.rotate(-pi / 2 + i * pi / 30);  //旋转坐标轴。坐标轴x的正方形从 向上开始算起
                ctx.beginPath();
                ctx.moveTo(110, 0);
                ctx.lineTo(140, 0);
                ctx.lineWidth = i % 5 ? 2 : 4;
                ctx.strokeStyle = i % 5 ? "blue" : "red";
                ctx.stroke();
                ctx.closePath();
                ctx.restore();
            }
            ctx.restore();
        }
    </script>
    </body>
    </html>
    

    展开全文
  • 浅谈HTML5 canvas(一)

    2017-08-19 11:55:14
    : ...主流浏览器都支持canvas,如IE9+、FireFox1.5+、Safari2+、Opera9+、Chrome、iOS版Safari及安卓版Webkit。 Canvas除了具备基本绘图能力的2D上下文,还有一个名为WebGL的3D上下文。目前支持canv

    HTML5添加的最受欢迎的功能就是<canvas>元素,这个元素负责在页面中设定一个区域,然后就可以通过JavaScript动态在这个区域绘制图形。

    主流浏览器都支持canvas,如IE9+、FireFox1.5+、Safari2+、Opera9+、Chrome、iOS版Safari及安卓版Webkit,IE8及之前的版本不支持<canvas>元素。

    Canvas除了具备基本绘图能力的2D上下文,还有一个名为WebGL的3D上下文。目前支持canvas元素的浏览器都支持2D上下文,但对WebGL的支持还不够好。

     

    1、基本用法

    要使用<canvas>元素,就要先设置width和height属性,指定可以绘制的区域大小,<canvas>和</canvas>标签中的内容是当浏览器不支持<canvas>元素时显示的信息。

    注意1:为了避免绘图时canvas元素还未加载,建议将绘制脚本放置在</body>标签之前。

    注意2:canvas元素默认宽 300px,高 150px,设置canvas元素的width和height属性有几种方法:

    1) HTML中:<canvas width="500" height="500">浏览器不支持canvas元素</canvas>(推荐使用)

    2)JavaScript中:canvas.width = 500; canvas.height = 500; (可以使用)

    3) CSS中:canvas{ width:500px; height:500px; }(会拉伸,不建议使用)。

    4) HTML中:<canvas style="width:500px;height:500px">浏览器不支持canvas元素</canvas>(会拉伸,不建议使用)。

    5) JavaScript中:canvas.style.width = "500px"; canvas.style.height = "500px"; (会拉伸,不建议使用)。

    6) jQuery中:$("canvas").width(500);$("canvas").height(500); (会拉伸,不建议使用)。

    要在画布canvas上绘图,需要取得绘图上下文。要取得绘图上下文的引用,需要调用getContext()方法并传入上下文的名字,如传入“2d”,就可以取得2D上下文对象。在使用<canvas>元素之前,需要先检测getContext()方法是否存在。

    使用toDataURL()方法,可以导出在<canvas>元素上绘制的图像,该方法接受一个参数,即图像的MIME类型格式,而且适合用于创建图像的任何上下文。

    取得画布中的一幅PNG格式的图像(默认情况下,浏览器会将图像编码为PNG格式,除非另行指定,Firefox和Opera也支持基于image/jpeg的JPEG编码格式,由于该方法是后来才增加的,所以支持canvas的浏览器也是在较新的版本中才加入了对它的支持,如IE9+、Firefox3.5和Opera10):

    var canvas = document.getElementsByTagName("canvas")[0];
    if (canvas.getContext) {
    	var imgURI = canvas.toDataURL("image/png");
    	var image = document.createElement("img");
    	image.src = imgURI;
    	document.body.appendChild(image);
    }


    2、2D上下文

    使用2D绘图上下文提供的方法,可以绘制简单的2D图形,如矩形、弧线和路径。

    2D上下文的坐标开始于<canvas>元素的左上角,原点坐标是(0, 0),所有坐标值都基于原点进行计算,默认情况下,width和height表示水平和垂直两个方向上可用的像素数目。

    1) 填充和描边

    填充:用指定的样式(颜色、渐变或图像)填充图形。

    描边:只在图形的边缘画线。

    大多数2D上下文都会细分为填充和描边两个操作,而操作的结果取决于两个属性:fillStyle和strokeStyle,这两个属性的值可以是字符串、渐变对象或模式对象,默认值都是“#000000”。如果为它们指定表示颜色的字符串,可以使用CSS中指定颜色的任何形式,包括颜色名、十六进制码、rgb、rgba、hsl或hsla。

     

    2) 绘制矩形

    矩形是唯一一种可以直接在2D上下文中绘制的形状。与矩形有关的方法包括:fillRect()、strokeRect()和clearRect(),这三个方法都能接收4个参数:矩形的x坐标、矩形的y坐标、矩形宽度和矩形高度,单位都是像素。

    fillRect()方法在画布上绘制的矩形会填充指定的颜色,填充的颜色通过fillStyle属性指定。

    strokeRect()方法在画布上绘制的矩形会使用指定的颜色描边,描边的颜色通过strokeStyle属性指定。

    clearRect()方法用于清除画布上的矩形区域,本质上,该方法可以吧绘制上下文中的某个矩形区域变透明。通过绘制形状然后再清除指定区域,可以生成切掉一块的效果。

    var canvas = document.getElementsByTagName("canvas")[0];
    if (canvas.getContext) {
    	var context = canvas.getContext("2d");
    	context.fillStyle = "red";
    	context.fillRect(10, 10, 50, 50);
    	context.strokeStyle= "blue";
    	context.strokeRect(30, 30, 50, 50);
    	context.clearRect(40, 40, 10, 10); // 在两个矩形重叠的地方清除一个小矩形
    }


    3) 绘制路径

    通过路径可以创造出复杂的形状和线条。

    绘制新路径的步骤如下:

    ① 调用beginPath()方法,表示要开始绘制新路径。

    ② 调用下列方法来绘制路径:

    a. arc(x, y, radius, startAngle, endAngle, counterClockwise):以(x, y)为圆心,绘制一条弧线,半径为radius,起始和结束角度分别为startAngle和endAngle,counterClockwise为true表示逆时针计算,为false表示顺时针计算;

    b. arcTo(x1, y1, x2, y2, radius):利用上一点、点(x1, y1)和点(x2, y2)这三个点所形成的夹角,绘制一段与夹角的两边相切并且半径为radius的圆上的弧线。夹角的一边是上一点与(x1, y1)的连线,另一边是(x1, y1)(x2, y2)的连线,弧线的起点就是上一点所在边与圆的切点,弧线的终点就是点(x2,y2)所在边与圆的切点,并且绘制的弧线是两个切点之间长度最短的那个圆弧。此外,如果上一点不是弧线起点,arcTo()方法还将添加一条当前端点到弧线起点的线段

    c. bezierCurveTo(c1x, c1y, c2x, c2y, x, y):从上一点开始绘制一条曲线,到(x, y)为止,并且以(c1x, c1y)和(c2x, c2y)为控制点。

    d. lineTo(x, y):从上一点开始绘制一条直线,到(x, y)为止。

    e. moveTo(x, y):将绘图游标移动到(x, y),不画线。

    f. quadraticCurveTo(cx, cy, x, y):从上一点开始绘制一条二次曲线,到(x, y)为止,并且以(cx, cy)作为控制点。

    g. rect(x, y, width, height):从点(x, y)开始绘制一个矩形,宽度和高度分别为width和height,该方法绘制的是矩形路径,而不是fillRect()和strokeRect()所绘制的独立的形状。

    ③ 创建了路径后,有以下几种选择:

    a. 若想绘制一条连接路径起点的线条,可以调用closePath();

    b. 若路径已经完成,可以调用fill()方法填充路径,使用的是fillStyle;

    说明:fill()方法用于填充路径,fillRect()方法用于填充矩形,rect()与fill()方法合用相当于fillRect()。也就是说,绘制填充矩形有两种方法,但绘制填充圆形只能通过arc()与fill()方法合用。

    c. 若路径已经完成,还可以调用stroke()方法对路径描边,使用的是strokeStyle;

    说明:stroke()方法用于路径描边,strokeRect()方法用于填充矩形,rect()与stroke()方法合用相当于strokeRect()。也就是说,绘制描边矩形有两种方法,但绘制描边圆形只能通过arc()与stroke()方法合用。

    注意:moveTo()和lineTo只是定义了路径,还需要stroke()方法才会实际绘制出路径。在beginPath()和Stroke()或closePath()之间若有多次设置lineWidth或strokeStyle,则后面设置的值会覆盖前面设置的值,若想要对两条路径设置不同的lineWidth或strokeStyle,需要为第一条路径设置lineWidth或strokeStyle通过Stroke()或closePath()结束第一条路径,再通过beginPath开始第二条路径后设置第二条路径的lineWidth或strokeStyle。

    var canvas = document.getElementsByTagName("canvas")[0];  
    if (canvas.getContext) {  
    	var context = canvas.getContext("2d");  
    	// 开始路径
    	context.beginPath();
    	// 绘制外圆
    	context.arc(100, 100, 99, 0, 2 * Math.PI, false);
    	// 绘制内圆
    	context.moveTo(194, 100);
    	context.arc(100, 100, 94, 0, 2 * Math.PI, false);
    	// 绘制分针
    	context.moveTo(100, 100);
    	context.lineTo(100, 15);
    	// 绘制时针
    	context.moveTo(100, 100);
    	context.lineTo(35,100);
    	// 描边路径
    	context.stroke();
    } 

    注意:在绘制内圆之前,必须把路径移到内圆上的某一点,以避免绘制出多余的线条。

    d. 最后还可以调用clip(),在路径上创建一个剪切区域。

    <!DOCTYPE html>
    <html>
    <head>
        <title></title>
        <style>
        </style>
    </head>
    <body>
    	<br>没有clip():<br>
    	<canvas id="canvas1" width="400" height="200" style="border:1px solid grey">浏览器不支持canvas元素</canvas>
    	<br>有clip():<br>
    	<canvas id="canvas2" width="400" height="200" style="border:1px solid grey">浏览器不支持canvas元素</canvas>
    	<script src="js/jquery-1.8.2.min.js"></script>
        <script>
    		var canvas1 = document.getElementById("canvas1");
    		var context1 = canvas1.getContext("2d");
    		context1.rect(50, 50, 200, 100);
    		context1.stroke();
    		context1.fillStyle = "red";
    		context1.fillRect(0, 0, 150, 100);
    		var canvas2 = document.getElementById("canvas2");
    		var context2 = canvas2.getContext("2d");
    		context2.rect(50, 50, 200, 100);
    		context2.stroke();
    		context2.clip();
    		context2.fillStyle="red";
    		context2.fillRect(0, 0, 150, 100);
        </script>
    </body>
    </html> 

    在2D绘制上下文中,路径是一种主要的绘图方式,因为路径能为要绘制的图形提供更多控制。isPointInPath()方法接收x和y坐标作为参数,用于在路径被关闭之前确定画布上的某一点是否位于路径上。

    if (context.isPointInPath(100, 100))
    	alert("Point (100, 100) is in the path");


    4) 绘制文本

    绘制文本主要有两个方法:fillText()和strokeText(),这两个方法可以接收4个参数,要绘制的文本字符串,x坐标,y坐标和可选的最大像素宽度(该可选参数尚未得到所有浏览器支持,提供该参数后,调用fillText()或strokeText()时若传入的字符串大于最大宽度,则绘制的文本字符的高度正确,,但宽度会收缩以适应最大宽度),fillText()方法使用fillStyle属性绘制文本,strokeText()方法使用strokeStyle属性绘制文本,且这两个方法都以下列3个属性为基础:

    ① font:表示文本样式、大小和字体,用CSS指定字体的格式来指定;

    ② textAlign:表示文本对齐方式,可能的值有start,end,left,right,center,建议使用start,end,不要使用left和right,前两者适用于从左到右和从右到左显示的语言。start表示x坐标的位置是文本左端的位置(从左到右阅读的语言),end表示x坐标的位置是文本右端的位置(从右到左阅读的语言);

    ③ textBaseline:表示文本的基线,可能的值有top,hanging,middle,alphabetic,ideographic和bottom,top表示y坐标的位置是文本顶端的位置,bottom表示y坐标的位置是文本底端的位置,hanging,alphabetic,ideographi表示y坐标分别指向字体的特定基线坐标。

    这几个属性都有默认值,因此没有必要每次使用它们都重新设置一次值。

    var canvas = document.getElementsByTagName("canvas")[0];  
    if (canvas.getContext) {  
    	var context = canvas.getContext("2d");  
    	// 开始路径
    	context.beginPath();
    	// 绘制外圆
    	context.arc(100, 100, 99, 0, 2 * Math.PI, false);
    	// 绘制内圆
    	context.moveTo(194, 100);
    	context.arc(100, 100, 94, 0, 2 * Math.PI, false);
    	// 绘制分针
    	context.moveTo(100, 100);
    	context.lineTo(100, 15);
    	// 绘制时针
    	context.moveTo(100, 100);
    	context.lineTo(35,100);
    	// 描边路径
    	context.stroke();
    	context.font = "15px solid Arial";
    	context.textAlign = "center";
    	context.textBaseine= "middle";
    	context.fillText("12", 100, 20);
    	context.textAlign = "start";
    	context.fillText("12", 100, 40);
    	context.textAlign = "end";
    	context.fillText("12", 100, 60);
    }

    在需要把文本控制在某一区域中时,2D上下文提供了辅助确定文本大小的方法measureText(),该方法接收一个参数即要绘制的文本,利用font、textAlign、textBaseline的当前值计算指定文本的大小。返回一个TextMetrics对象,该对象目前只包含指示以像素计的指定字体宽度的width属性,但将来还会增加更多属性。

    var canvas = document.getElementsByTagName("canvas")[0];  
    if (canvas.getContext) {  
    	var context = canvas.getContext("2d");  
    	var fontSize = 100;
    	context.font = fontSize + "px Arial";
    	while (context.measureText("Hello world").width > 140) {
    		fontSize--;
    		context.font = fontSize + "px Arial";
    	}
    	context.fillText("Hello world", 10, 10);
    }
    关于2D上下文的更多应用详见:http://blog.csdn.net/zhouziyu2011/article/details/66474969
    展开全文
  • HTML5Canvas绘图(上)

    2018-11-26 15:35:11
    1.Canvas绘制步骤 在html5页面中添加canvas元素,定义id属性值以便后面调用  &lt;canvas id="myCanvas" width="500" height="200"&gt;&lt;/canvas&gt; 使用id寻找...

    1.Canvas绘制步骤

    • 在html5页面中添加canvas元素,定义id属性值以便后面调用

               <canvas id="myCanvas" width="500" height="200"></canvas>

    • 使用id寻找页面中的canvas元素

              var c=document.getElementById("myCanvas");

    • 通过canvas元素的getContext方法来获取其上下文(Context),即创建context对象,以获取允许绘制的2D环境

              var context=c.getContext("2d");

    • 使用javascript脚本来进行绘制

             context.fillStyle="#ff0000";

             context.fillRect(50,25,100,50);

    <head>
    	<title></title>
    	<!--给画布设置一个样式-->
    	<style type="text/css">
    		#myCanvas{
    			border: 1px solid blue;
    		}
    	</style>
    	<script type="text/javascript">
    		window.onload=function(){
    			var canvas=document.getElementById("myCanvas");
    			var context=canvas.getContext("2d");
    			context.fillStyle="#ff0000";
    			context.fillRect(50,25,100,50);
    			//距离画布左边50,上边25,绘制的图形宽100,高50
    		}
    	</script>
    </head>
    <body>
        <canvas id="myCanvas" width="500" height="200"></canvas> 
    </body>

    运行结果:

     2.绘制直线相关方法及属性

    方法:

    • beginPath():定义绘制动作的开始
    • moveTo():绘制图形的起点位置
    • lineTo():绘制图形的重点位置
    • stroke():为所画的线赋予颜色,如没有指定,默认为黑色

    属性:

    • lineWidth:直线的宽度
    • strokeStvle:直线的颜色
    • 直线端点样式:用lineCap属性设定,包括三种样式,分别为butt,round,square
    <html>
    <title></title>
    	<style type="text/css">
    		#myCanvas{
    			border: 1px solid blue;
    			background-color: #77ffcc;
    		}
    	</style>
    	<script type="text/javascript">
    		window.onload=function(){
    			var canvas=document.getElementById("myCanvas");
    			var context=canvas.getContext("2d");
    			//绘制直线
    			context.beginPath();
    			context.moveTo(50,100);
    			context.lineTo(200,100);
    			context.lineWidth=10;
    			context.strokeStyle="#ff0000";
    			context.lineCap="round";
    			context.stroke();	
    		}
    	</script>
    </head>
    <body>
        <canvas id="myCanvas" width="500" height="200"></canvas> 
    </body>
    </html>

    3.绘制弧线和曲线  

              arcTo(x1,y1,x2,y2,radius) ;包含五个参数,(x1,y1)是端点1,(x2,y2)是端点2,radius是绘制的弧线的半径,此方法就是利用第一条线的终点、端点1、端点2组成的夹角,与夹角两边相切并以radius为半径画弧线,详情实例见下面代码。

    <html>
    <title></title>
    	<style type="text/css">
    		#myCanvas{
    			border: 1px solid blue;
    			background-color: #77ffcc;
    		}
    	</style>
    	<script type="text/javascript">
    		window.onload=function(){
    			var canvas=document.getElementById("myCanvas");
    			var context=canvas.getContext("2d");
    			//绘制弧线
    			context.beginPath();
    			context.moveTo(20,20);//第一条直线的起点
    			context.lineTo(100,20);//第一条直线的终点
    			//端点1:(150,20)端点2:(150,70)b半径:50;
    			context.arcTo(150,20,150,70,50);
    			context.lineTo(150,120);//第二条线的终点
    			context.stroke();	
    		}
    	</script>
    </head>
    <body>
        <canvas id="myCanvas" width="500" height="200"></canvas> 
    </body>

    •  arcTo():创建介于两个切线之间的弧/曲线
    • quadraticCurveTo():绘制二次曲线,每条二次曲线由上下文点、一个控制点和一个终止点来定义
    <html>
    	<style type="text/css">
    		#myCanvas{
    			border: 1px solid blue;
    			background-color: #77ffcc;
    		}
    	</style>
    	<script type="text/javascript">
    		window.onload=function(){
    			var canvas=document.getElementById("myCanvas");
    			var context=canvas.getContext("2d");
    			//绘制二次贝塞尔曲线
    			context.beginPath();
    			context.moveTo(200,100);//起始点
    			context.quadraticCurveTo(288,0,388,150);
    			context.lineWidth=5;
    			context.strokeStyle="pink";
    			context.stroke();	
    		}
    	</script>
    </head>
    <body>
        <canvas id="myCanvas" width="500" height="200"></canvas> 
    </body>
    </html>

     

    • bezierCurveTo():绘制贝塞尔曲线,每条贝塞尔曲线由上下文点、两个控制点和一个终止点来确定

     

    展开全文
  • 原作很强悍 ...前言基本知识绘制矩形清除矩形区域圆弧路径绘制线段绘制贝塞尔曲线线性渐变径向渐变(发散)图形变形(平移、旋转、缩放)矩阵变换(图形变形的机制)图形组合给图形绘制阴影绘制图像(图片平铺...
  • 一个很重要的原因是,Canvas 的标准还没有完全确定,不适合大规模用在生产环境。但是,Canvas 的优点也是很明显的,例如在绘制含有大量元素的图表的时候,SVG 往往因为性能问题而无法胜任,例如我见过的一次技术分享...
  • canvas详解(1)-原理

    2018-08-13 10:24:51
    canvas详解(1)-原理 原理 canvas本身并不具备绘画能力,它本身只是一个画布,是一个容器。绘图能力是基于html5的getContext("2d")返回的CanvasRenderingContext2D对象来完成的。 const canvas = ...
  • Canvas

    2016-01-07 09:37:27
    API—Canvas | Android 开发者 Canvas介绍 Canvas(画布):可以理解成画布。嵌套类1.Canvas.EdgeTypeAPI—Canvas.EdgeType | Android 开发者2.Canvas.VertexModeAPI—Canvas.VertexMode | Android 开发者常量 标记 ...
  • canvas

    2018-07-07 14:40:14
    1 设置宽高的时候要在canvas标签里 width=1000 height=1000 或者 canvas.width = 1000 canvas.height = 10002填充色 3 边框色4绘制多个线条需要加入首尾 beiginPath() closePath5 canvas 是基于状态的6 画圆 ...
  • 先说下canvas绘图的基本方法,如下: const myCanvas = document.createElement('canvas'); myCanvas.width = 400; myCanvas.height = 400; const ctx = myCanvas.getContext('2d'); const ...
  • html5中的canvas标签

    2019-10-29 14:17:54
    canvas基本用法 什么是canvas(画布) 是 HTML5 新增的元素,可用于通过使用JavaScript中的脚本来绘制图形 例如,它可以用于绘制图形,创建动画。 最早由Apple引入WebKit 我们可以使用标签来定义一个canvas元素 ---...
  • canvas导出为图像

    2019-07-15 23:56:18
    <!DOCTYPE html> <html> <head> <meta http-equiv="X-UA-Compatible" content="chrome=IE8"> <meta http-equiv="Content-type" content="text/html;charset=UTF-8">......
  • js实现截图并保存图片在本地(html转canvascanvas转image) 一、html转canvas 需要的库html2canvas.js和canvas2image.js 话不多说,直接上代码! html &amp;amp;amp;amp;lt;h2&amp;amp;amp;amp...
  • 前面讲了paint,后面会花几篇主要讲讲canvas,并且由于最近项目比较紧,所以近期的文章都会“短小精悍”; paint 作为画笔,里面有非常多而强大的设置方法,比如设置颜色过滤器,设置位图渲染、渐变,设置图像的混合...
  • 前言:前几篇讲解了有关canvas绘图的一些操作,今天更深入一些,讲讲对画布的操作,这篇文章不像前几篇那么容易理解,如果以前没有接触过画布的童鞋可能比较难以理解,为什么会这样。我尽量多画图,让大家更清晰明白...
  • 所以,如果你想学习Canvas画图,你必须要有Javascript基础。另外,画图嘛,总有一些图像方面的术语和知识点,所以如果你有过做图或美工经验,学习Canvas会更容易。Canvas,意为画布也。而Html5中的Canvas也真的跟...
  • 前面说Canvas大致可以分为三类: 1. save、restore 等与层的保存和回滚相关的方法; 2. scale、rotate、clipXXX 等对画布进行操作的方法; 3. drawXXX 等一系列绘画相关的方法; 前面主要讲了drawBitmap方法,并举了...
  • 上一章内容中我们对canvas元素有了一个初步的认识,在接下来的章节中我们会慢慢学习canvas中图形的绘制;但是在绘制之前我们先来看看canvas中的坐标系统,因为这样我们才能知道绘制的图形放在什么位置。 比如:我们...
  • 实现html内容转成图片格式搞这个东西之前尝试过好多种方法,包括canvas画图,php gd2画图,画的我怀疑人生,我就想实现一个大概名片的效果,不用太炫酷,最后还是选择用html2canvas,但是遇到的问题还是图片的跨域...
  • 这里canvas.save();和canvas.restore();是两个相互匹配出现的,作用是用来保存画布的状态和取出保存的状态的。这里稍微解释一下,  当我们对画布进行旋转,缩放,平移等操作的时候其实我们是想对特定的元素进行...
1 2 3 4 5 ... 20
收藏数 236,641
精华内容 94,656
关键字:

canvas