1. 程式人生 > >canvas圖形繪制

canvas圖形繪制

多條 lineto mat 一輪 ima line ans sta clear

前面的話

  前面分別介紹了canvas的基礎用法和進階用法,本文將使用canvas的各種語法進行圖形繪制

繪制線條

【繪制線條】

  下面來嘗試繪制一段線條

技術分享
<canvas id="drawing" style="border:1px solid black">
    <p>The canvas element is not supported!</p>
</canvas>
<script>
var drawing = document.getElementById(‘drawing‘);
if(drawing.getContext){
    var context = drawing.getContext(‘2d‘);
    //開始繪制
    context.beginPath();
    //將光標移動到(10,10)位置
    context.moveTo(10,10);
    //從(10,10)點開始繪制一條直線,到(100,100)為止
    context.lineTo(100,100);
    //線條寬度為5
    context.lineWidth = 5;
    //線條顏色為淺綠
    context.strokeStyle = "lightgreen";
    //繪制線條
    context.stroke();    
} 
</script>
技術分享 技術分享

【繪制折線】

  下面,更進一步,繪制多條折線

技術分享
<canvas id="drawing" style="border:1px solid black">
    <p>The canvas element is not supported!</p>
</canvas>
<script>
var drawing = document.getElementById(‘drawing‘);
if(drawing.getContext){
    var context = drawing.getContext(‘2d‘);
    context.beginPath();
    context.moveTo(10,10);
    context.lineTo(50,50);
    context.lineTo(10,100);
    context.lineWidth = 5;
    context.strokeStyle = "lightgreen";
    context.stroke();

    context.beginPath();
    context.moveTo(60,10);
    context.lineTo(100,50);
    context.lineTo(60,100);
    context.lineWidth = 5;
    context.strokeStyle = "lightblue";
    context.stroke();

    context.beginPath();
    context.moveTo(110,10);
    context.lineTo(150,50);
    context.lineTo(110,100);
    context.lineWidth = 5;
    context.strokeStyle = "pink";
    context.stroke();
} 
</script>
技術分享

【繪制閉合圖形】

  下面繪制四條線條,組合成一個閉合圖形

技術分享
<canvas id="drawing" style="border:1px solid black">
    <p>The canvas element is not supported!</p>
</canvas>
<script>
var drawing = document.getElementById(‘drawing‘);
if(drawing.getContext){
    var context = drawing.getContext(‘2d‘);
    context.beginPath();
    context.moveTo(10,10);
    context.lineTo(110,10);
    context.lineTo(110,110);
    context.lineTo(10,110);
    context.lineTo(10,10);
    context.lineWidth = 10;
    context.strokeStyle = "lightgreen";
    context.stroke();    
} 
</script>
技術分享

  結果如下所示,最後一筆閉合的時候有問題,導致左上角有一個缺口。這種情況是設置了lineWidth導致的。如果默認1筆觸的話,是沒有問題的。但是筆觸越大,線條越寬

  這時,需要使用clothPath()來閉合圖形,而最後一筆可以不畫出來

技術分享
<script>
var drawing = document.getElementById(‘drawing‘);
if(drawing.getContext){
    var context = drawing.getContext(‘2d‘);
    context.beginPath();
    context.moveTo(10,10);
    context.lineTo(110,10);
    context.lineTo(110,110);
    context.lineTo(10,110);
    context.closePath();
    context.lineWidth = 10;
    context.strokeStyle = "lightgreen";
    context.stroke();    
} 
</script>
技術分享

  當然,如果只是畫矩形,使用rect()或fillRect()方法更簡單

繪制矩形

  下面來繪制一個背景顏色為紅色,尺寸為100*100,位置為(0,0)點的矩形

技術分享
<canvas id="drawing" style="border:1px solid black">
    <p>The canvas element is not supported!</p>
</canvas>
<script>
var drawing = document.getElementById(‘drawing‘);
if(drawing.getContext){
    var context = drawing.getContext(‘2d‘);
   context.fillStyle = ‘red‘;
   context.fillRect(0,0,100,100);
}
</script>
技術分享 技術分享

  下面來繪制一個半透明的藍色描邊矩形,尺寸為100*100,位置在(0,0)點

技術分享
<script>
var drawing = document.getElementById(‘drawing‘);
if(drawing.getContext){
    var context = drawing.getContext(‘2d‘);
   context.strokeStyle = ‘rgba(0,0,255,0.5)‘;
   context.strokeRect(0,0,100,100);
} </script>
技術分享 技術分享

  接下來,在(0,0)點繪制尺寸為100*100背景為半透明紅色的矩形, 1s後在(50,50)點繪制尺寸為100*100,描邊為半透明藍色的矩形,1s後使用clearRect()清除矩形

技術分享
<canvas id="drawing" style="border:1px solid black">
    <p>The canvas element is not supported!</p>
</canvas>
<script>
var drawing = document.getElementById(‘drawing‘);
if(drawing.getContext){
    var context = drawing.getContext(‘2d‘);
    context.fillStyle = ‘rgba(255,0,0,0.5)‘;
    context.fillRect(0,0,100,100);
    setTimeout(function(){
      context.strokeStyle = ‘rgba(0,0,255,0.5)‘;
      context.strokeRect(50,50,100,100);  
    },1000);
    setTimeout(function(){
      context.clearRect(0,0,300,150);
    },2000);    
} 
</script>
技術分享 技術分享

繪制弧形

【繪制圓】

技術分享
<canvas id="canvas">
    <p>The canvas element is not supported!</p>
</canvas>
<script>
var canvas = document.getElementById(‘canvas‘);
if(canvas.getContext){
    canvas.width = 1000;
    canvas.height = 200;
    canvas.style.width = ‘400px‘;    
    var context = canvas.getContext(‘2d‘);
    context.lineWidth = 5;
    context.strokeStyle = ‘#058‘;
    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();
    }    
}
</script>    
技術分享

【繪制圓角矩形】

  圓角矩形的示意圖如下所示

技術分享 技術分享
<canvas id="canvas" style="border:1px solid black">
    <p>The canvas element is not supported!</p>
</canvas>
<script>
var canvas = document.getElementById(‘canvas‘);
if(canvas.getContext){
    var cxt = canvas.getContext(‘2d‘);
    var W = 300,H = 150;
    drawRoundRect(cxt,0,0,W,H,50); 
    cxt.lineWidth = 10;
    cxt.stroke();       
    function drawRoundRect(cxt, x, y, w, h, r){  
        cxt.beginPath();
        //左上角
        cxt.arc(x+r,y+r,r,Math.PI,Math.PI*3/2);
        //上側
        cxt.lineTo(x+w-r,y);
        //右上角
        cxt.arc(x+w-r,y+r,r,Math.PI*3/2,Math.PI*2);
        //右側
        cxt.lineTo(x+w,y+h-r);
        //右下角
        cxt.arc(x+w-r,y+h-r,r,0,Math.PI/2);
        //下側
        cxt.lineTo(x+r,y+h);
        //左下角
        cxt.arc(x+r,y+h-r,r,Math.PI/2,Math.PI);
        cxt.closePath();
    }
}
</script>   
技術分享

【繪制彎月】

  下面是一輪彎月的計算示意圖

技術分享

  下面將上面的視圖變成更通用的函數封裝,代碼如下

技術分享
<canvas id="drawing" style="border:1px solid black">
    <p>The canvas element is not supported!</p>
</canvas>
<script>
if(drawing.getContext){
  var W = drawing.width = 200;
  var H = drawing.height = 200;
  var cxt = drawing.getContext(‘2d‘);
  function dis(x1,y1,x2,y2){
    return Math.sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));
  }
  function fillMoon(cxt,d,x,y,r,rot){
    cxt.save();
    cxt.translate(x,y);
    cxt.rotate(rot*Math.PI/180);
    cxt.scale(r,r);
    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);
    cxt.closePath();
    cxt.restore();
  }
  fillMoon(cxt,2,100,100,100,0)
  cxt.fillStyle = ‘#fb5‘;
  cxt.fill();
}
</script>
技術分享

復雜圖形

  下面基於線條、矩形和弧形,來繪制復雜圖形

【繪制魔性圖案】

  設置為正方形的魔性圖案,當坐標位置x或y變化1px時,寬度或高度需要變化2px

  於是,得到下面代碼

技術分享
<canvas id="canvas" width=300 height=300 style="border: 1px solid #aaaaaa;">
    <p>The canvas element is not supported!</p>
</canvas>
<script>
var canvas = document.getElementById("canvas");
if(canvas.getContext){
  var context = canvas.getContext("2d");  
  for(var i=0; i<=20; i++){
    drawRect(context, 0 + 15 * i, 0 + 15 * i, 300 - 30 * i, 300 - 30 * i);
  }
  function drawRect(cxt,x,y,width,height){
    cxt.beginPath();
    cxt.rect(x, y, width, height);
    cxt.lineWidth = 5;
    cxt.strokeStyle = "blue";
    cxt.stroke();    
  }
}
</script>
技術分享

【繪制五角星】

  五角星可分為大圓和小圓兩部分。大圓控制外側5個點的坐標位置,小圓控制內側5個點的坐標位置。下面是詳細的角度分析

技術分享 技術分享
<canvas id="canvas">
    <p>The canvas element is not supported!</p>
</canvas>
<script>
var canvas = document.getElementById(‘canvas‘);
if(canvas.getContext){
    var cxt = canvas.getContext(‘2d‘);
    var H = 100,W = 200;
    canvas.height = H;
    canvas.width = W;    
    function drawStar(cxt,r,R,x,y,rotate){
        if(rotate == undefined){
            rotate = 0;
        }
        cxt.beginPath();
        for(var i = 0; i < 5; i++){
            cxt.lineTo(Math.cos((18 + i*72 - rotate)/180*Math.PI)*R + x,-Math.sin((18+i*72 - rotate)/180 * Math.PI) * R + y);
            cxt.lineTo(Math.cos((54 + i*72 - rotate)/180*Math.PI)*r + x,-Math.sin((54+i*72 - rotate)/180 * Math.PI) * r + y);
        }
        cxt.closePath();
        cxt.stroke();
    }  
    drawStar(cxt,30,50,50,50);    
}
</script>    
技術分享

【繪制螺旋線】

  下面是制作螺旋線的示意圖

技術分享

  從圓心點開始,按照圓的公式向外移動,每次移動時,圓心角逐漸增大,半徑逐漸增大

技術分享
<canvas id="drawing" width="100" height="100"></canvas>
<script>
var drawing = document.getElementById(‘drawing‘);
if(drawing.getContext){
    var context = drawing.getContext(‘2d‘);
    var x = drawing.width/2;
    var y = drawing.height/2;
    var deg = 0;
    var r = 1;
    context.strokeStyle = ‘red‘;
    context.lineWidth = 2;
    context.moveTo(x,y);
    for(var i = 0; i < 4800; i++){
        deg++;
        r+=0.01;
        context.lineTo(x+Math.cos(deg * Math.PI/180)*r,y+Math.sin(deg * Math.PI/180)*r);
    }
    context.stroke();
}
</script>
技術分享

canvas圖形繪制