canvas基礎(chǔ)學(xué)習(xí)筆記(五)

canvas高級(jí)內(nèi)容

一、陰影

context.shadowColor="gray";//指定陰影的顏色
context.shadowOffsetX=-20;//指定陰影的位移值
context.shadowOffsetY=-20;//指定陰影的位移值
context.shadowBlur=5;//描述陰影模糊的程度(值越大越模糊)
示例代碼如下:

<script type="text/javascript">
    window.onload=function(){
       var canvas=document.getElementById('canvas');
      
       canvas.width=1024;
       canvas.height=800;
    
       var context=canvas.getContext('2d');
       
       context.fillStyle="#058";
       context.shadowColor="gray";//可以使用任意的css可以接受的樣式值,包括使用rgba設(shè)置半透明色
       //context.shadowOffsetX=20;
       //context.shadowOffsetY=20;
       //負(fù)值時(shí)陰影方向會(huì)相反
       context.shadowOffsetX=-20;
       context.shadowOffsetY=-20;
       context.shadowBlur=5;//越大越模糊

       context.fillRect(200,200,400,400);
      }
</script>

二、global屬性

1.globalAlpha

context.globalAlpha=1;默認(rèn)值,在這種情況下默認(rèn)繪制的圖形都不具有透明度,即后繪制的圖形會(huì)蓋住之前繪制的圖形。示例如下:

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

       context.globalAlpha=0.5;//不加此句時(shí)后繪制的圓會(huì)蓋住之前繪制的
       //畫(huà)出100個(gè)圓
       for(var i=0;i<100;i++){
        var R=Math.floor(Math.random()*255);
        var G=Math.floor(Math.random()*255);
        var B=Math.floor(Math.random()*255);

        context.fillStyle="rgb("+R+","+G+","+B+")";

        context.beginPath();
        context.arc(Math.random()*canvas.width,Math.random()*canvas.height,Math.random()*100,0,Math.PI*2);
        context.fill();
       }
      }
</script>

2.globalCompositeOperation(描述繪制的圖形在重疊時(shí)所產(chǎn)生的效果)

context.globalCompositeOperation="source-over";//后繪制的圖形會(huì)蓋住之前繪制的圖形
context.globalCompositeOperation="destination-over";//之前繪制的圖形會(huì)蓋住之后繪制的圖形
示例如下:

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

      context.fillStyle="blue";
      context.fillRect(100,200,400,400);

      //context.globalCompositeOperation="source-over";
      context.globalCompositeOperation="destination-over";
      context.fillStyle="red";

      context.beginPath();
      context.moveTo(400,300);
      context.lineTo(650,700);
      context.lineTo(150,700);
      context.closePath();
      context.fill();
  }
</script>

此外,其他globalCompositeOperation屬性的屬性值如下:
source-over、source-atop、source-in 、source-out ;destination-over 、destination-atop 、destination-in 、destination-out;lighter、 copy、 xor。示例代碼如下:

<body >
 <canvas id="canvas" style="border: 1px solid #aaa;display: block;margin: 50px auto">
 當(dāng)前瀏覽器不支持canvas,請(qǐng)更換瀏覽器后再試
 </canvas>
 <div id="buttons">
   <a href="#">source-over</a>
   <a href="#">source-atop</a>
   <a href="#">source-in</a>
   <a href="#">source-out</a>
   <a href="#">destination-over</a>
   <a href="#">destination-atop</a>
   <a href="#">destination-in</a>
   <a href="#">destination-out</a>
   <a href="#">lighter</a>
   <a href="#">copy</a>
   <a href="#">xor</a>
 </div>

<script type="text/javascript">
  window.onload=function(){
    draw("source-over");
    var buttons=document.getElementById("buttons").getElementsByTagName("a");
    for(var i=0;i<buttons.length;i++){
      buttons[i].onclick=function(){
        draw(this.text);
        return false;
      }
    }
  }

    function draw(compositeStyle){
      var canvas=document.getElementById('canvas');
      canvas.width=1200;
      canvas.height=800;
      var context=canvas.getContext('2d');

      context.clearRect(0,0, canvas.width,canvas.height);

      //draw title
      context.font="bold 40px Arial";
      context.textAlign="center";
      context.textBaseline="middle";
      context.fillStyle="#058";
      context.fillText("globalCompositeOperation="+compositeStyle,canvas.width/2,60);

      //draw a rect
      context.fillStyle="blue";
      context.fillRect(300,150,500,500);

      //drae a triangle
      context.globalCompositeOperation=compositeStyle;
      context.fillStyle="red";
      context.beginPath();
      context.moveTo(700,250);
      context.lineTo(1000,750);
      context.lineTo(400,750);
      context.closePath();
      context.fill();
  }
</script>

三、clip和剪輯區(qū)域

1. context.clip();此函數(shù)與路徑規(guī)劃函數(shù)一起使用,例如:lineTo、arc、貝塞爾曲線等等。示例代碼如下:

<script type="text/javascript">
    window.onload=function(){
       var canvas=document.getElementById('canvas');
      
       canvas.width=800;
       canvas.height=800;
    
       var context=canvas.getContext('2d');
       //設(shè)置畫(huà)布顏色
       context.beginPath();
       context.fillStyle="black";
       context.fillRect(0,0,canvas.width,canvas.height)

       context.beginPath();
       context.arc(400,400,150,0,Math.PI*2);
       context.fillStyle="#fff";
       context.fill();
       context.clip();
       
       context.font="bold 140px Arial";
       context.textAlign="center";
       context.textBaseline="middle";
       context.fillStyle="#058";
       context.fillText("CANVAS",canvas.width/2,canvas.height/2);    
  }
</script>

2.小實(shí)例(圓形探照燈制作)

<script type="text/javascript">
  var searchLight={x:400,y:400,radius:150,vx:Math.random()*5+10,vy:Math.random()*5+10,}//vx vy代表移動(dòng)的速度

    window.onload=function(){
       var canvas=document.getElementById('canvas');
      
       canvas.width=800;
       canvas.height=800;
    
       var context=canvas.getContext('2d');
       
       //動(dòng)畫(huà)基礎(chǔ)
       setInterval(function(){
        draw(context);
        update(canvas.width,canvas.height);
       },40);
    }

    function draw(cxt){
      var canvas=cxt.canvas;
      cxt.clearRect(0,0,canvas.width,canvas.height);//清空畫(huà)布

      cxt.save();
      //填充畫(huà)布為黑色
      cxt.beginPath();
      cxt.fillStyle="black";
      cxt.fillRect(0,0,canvas.width,canvas.height);
      //畫(huà)出填充區(qū)域
      cxt.beginPath();
      cxt.arc(searchLight.x,searchLight.y,searchLight.radius,0,Math.PI*2);
      cxt.fillStyle="#fff";
      cxt.fill();
      cxt.clip();
      //撰寫(xiě)文字
      cxt.font="bold 140px Arial";
      cxt.textAlign="center";
      cxt.textBaseline="middle";
      cxt.fillStyle="#058";
      cxt.fillText("CANVAS",canvas.width/2,canvas.height/4);
      cxt.fillText("CANVAS",canvas.width/2,canvas.height/2);
      cxt.fillText("CANVAS",canvas.width/2,canvas.height*3/4);

      cxt.restore();
    }

    function update(canvasWidth,canvasHeight){
      searchLight.x+=-searchLight.vx;
      searchLight.y+=searchLight.vy;

      if(searchLight.x-searchLight.radius<=0){
        searchLight.vx=-searchLight.vx;
        searchLight.x=searchLight.radius;
      }

      if(searchLight.x+searchLight.radius>=canvasWidth){
        searchLight.vx=-searchLight.vx;
        searchLight.x=canvasWidth-searchLight.radius;
      }
      
      if(searchLight.y-searchLight.radius<=0){
        searchLight.vy=-searchLight.vy;
        searchLight.y=searchLight.radius;
      }
      
       if(searchLight.y+searchLight.radius>=canvasHeight){
        searchLight.vy=-searchLight.vy;
        searchLight.y=canvasHeight-searchLight.radius;
      }
    }
</script>

四、路徑方向和剪紙效果

1.路徑方向(非零環(huán)繞原則)

路徑示意圖.jpg

如上圖,將圖形的繪制路徑首尾相接并標(biāo)明方向,然后從某個(gè)區(qū)域由區(qū)域內(nèi)到外畫(huà)出一個(gè)箭頭,兩個(gè)箭頭方向相加不為0則染色,為0則不染色。下面以一個(gè)圓環(huán)的繪制為例:

圓環(huán)路徑示意圖.jpg

示例代碼如下:

<script type="text/javascript">
 
    window.onload=function(){
       var canvas=document.getElementById('canvas');
      
       canvas.width=800;
       canvas.height=800;
    
       var context=canvas.getContext('2d');
       
       //繪制圓環(huán)
       context.beginPath();
       context.arc(400,400,300,0,Math.PI*2,false);
       context.arc(400,400,150,0,Math.PI*2,true);
       context.closePath();

       context.fillStyle="#058";
       context.shadowColor="gray";
       context.shadowOffsetX=10;
       context.shadowOffsetY=10;
       context.shadowBlur=10;
       context.fill();
    }
</script>

2.剪紙效果(需明確哪個(gè)位置染色,哪個(gè)位置不染色)

示例代碼如下:

<script type="text/javascript">
 
    window.onload=function(){
       var canvas=document.getElementById('canvas');
      
       canvas.width=800;
       canvas.height=800;
    
       var context=canvas.getContext('2d');
       
       //繪制
       context.beginPath();
       context.rect(100,100,600,600);//順時(shí)針
       pathRect(context,200,200,400,200);//逆時(shí)針
       pathTriangle(context,300,450,150,650,450,650);
       context.arc(550,550,100,0,Math.PI*2,true);//逆時(shí)針
       context.closePath();

       context.fillStyle="#058";
       context.shadowColor="gray";
       context.shadowOffsetX=10;
       context.shadowOffsetY=10;
       context.shadowBlur=10;
       context.fill();
    }
  
  function pathRect(cxt,x,y,width,height){
    cxt.moveTo(x,y);
    cxt.lineTo(x,y+height);
    cxt.lineTo(x+width,y+height);
    cxt.lineTo(x+width,y);
    cxt.lineTo(x,y);
  }
  function pathTriangle(cxt,x1,y1,x2,y2,x3,y3){
    cxt.moveTo(x1,y1);
    cxt.lineTo(x2,y2);
    cxt.lineTo(x3,y3);
    cxt.lineTo(x1,y1);
  }
</script>

五、使用canvas交互

isPointInPath 是canvas中內(nèi)置的點(diǎn)擊檢測(cè)函數(shù)
context.isPointInPath(x,y)看傳入的點(diǎn)(x,y)是否在當(dāng)前規(guī)劃的路徑內(nèi)。下邊的例子是繪制10個(gè)小球,當(dāng)點(diǎn)擊小球時(shí)它的顏色由藍(lán)色變?yōu)榧t色,示例代碼如下:

<script type="text/javascript">
  var balls=[];
  var canvas=document.getElementById('canvas');
  var context=canvas.getContext('2d');

    window.onload=function(){
    canvas.width=800;
    canvas.height=800;
    for(var i=0;i<10;i++){
      var aBall={x:Math.random()*canvas.width,
          y:Math.random()*canvas.height,
          r:Math.random()*50+20};
          balls[i]=aBall;
    }
    draw();
    canvas.addEventListener("mouseup",detect);//用canvas的addEventListener方法創(chuàng)建事件
  }

    function draw(){
      //一次for循環(huán)遍歷balls數(shù)組
      for(var i=0;i<balls.length;i++){
        context.beginPath();
        context.arc(balls[i].x,balls[i].y,balls[i].r,0,Math.PI*2);

        context.fillStyle="#058";
        context.fill();
      }
    }

    function detect(event){
      //獲得鼠標(biāo)點(diǎn)擊在canvas中位置的方法
      var x=event.clientX-canvas.getBoundingClientRect().left;//鼠標(biāo)坐標(biāo)基于Web文檔的橫向距離減去canvas畫(huà)布離整個(gè)文檔左側(cè)的距離
      var y=event.clientY-canvas.getBoundingClientRect().top;

      for(var i=0;i<balls.length;i++){
        context.beginPath();
        context.arc(balls[i].x,balls[i].y,balls[i].r,0,Math.PI*2);

        if(context.isPointInPath(x,y)){
          context.fillStyle="red";
          context.fill();
        }
      }
    }
</script>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容