canvas基础学习笔记(三)

一、曲线绘制

context.arc(centerx,centery,radius,startingAngle,endingAngle,anticlockwise=false);
其中,(centerx,centery)代表绘制的中心点坐标,radius代表曲线半径,startingAngle,endingAngle,分别代表绘制的起始位置和结束位置,anticlockwise=false代表按顺时针绘制(不设置时默认为顺时针绘制),示例如下:

<script type="text/javascript">
    window.onload=function(){
      var canvas=document.getElementById('canvas');
      canvas.width=1024;
      canvas.height=768;
      var context=canvas.getContext('2d');
     
      //绘制多段弧线
      context.lineWidth=5;
      context.strokeStyle="#005588";
      for(var i=0;i<10;i++){
            context.beginPath();
            context.arc(50+i*100,60,40,0,2*Math.PI*(i+1)/10);
            context.closePath();//会自动将画好的图形首尾连接起来
            context.stroke();
      }
      
      for(var i=0;i<10;i++){
            context.beginPath();
            context.arc(50+i*100,150,40,0,2*Math.PI*(i+1)/10);
            context.stroke();
      }

      //逆时针
      for(var i=0;i<10;i++){
            context.beginPath();
            context.arc(50+i*100,300,40,0,2*Math.PI*(i+1)/10,true);
            context.closePath();//会自动将画好的图形首尾连接起来
            context.stroke();
      }

       for(var i=0;i<10;i++){
            context.beginPath();
            context.arc(50+i*100,420,40,0,2*Math.PI*(i+1)/10,true);
          
            context.stroke();
      }
      //填充
      context.fillStyle="#005588"
       for(var i=0;i<10;i++){
            context.beginPath();
            context.arc(50+i*100,540,40,0,2*Math.PI*(i+1)/10,true);
            context.closePath();
            context.stroke();
            context.fill();
      }    
}
</script>

二、绘制圆角矩形

圆角矩形绘制思路.jpg

示例代码如下:

<script type="text/javascript">
    window.onload=function(){
      var canvas=document.getElementById('canvas');
      canvas.width=800;
      canvas.height=800;
      var context=canvas.getContext('2d');
      
      drawRoundRect(context,100,100,600,500,50);

    } 
      //绘制(x,y)代表左上角的位置    width,height代表矩形的宽高)
    
      function drawRoundRect(cxt,x,y,width,height,radius){
        cxt.save();
        cxt.translate(x,y);
        pathRoundRect(cxt,width,height,radius);
        cxt.strokeStyle="black";
        cxt.stroke();
        cxt.restore();
      }
      
      function  pathRoundRect(cxt,width,height,radius){
        cxt.beginPath();

        cxt.arc(width-radius,height-radius,radius,0,Math.PI/2);
        cxt.lineTo(radius,height);
        cxt.arc(radius,height-radius,radius,Math.PI/2,Math.PI);
        cxt.lineTo(0,radius);
        cxt.arc(radius,radius,radius,Math.PI,Math.PI*3/2);
        cxt.lineTo(width-radius,0);
        cxt.arc(width-radius,radius,radius,Math.PI*3/2,Math.PI*2);
  
        cxt.closePath();
      }
</script>

三、圆弧绘制

圆弧绘制.jpg

context.moveTo(x0,y0);
context.arcTo(x1,y1,x2,y2,radius);
其中(x0,y0)为起始点并非是圆弧的开始的位置,(x1,y1)为控制点,(x2,y2)为终止点,并非是圆弧结束的位置。示例代码如下:

<script type="text/javascript">
    window.onload=function(){
      var canvas=document.getElementById('canvas');
      canvas.width=800;
      canvas.height=800;
      var context=canvas.getContext('2d');
      
      //arcTo
      context.beginPath();
      context.moveTo(150,150);//起始点
      context.arcTo(650,150,650,650,300);

      context.lineWidth=5;
      context.strokeStyle="red";
      context.stroke();
     
      context.beginPath();
      context.moveTo(150,150);
      context.lineTo(650,150);
      context.lineTo(650,650);

      context.lineWidth=2;
      context.strokeStyle="gray";
      context.stroke();
     } 
</script>

四、绘制弯月

绘制弯月示意图.jpg

由上图可知:R=(AC*AH)/HC,代码如下:

<script type="text/javascript">
    window.onload=function(){
      var canvas=document.getElementById('canvas');
      canvas.width=800;
      canvas.height=800;
      var context=canvas.getContext('2d');
      //开始绘制
      context.arc(400,400,300,0.5*Math.PI,1.5*Math.PI,true);
      context.moveTo(400,100);
      context.arcTo(1200,400,400,700,(400-100)*dis(400,100,1200,400)/(1200-400));
      context.stroke();
     } 

      function dis(x1,y1,x2,y2){
        return Math.sqrt((x1-x2)*(x1-x2)+(y2-y1)*(y2-y1));     
      }
</script>

五、贝塞尔曲线

1.二次贝塞尔曲线

context.moveTo(x0,y0);
context.quadraticCurveTo(x1,y1,x2,y2);
其中(x0,y0)为曲线的起点,(x1,y1)为控制点,(x2,y2)为曲线的终点。示例代码如下:

<script type="text/javascript">
  window.onload=function(){
      var canvas=document.getElementById('canvas');
      canvas.width=800;
      canvas.height=800;
      var context=canvas.getContext('2d');

      context = canvas.getContext("2d")
      context.lineWidth = 6;
      context.strokeStyle = "#333";
      context.beginPath();
      context.moveTo(100, 250);
      context.quadraticCurveTo(250, 100, 400, 250);
      context.stroke();
      }
</script>

2.三次贝塞尔曲线

context.moveTo(x0,y0);
context.bezierCurveTo(x1,y1,x2,y2,x3,y3);
其中(x0,y0)为曲线的起点,(x1,y1),(x2,y2)为控制点,(x3,y3)为曲线的终点。示例代码如下:

<script type="text/javascript">
  window.onload=function(){
      var canvas=document.getElementById('canvas');
      canvas.width=800;
      canvas.height=800;
      var context=canvas.getContext('2d');
    
      context = canvas.getContext("2d")
      context.lineWidth = 6;
      context.strokeStyle = "#333";
      context.beginPath();
      context.moveTo(212, 275);
      context.bezierCurveTo(150, 100, 350, 100, 276, 282);
      context.stroke();
      }
</script>

六、总结

利用前面所学知识绘制一片星空,代码如下:

<script type="text/javascript">
    window.onload=function(){
       var canvas=document.getElementById('canvas');
      
       canvas.width=1024;
       canvas.height=800;
    
       var context=canvas.getContext('2d');

       var skyStyle=context.createRadialGradient(canvas.width/2,canvas.height,0,canvas.width/2,canvas.height,canvas.height);
       skyStyle.addColorStop(0.0,'#035');
       skyStyle.addColorStop(1.0,'black');
       context.fillStyle=skyStyle;
       context.fillRect(0,0,canvas.width,canvas.height);

        for(var i=0;i<200;i++){
        var R=Math.random()*5+5;//星星可以变小
        var x=Math.random()*canvas.width;
        var y=Math.random()*canvas.height*0.65;//js 中的Math.random()随机产生0-1之间的数  星星产生的竖直位置从0到画布高度的65%
        var a=Math.random()*360;
        drawStar(context,R,x,y,a);

        }
       fillMoon(context,2,900,200,50,30);
       drawLand(context);//绘制绿地,只需要传入上下文的绘图环境

      }

      //******************************************绘制星星
      //rot为旋转的角度  -rot是顺时针转度数
      function drawStar(cxt,R,x,y,rot){
       cxt.save();

       cxt.translate(x,y);//位移
       cxt.rotate(rot/180*Math.PI);//旋转
       cxt.scale(R,R);
       starPath(cxt);//函数的作用是绘制标准的五角星的路径

       cxt.fillStyle="#fb3";
       cxt.fill();
       cxt.restore();
      }
      
      function starPath(cxt){
      cxt.beginPath();
       for(var i=0;i<5;i++){
            cxt.lineTo(Math.cos((18+i*72)/180*Math.PI),-Math.sin((18+i*72)/180*Math.PI));
            cxt.lineTo(Math.cos((54+i*72)/180*Math.PI)*0.5,-Math.sin((54+i*72)/180*Math.PI)*0.5);
       }
       cxt.closePath();
      }

      //******************************************绘制月亮
       //d为控制点横坐标的值  x,y表示弯月的位置 R表示弯月的半径
      function fillMoon(cxt,d,x,y,R,rot,fillColor){
       cxt.save();

       cxt.translate(x,y);
       cxt.rotate(rot*Math.PI/180);
       cxt.scale(R,R);
       pathMoon(cxt,d);//绘制弯月的轮廓
       cxt.fillStyle=fillColor||"#fb3";
       cxt.fill();

       cxt.restore();
      }
      
      function pathMoon(cxt,d){
       cxt.beginPath();
       cxt.arc(0,0,1,0.5*Math.PI,1.5*Math.PI,true);
       cxt.moveTo(0,-1);
       cxt.arcTo(d,0,0,1,dis(0,-1,d,0)/d);//内弧结束的位置为0,1
       cxt.closePath();
      }

      function dis(x1,y1,x2,y2){
        return Math.sqrt((x1-x2)*(x1-x2)+(y2-y1)*(y2-y1));     
      }

      //******************************************绘制绿地
      function drawLand(cxt){
        cxt.save();
        
        cxt.beginPath();
        cxt.moveTo(0,600);
        cxt.bezierCurveTo(540,400,660,800,1200,600);
        cxt.lineTo(1200,800);
        cxt.lineTo(0,800);
        cxt.closePath();

       //填充线性渐变色
       var landStyle=cxt.createLinearGradient(0,800,0,0);
       landStyle.addColorStop(0.0,'#030');
       landStyle.addColorStop(1.0,'#580');
       cxt.fillStyle=landStyle;
       cxt.fill();

       cxt.restore();
      }
</script>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,686评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,668评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,160评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,736评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,847评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,043评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,129评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,872评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,318评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,645评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,777评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,861评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,589评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,687评论 2 351

推荐阅读更多精彩内容