zoukankan      html  css  js  c++  java
  • canvas基础学习笔记

    canvas基本用法

    1.什么是canvas(画布)

       <canvas> 是 HTML5 新增的元素,可用于通过使用JavaScript中的脚本来绘制图形,例如,它可以用于绘制图形,创建动画。可以使用 <canvas>标签来定义一个canvas元素,使用 <canvas>标签时,建议要成对出现,不要使用闭合的形式。

       <canvas>元素具有默认高宽  300px; height: 150px 

    2.替换内容

      对于某些不支持HTML元素 <canvas>的较老的浏览器(尤其是IE9之前的IE浏览器)只需要在标签中提供替换内容就可以。支持 <canvas>的浏览器将会忽略在容器中包含的内容,并且只是正常渲染canvas。不支持 <canvas>的浏览器会显示代替内容

    3.canvas标签的两个属性

       <canvas>标签只有两个属性—— width和height。这些都是可选的。 <canvas>元素默认具有高宽 (width: 300px; height:150px)。html属性设置width height时只影响画布本身不影画布内容。css属性设置width height时不但会影响画布本身的高宽,还会使画布中的内容等比例缩放(缩放参照于画布默认的尺寸)。

    4.渲染上下文

      <canvas> 元素只是创造了一个固定大小的画布,要想在它上面去绘制内容,我们需要找到它的渲染上下文。 getContext() 方法是用来获得渲染上下文和它的绘画功能。它只有一个参数,即上下文的格式。

    5.canvas模板

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>canvas模板</title>
        <style>
            canvas { border: 1px solid; }
        </style>
    </head>
    <body>
        <canvas id="test" width="300" height="300">
            <span>您的浏览器不支持画布元素,请升级或更换浏览器,推荐使用谷歌浏览器</span>
        </canvas>
    
        <script>
    
            function draw() {
                var canvasNode = document.querySelector('#test'); // 获取画布
    
                if (!canvasNode.getContext)  return; // 检测支持性,防止在低版本浏览器报错
    
                var ctx = canvasNode.getContext("2d"); // 获取画笔
    
                // 绘制.....
           ctx.save();
            // 样式
           ctx.beginPath();
            // 路径
           ctx.restore();
    } draw(); </script> </body> </html>

    canvas绘制矩形

      HTML中的元素canvas只支持一种原生的图形绘制:矩形。所有其他的图形的绘制都至少需要生成一条路径

    1.绘制矩形

    • 绘制矩形的三种方法
      •  fillRect(x, y, width, height)  --- 绘制一个填充的矩形(填充色默认为黑色)
      •  strokeRect(x, y, width, height)  --- 绘制一个矩形的边框(默认边框为:一像素实心黑色)
      • clearRect(x, y, width, height) --- 清除指定矩形区域,让清除部分完全透明。

      x与y指定了在canvas画布上所绘制的矩形的左上角(相对于原点)的坐标。

      width和height设置矩形的尺寸。(存在边框的话,边框会在width上占据一个边框的宽度,height同理)

    2.strokeRect时,边框像素渲染问题

       context.strokeRect(10,10,50,50) 

      按理渲染出的边框应该是1px的,但canvas在渲染矩形边框时,边框宽度是平均分在偏移位置的两侧。浏览器是不会让一个像素只用自己的一半的,故渲染出的边框实际上为2px且颜色较淡。在横纵轴多偏移0.5px可解决此问题。

       context.strokeRect(10.5,10.5,50,50) 

    3.添加样式和颜色

       fillStyle :设置图形的填充颜色。默认颜色黑色。

       strokeStyle :设置图形轮廓的颜色。默认颜色黑色。

       lineWidth  :设置当前绘线的粗细。属性值必须为正数。0、 负数、 Infinity 和 NaN 会被忽略。默认值是1.0。

       lineJoin  :设定线条与线条间接合处的样式(round : 圆角;bevel : 斜角;miter : 直角),默认值为miter。

    canvas绘制路径

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

    1.beginPath()

      新建一条路径,生成之后,图形绘制命令被指向到路径上准备生成路径。生成路径的第一步叫做beginPath()。本质上,路径是由很多子路径构成,这些子路径都是在一个列表中,所有的子路径(线、弧形、等等)构成图形。而每次这个方法调用之后,列表清空重置,然后就可以重新绘制新的图形。

    2.moveTo(x, y)

      将笔触移动到指定的坐标x以及y上。当canvas初始化或者beginPath()调用后,通常会使用moveTo()函数设置起点。

    3.lineTo(x, y)

      将笔触移动到指定的坐标x以及y上,绘制一条从当前位置到指定x以及y位置的直线。

    4.closePath()

      闭合路径之后图形绘制命令又重新指向到上下文中。合路径closePath(),不是必需的。这个方法会通过绘制一条从当前点到开始点的直线来闭合图形。如果图形是已经闭合了的,即当前点为开始点,该函数什么也不做。当调用fill()函数时,所有没有闭合的形状都会自动闭合,所以你不需要调用closePath()函数,但是调用stroke()时不会自动闭合。

    5.stroke()

      通过线条来绘制图形轮廓。不会自动调用closePath()。

    6.fill()

      通过填充路径的内容区域生成实心的图形。自动调用closePath()

    7.rect(x, y, width, height)

      绘制一个左上角坐标为(x,y),宽高为width以及height的矩形路径。

    8.lineCap

      指定如何绘制每一条线段末端的属性。有3个可能的值,分别是:

    butt(默认值) 线段末端以方形结束
    round 线段末端以圆形结束
    square 线段末端以方形结束,但是增加了一个宽度和线段相同,高度是线段厚度一半的矩形区域

    9.save()

      save() 是 Canvas 2D API 通过将当前状态放入栈中,保存 canvas 全部状态的方法。

    10.restore()

      restore() 是 Canvas 2D API 通过在绘图状态栈中弹出顶端的状态,将 canvas 恢复到最近的保存状态的方法。如果没有保存状态,此方法不做任何改变。

    canvas绘制曲线

    1.绘制圆形

    • arc(x, y, radius, startAngle, endAngle, anticlockwise)
      • 画一个以(x,y)为圆心的以radius为半径的圆弧(圆),从startAngle开始到endAngle结束,按照anticlockwise给定的方向(默认为顺时针)来生成。
      • x:圆心横坐标
      • y:圆心纵坐标
      • radius:半径
      • startAngle:开始弧度
      • endAngle:结束弧度
      • anticlockwise:定义圆形路径的绘制方向,true为逆时针,false为顺时针,默认为fals
    • arcTo(x1, y1, x2, y2, radius) + moveTo(x0,y0)
      • 根据给定的控制点和半径画一段圆弧,根据三点确定一个夹角绘制出一段圆弧,需要与moveTo配合使用
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>画个圆弧</title>
        <style>
            * {margin: 0;padding: 0;}
            body { width: 100%; height: 100%; background-color: gray;}
            canvas {position: absolute; left: 0; right: 0; top: 0; bottom: 0; margin: auto; background-color: #fff; }
        </style>
    </head>
    <body>
        <canvas id="canvas" width="400" height="400"></canvas>
        <script>
            window.onload = function () {
                var canvas = document.querySelector("#canvas");
    
                if (canvas.getContext) {
                    var ctx = canvas.getContext("2d");
    ctx.moveTo(
    50, 50); // x0 y0 ctx.lineTo(400, 0); // x1 y1 ctx.lineTo(200, 200); // x2 y2 ctx.moveTo(50, 50); ctx.arcTo(400, 0, 200, 200, 50); ctx.stroke(); } } </script> </body> </html>

    显示效果

    2.二次贝塞尔  

      quadraticCurveTo(x1,y1, x2, y2)

      绘制二次贝塞尔曲线,x1,y1为一个控制点,x2,y2为结束点。

      起始点为moveto时指定的点。

    3.三次贝塞尔

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

      绘制三次贝塞尔曲线,cp1x,cp1y为控制点一,cp2x,cp2y为控制点二,x,y为结束点。

      起始点为moveto时指定的点。

    canvas变换

    1.平移(translate)

    • translate(x, y)
      • 移动 canvas的原点到一个不同的位置。
      • translate 方法接受两个参数。x 是左右偏移量,y 是上下偏移量
      • 在canvas中translate是累加的

    2.旋转(rotate)

    • rotate(angle)
      • 这个方法只接受一个参数:旋转的角度(angle),它是顺时针方向的,以弧度为单位的值。
      • 旋转的中心点始终是 canvas 的原点,如果要改变它,需要用到 translate 方法
      • 在canvas中rotate是累加的

    3.缩放(scale)

    • scale(x, y)
      • scale 方法接受两个参数。x,y 分别是横轴和纵轴的缩放因子,它们都必须是正值。
      • 值比 1.0 小表示缩小,比 1.0 大则表示放大,值为 1.0 时什么效果都没有。
      • 缩放一般我们用它来增减图形在 canvas 中的像素数目,对形状,位图进行缩小或者放大
      • 在canvas中scale是累乘的

    canvas(图片使用、设置背景、渐变)

    1.在canvas中插入图片(需要使用image对象)

    • canvas操作图片时,必须要等图片加载完才能操作
    • drawImage(image, x, y, width, height)
      • image:image 或者 canvas 对象
      • x:canvas 里的起始横坐标
      • y:canvas 里的起始纵坐标
      • width/height:用来控制当canvas画入时应该缩放的大小

    2.在canvas中设置背景(需要image对象)

    • createPattern(image, repetition)
      • image:图像源
      • epetition:repeat / repeat-x / repeat-y / no-repeat
      • 返回值:CanvasPattern对象;可将createPattern返回的对象作为fillstyle的值

    3.渐变

    canvas渐变(线性渐变)

    • createLinearGradient(x1, y1, x2, y2)
      • (x1,y1):表示渐变的起点
      • (x2,y2):表示渐变的终点
    • gradient.addColorStop(position, color)
      • gradient:createLinearGradient的返回值
      • position:position参数必须是一个 0.0 与 1.0 之间的数值,表示渐变中颜色所在的相对位置。例如,0.5 表示颜色会出现在正中间。
      • color:color 参数必须是一个有效的 CSS 颜色值(如 #FFF, rgba(0,0,0,1),等等)

    canvas渐变(径向渐变)

    • createRadialGradient(x1, y1, r1, x2, y2, r2)
      • 前三个参数定义一个以(x1,y1) 为原点,半径为 r1 的圆
      • 后三个参数定义另一个以 (x2,y2) 为原点,半径为 r2 的圆。

     canvas文本绘制

    1.渲染文本

    • fillText(text, x, y)
      • 在指定的(x,y)位置填充指定的文本
    • strokeText(text, x, y)
      • 在指定的(x,y)位置绘制文本边框

    2.文本样式

    font

      用来设置绘制文本的样式. 这个字符串使用和 CSS font 属性相同的语法。默认的字体是 10px sans-serif,有且只有 sans-serif 字体,且 sans-serif 字体不可省略。即font属性在指定时,必须要有大小和字体 缺一不可。

    textAlign

    • 文本对齐选项. 可选的值包括: left, right  center.
      • left:文本左对齐。
      • right:文本右对齐
      • center:文本居中对齐,这里的textAlign="center"比较特殊。textAlign的值为center时候,文本的居中是基于你在fillText的时候所给的x的值。也就是说文本一半在x的左边,一半在x的右边。

    textBaseline

    • 描述绘制文本时,当前文本基线的属性。
      • top:文本基线在文本块的顶部。    
      • middle:文本基线在文本块的中间。
      • bottom:文本基线在文本块的底部。

    measureText

      measureText() 方法返回一个 TextMetrics 对象,包含关于文本尺寸的信息(例如文本的宽度)

    canvas文本垂直水平居中

    var canvas = document.querySelector("#canvas");
    var ctx = canvas.getContext("2d");
    ctx.font = "60px sans-serif";
    var obj = ctx.measureText("略略略");
    ctx.textBaseline = "middle";
    ctx.fillText("略略略", (canvas.width - obj.width) / 2, (canvas.height - 60) / 2);

    阴影(文本阴影&盒模型阴影)

    shadowOffsetX / shadowOffsetY

      shadowOffsetX 和 shadowOffsetY 用来设定阴影在 X 和 Y 轴的延伸距离,它们默认都为 0。

    shadowBlur

      shadowBlur 用于设定阴影的模糊程度,其数值并不跟像素数量挂钩,也不受变换矩阵的影响,默认为 0。

    shadowColor(必需项)

      shadowColor 是标准的 CSS 颜色值,用于设定阴影颜色效果,默认是全透明的黑色。

    像素操作

      通过像素操作,我们可以直接通过ImageData对象操纵像素数据,直接读取或将数据数组写入该对象中,具体API如下

    得到场景像素数据

    • getImageData():获得一个包含画布场景像素数据的ImageData对像,它代表了画布区域的对象数据
    • ctx.getImageData(sx, sy, sw, sh)
      • sx:将要被提取的图像数据矩形区域的左上角 x 坐标。  
      • sy:将要被提取的图像数据矩形区域的左上角 y 坐标。  
      • sw:将要被提取的图像数据矩形区域的宽度。  
      • sh:将要被提取的图像数据矩形区域的高度。  

    ImageData对象

      ImageData对象中存储着canvas对象真实的像素数据,它包含以下几个只读属性:

        图片宽度,单位是像素

        height:图片高度,单位是像素

        data:Uint8ClampedArray类型的一维数组,包含着RGBA格式的整型数据,范围在0至255之间(包括255)

          R:0 --> 255(黑色到白色)

          G:0 --> 255(黑色到白色)

          B:0 --> 255(黑色到白色)

          A:0 --> 255(透明到不透明)

    在场景中写入像素数据

      使用putImageData()方法去对场景进行像素数据的写入。

      putImageData(myImageData, dx, dy)

        dx和dy参数表示你希望在场景内左上角绘制的像素数据所得到的设备坐标

    创建一个ImageData对象

      ctx.createImageData(width, height);

        width : ImageData 新对象的宽度。

        height: ImageData 新对象的高度。

      注:默认创建出来的imagData对象是黑色透明的

    canvas合成

    全局透明度的设置globalAlpha

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

    覆盖合成

    • globalCompositeOperation
      • source:新的图像(源) 
        • source-over(默认值):源在上面,新的图像层级比较高
        • source-in  :只留下源与目标的重叠部分(源的那一部分)
        • source-out :只留下源超过目标的部分
        • source-atop:砍掉源溢出的部分
      • destination:已经绘制过的图形(目标)  
        • destination-over:目标在上面,旧的图像层级比较高
        • destination-in:只留下源与目标的重叠部分(目标的那一部分)
        • destination-out:只留下目标超过源的部分
        • destination-atop:砍掉目标溢出的部分

    其他

    toDataURL

    • 将画布导出为图像
    • 注意此方法是canvas元素接口上的方法

    isPointInPath(x, y)

    • 判断在当前路径中是否包含检测点
    • x:检测点的X坐标
    • y:检测点的Y坐标
    • 注意,此方法只作用于最新画出的canvas图像
  • 相关阅读:
    jbox使用总结
    NOI 2012 【迷失游乐园】
    SCOI 2008 【奖励关】
    trie树——【吴传之火烧连营】
    状压DP——【蜀传之单刀赴会】
    NOIP提高组2016 D2T3 【愤怒的小鸟】
    NOIP提高组2013 D2T3 【华容道】
    [学习笔记] [KMP]字符串匹配算法
    SHOI 2014 【概率充电器】
    HNOI 2015 【亚瑟王】
  • 原文地址:https://www.cnblogs.com/zhanghua-zh/p/10291624.html
Copyright © 2011-2022 走看看