zoukankan      html  css  js  c++  java
  • Canvas教程

    一.Canvas基本用法

    canvas对应中文是“画布”,<canvas>是HTML5的新元素,IE9+支持

    canvas元素的默认大小是300px * 150px,最简单的代码将生成一个透明的矩形画布,例如:

    <canvas>
      浏览器不支持canvas
    </canvas>

    如果浏览器支持的话,那么你将不会看到一个300px * 150px的透明块(因为透明了嘛,审查元素就找到它了)。如果浏览器不支持,那么将会显示替换文字:“浏览器不支持canvas”,例如IE8。

    有了画布,我好想画点儿什么。不过对于canvas来说,最容易的是画个空心/实心矩形,而不是画条直线,例如:

    <canvas id="my_canvas"> 浏览器不支持canvas </canvas>
    <script type="text/javascript">
      var canvas = document.getElementById('my_canvas');
      if(canvas.getContext){
      var ctx = canvas.getContext('2d');//获取2d上下文
      ctx.strokeStyle = '#f00';//边框设置为红色
      ctx.lineWidth = 3;//线宽设置为3px
      ctx.fillStyle = 'rgba(0, 0, 255, 0.5)';//填充半透明蓝色
      ctx.strokeRect(0, 0, 50, 50);//描边
      ctx.fillRect(0, 0, 50, 50);//填充
      }
    </script>

    结果就是这个样子:

    绘图结果

    二.画方画圆画线

    矩形在上面已经画过了,用到了上下文对象的描边和填充方法,除此之外还有一个关于矩形的方法:clearRect()参数意义相同,作用是掏空一个矩形块(用透明色填充指定区域)

    画圆相对麻烦一点,比如要画一个圆心为(30, 30)半径为20的圆:

    ctx.beginPath();//创建路径
    ctx.arc(30,30,20,0,Math.PI*2,true);//设置弧线路径
    ctx.closePath();//闭合路径
    ctx.stroke();//描边
    ctx.fill();//填充

    arc(x, y, radius, startAngle, endAngle, counterclockwise)方法是用来画弧线的,表示以(x, y)为圆心,radius为半径,起始角度和结束角度分别为startAngle和endAngle,最后一个参数表示前两个角度值是按顺时针还是逆时针算,false表示顺时针。

    画线比画圆要简单些(从(30, 30)画一条50px的横线):

    ctx.beginPath();//创建路径
    ctx.moveTo(30, 30);//把起点移动到(30, 30)
    ctx.lineTo(80, 30);//设置路径连接两点
    ctx.closePath();//闭合路径
    ctx.stroke();//绘制

    能画线画弧了,那画三角五角也就不在话下了,除了上面用到的路径方法之外,还有以下方法:

    • arcTo(x1, y1, x2, y2, radius):从上一点开始绘制一条弧线,到(x2, y2)为止,并且以给定的半径radius穿过(x1, y1)

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

    • quadraticCurveTo(cx, cy, x, y):二次贝塞尔曲线,从上一点开始绘制一条二次曲线,到(x, y)为止,并且以(cx, cy)为控制点

    • rect(x, y, width, height):绘制矩形路径

    设置好路径之后,可以用fill()方法填充或者用stroke()方法描边,还可以用clip()方法对下面的绘图作以限制(相当于PS的选区,详情参见W3School

    三.画图片

    这个功能无疑是最重要的,简单的图形绘制并不是很实用(不信你拿坐标画个肖像画试试)

    1.导入图像

    1. 获得一个指向HTMLImageElement或者另一个canvas元素的引用作为源,也可以通过提供一个URL的方式来使用图片

      图像源可以是img, video, canvas元素的引用,当然,也可以是当场创建的new Image(),但要注意应该在新的Image对象的load事件处理器中引用它,否则因为图像没有加载完成,某些浏览器可能会出错。当然,此外还可以用Base64编码图像源。

    2. 使用drawImage()函数将图片绘制到画布上

    • drawImage(image, x, y):简单明了的好方法

    • drawImage(image, x, y, width, height):支持缩放

    • drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight):支持裁剪(从大图里抠出一小部分,详情参见MDN

    2.导出图像

    这个当然要比图像操作更重要,拿着画布画了半天,该怎么把它导出成图片呢

    canvas.toDataURL():返回图像URL,直接把URL赋值给img的src就可以显示了,它就像一个普通图片地址一样,想怎么用就怎么用。但需要注意

    1. 图像不能来自其它域,嗯,没错,又是跨域安全限制,如果来自其它域,toDataURL()方法会抛出错误

    2. 看清楚toDataURL方法是canvas的,而不是上面一直在用的ctx上下文对象的,而且方法名的大小写也比较特殊

    3.图像操作

    canvas最强大的功能莫过于获取图像数据了,我们可以获取画布上每一点的色值,不用canvas能搞定吗?不能。所以简单的图像处理现在已经可以用js搞定了,而不需要后台函数的参与。

    比如,对上文中的截图做一个简单的反色:

    var canvas = document.getElementById('my_canvas');
    if(canvas.getContext){
        var ctx = canvas.getContext('2d');//获取2d上下文
        //画图
        var img = document.images[0];
        ctx.drawImage(img, 0, 0);
        //获取ImageData
        var imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
        var data = imgData.data;//获取rgba(ImageData的data属性是每个像素点的rgba值)
        //反色
        var r, g, b, a;
        for(var i = 0, len = data.length;i < len; i+=4){
            //取色
                r = data[i];
                g = data[i+1];
                b = data[i+2];
                //a = data[i+3];//反色不需要透明度
                //反色
                data[i] = 255 - r;
                data[i+1] = 255 - g;
                data[i+2] = 255 - b;
        }
    
        imgData.data = data;//写回图像数据
        ctx.putImageData(imgData, 0, 0);//显示结果
    }

    处理效果还是很棒的,如下图:

    反色结果

    需要注意一个小问题,Chrome不允许用drawImage画本地图片,所以上面的结果是FF下的,在测试Ajax的时候也遇到了类似问题,FF一般在限制跨域安全时不会限制本地资源,而Chrome会,对于服务器上的同源资源则不存在这样的差异。

    四.Canvas的更多功能

    渐变、图案填充、线条控制、阴影、旋转、变形、缩放、组合、动画等等更多内容参见参考资料MDN教程

    参考资料

    1. MDN教程:很不错的一篇教程

    2. 《JavaScript高级程序设计》:不舍得还给图书馆的一本好书

  • 相关阅读:
    FastDFS学习总结(2)--Tracker与Storage配置详解
    FastDFS学习总结(1)--FastDFS安装和部署
    Git学习总结(6)——作为一名程序员这些代码托管工具你都知道吗?
    Git学习总结(6)——作为一名程序员这些代码托管工具你都知道吗?
    ActiveMQ学习总结(8)——消息队列设计精要
    ActiveMQ学习总结(8)——消息队列设计精要
    vnc
    Apache HTTP服务器 2.0版本文档
    SSH登录很慢
    source insight技巧
  • 原文地址:https://www.cnblogs.com/ayqy/p/4357015.html
Copyright © 2011-2022 走看看