• 技术文章 >web前端 >H5教程

    canvas游戏开发学习之三:绘制复杂形状

    黄舟黄舟2017-01-16 17:03:03原创700

    贝塞尔和二次方曲线Bezier and quadratic curves

    接下来要介绍的路径是贝塞尔曲线,它可以是二次和三次方的形式,一般用于绘制复杂而有规律的形状。

    quadraticCurveTo(cp1x, cp1y, x, y) // BROKEN in Firefox 1.5 (see work around below)
    bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)

    上面两行代码的区别见右图。它们都有一个起点一个终点(图中的蓝点),但二次方贝塞尔曲线只有一个(红色)控制点点)而三次方贝塞尔曲线有两个。参数 x和y是终点坐标,cp1x和cp1y 是第一个控制点的坐标,cp2x和cp2y是第二个的。

    179.png

    使用二次方和三次方的贝塞尔曲线是相当有挑战的,因为不像在矢量绘图软件 Adobe Illustrator 里那样有即时的视觉反馈。因为用它来画复杂图形是比较麻烦的。但如果你有时间,并且最重要是有耐心,再复杂的图形都可以绘制出来的。下面我们来画一个简单 而又规律的图形。这些例子都比较简单。我们绘制的都是完整的图形。

    180.png

    // Quadratric curves example
    ctx.beginPath();
    ctx.moveTo(75,25);
    ctx.quadraticCurveTo(25,25,25,62.5);
    ctx.quadraticCurveTo(25,100,50,100);
    ctx.quadraticCurveTo(50,120,30,125);
    ctx.quadraticCurveTo(60,120,65,100);
    ctx.quadraticCurveTo(125,100,125,62.5);
    ctx.quadraticCurveTo(125,25,75,25);
    ctx.stroke();

    通过计算,可以由二次曲线的单个控制点得出相应三次方曲线的两个控制点,因此二次方转三次方是可能的,但是反之不然。仅当三次方程中的三次项为零是才可能转换为二次的贝塞尔曲线。通常地可以用多条二次方曲线通过细分算法来近似模拟三次方贝塞尔曲线。

    181.png

    // Bezier curves example
    ctx.beginPath();
    ctx.moveTo(75,40);
    ctx.bezierCurveTo(75,37,70,25,50,25);
    ctx.bezierCurveTo(20,25,20,62.5,20,62.5);
    ctx.bezierCurveTo(20,80,40,102,75,120);
    ctx.bezierCurveTo(110,102,130,80,130,62.5);
    ctx.bezierCurveTo(130,62.5,130,25,100,25);
    ctx.bezierCurveTo(85,25,75,37,75,40);
    ctx.fill();

    矩形路径 Rectangles

    除了上面提到的三个方法可以直接绘制矩形之外,我们还有一个rect方法是用于绘制矩形路径的。

    rect(x, y, width, height)

    它接受四个参数,x和y 是其左上角坐标,width和height 是其宽和高。当它被调用时,moveTo方法会自动被调用,参数为(0,0),于是起始坐标又恢复成初始原点了。

    综合样例

    在整个例子里,最值得注意的是roundedRect函数的使用和fillStyle属性的设置。自定义函数对于封装复杂图形的绘制是非常有用的。在这个例子里使用自定义函数就省掉了大约一半的代码。在接下来的例子里会深入探讨fillStyle属性的使用。这里是用它来改变填充颜色,从默认的黑色,到白色,然后再回到黑色。

    182.png

    function draw() {
      var ctx = document.getElementById('canvas').getContext('2d');
      roundedRect(ctx,12,12,150,150,15);
      roundedRect(ctx,19,19,150,150,9);
      roundedRect(ctx,53,53,49,33,10);
      roundedRect(ctx,53,119,49,16,6);
      roundedRect(ctx,135,53,49,33,10);
      roundedRect(ctx,135,119,25,49,10);
    
      ctx.beginPath();
      ctx.arc(37,37,13,Math.PI/7,-Math.PI/7,false); //chiensexu  本来是true呵呵,反了
      ctx.lineTo(31,37);
      ctx.fill();
      for(i=0;i<8;i++){
        ctx.fillRect(51+i*16,35,4,4);
      }
      for(i=0;i<6;i++){
        ctx.fillRect(115,51+i*16,4,4);
      }
      for(i=0;i<8;i++){
        ctx.fillRect(51+i*16,99,4,4);
      }
      ctx.beginPath();
      ctx.moveTo(83,116);
      ctx.lineTo(83,102);
      ctx.bezierCurveTo(83,94,89,88,97,88);
      ctx.bezierCurveTo(105,88,111,94,111,102);
      ctx.lineTo(111,116);
      ctx.lineTo(106.333,111.333);
      ctx.lineTo(101.666,116);
      ctx.lineTo(97,111.333);
      ctx.lineTo(92.333,116);
      ctx.lineTo(87.666,111.333);
      ctx.lineTo(83,116);
      ctx.fill();
      ctx.fillStyle = "white";
      ctx.beginPath();
      ctx.moveTo(91,96);
      ctx.bezierCurveTo(88,96,87,99,87,101);
      ctx.bezierCurveTo(87,103,88,106,91,106);
      ctx.bezierCurveTo(94,106,95,103,95,101);
      ctx.bezierCurveTo(95,99,94,96,91,96);
      ctx.moveTo(103,96);
      ctx.bezierCurveTo(100,96,99,99,99,101);
      ctx.bezierCurveTo(99,103,100,106,103,106);
      ctx.bezierCurveTo(106,106,107,103,107,101);
      ctx.bezierCurveTo(107,99,106,96,103,96);
      ctx.fill();
      ctx.fillStyle = "black";
      ctx.beginPath();
      ctx.arc(101,102,2,0,Math.PI*2,true);
      ctx.fill();
      ctx.beginPath();
      ctx.arc(89,102,2,0,Math.PI*2,true);
      ctx.fill();
    }
    function roundedRect(ctx,x,y,width,height,radius){
      ctx.beginPath();
      ctx.moveTo(x,y+radius);
      ctx.lineTo(x,y+height-radius);
      ctx.quadraticCurveTo(x,y+height,x+radius,y+height);
      ctx.lineTo(x+width-radius,y+height);
      ctx.quadraticCurveTo(x+width,y+height,x+width,y+height-radius);
      ctx.lineTo(x+width,y+radius);
      ctx.quadraticCurveTo(x+width,y,x+width-radius,y);
      ctx.lineTo(x+radius,y);
      ctx.quadraticCurveTo(x,y,x,y+radius);
      ctx.stroke();
    }

    以上就是canvas游戏开发学习之三:绘制复杂形状的内容,更多相关内容请关注PHP中文网(m.sbmmt.com)!



    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。
    上一篇:canvas游戏开发学习之二:绘制基本图形 下一篇:自己动手写 PHP MVC 框架(40节精讲/巨细/新人进阶必看)

    相关文章推荐

    • HTML 5可以做五件事情 超出你的想象• 为什么html5将主宰在线视频?• 分享HTML5虚拟键盘出现挡住输入框的解决办法• HTML5 b和i标记将被赋予真正的语义_html5教程技巧• html5 实现客户端验证上传文件的大小(简单实例)_html5教程技巧
    1/1

    PHP中文网