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閱讀 230,431評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,637評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,555評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,900評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,629評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,976評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,976評論 3 448
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,139評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,686評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,411評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,641評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,129評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,820評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,233評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,567評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,362評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,604評論 2 380

推薦閱讀更多精彩內容