美文网首页canvas
canvas基础学习笔记(五)

canvas基础学习笔记(五)

作者: 开心糖果的夏天 | 来源:发表于2017-05-03 08:47 被阅读233次

    canvas高级内容

    一、阴影

    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设置半透明色
           //context.shadowOffsetX=20;
           //context.shadowOffsetY=20;
           //负值时阴影方向会相反
           context.shadowOffsetX=-20;
           context.shadowOffsetY=-20;
           context.shadowBlur=5;//越大越模糊
    
           context.fillRect(200,200,400,400);
          }
    </script>
    

    二、global属性

    1.globalAlpha

    context.globalAlpha=1;默认值,在这种情况下默认绘制的图形都不具有透明度,即后绘制的图形会盖住之前绘制的图形。示例如下:

    <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;//不加此句时后绘制的圆会盖住之前绘制的
           //画出100个圆
           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(描述绘制的图形在重叠时所产生的效果)

    context.globalCompositeOperation="source-over";//后绘制的图形会盖住之前绘制的图形
    context.globalCompositeOperation="destination-over";//之前绘制的图形会盖住之后绘制的图形
    示例如下:

    <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">
     当前浏览器不支持canvas,请更换浏览器后再试
     </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和剪辑区域

    1. context.clip();此函数与路径规划函数一起使用,例如: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');
           //设置画布颜色
           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.小实例(圆形探照灯制作)

    <script type="text/javascript">
      var searchLight={x:400,y:400,radius:150,vx:Math.random()*5+10,vy:Math.random()*5+10,}//vx vy代表移动的速度
    
        window.onload=function(){
           var canvas=document.getElementById('canvas');
          
           canvas.width=800;
           canvas.height=800;
        
           var context=canvas.getContext('2d');
           
           //动画基础
           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);//清空画布
    
          cxt.save();
          //填充画布为黑色
          cxt.beginPath();
          cxt.fillStyle="black";
          cxt.fillRect(0,0,canvas.width,canvas.height);
          //画出填充区域
          cxt.beginPath();
          cxt.arc(searchLight.x,searchLight.y,searchLight.radius,0,Math.PI*2);
          cxt.fillStyle="#fff";
          cxt.fill();
          cxt.clip();
          //撰写文字
          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.路径方向(非零环绕原则)

    路径示意图.jpg

    如上图,将图形的绘制路径首尾相接并标明方向,然后从某个区域由区域内到外画出一个箭头,两个箭头方向相加不为0则染色,为0则不染色。下面以一个圆环的绘制为例:

    圆环路径示意图.jpg

    示例代码如下:

    <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.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.剪纸效果(需明确哪个位置染色,哪个位置不染色)

    示例代码如下:

    <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);//顺时针
           pathRect(context,200,200,400,200);//逆时针
           pathTriangle(context,300,450,150,650,450,650);
           context.arc(550,550,100,0,Math.PI*2,true);//逆时针
           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中内置的点击检测函数
    context.isPointInPath(x,y)看传入的点(x,y)是否在当前规划的路径内。下边的例子是绘制10个小球,当点击小球时它的颜色由蓝色变为红色,示例代码如下:

    <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方法创建事件
      }
    
        function draw(){
          //一次for循环遍历balls数组
          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){
          //获得鼠标点击在canvas中位置的方法
          var x=event.clientX-canvas.getBoundingClientRect().left;//鼠标坐标基于Web文档的横向距离减去canvas画布离整个文档左侧的距离
          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>
    

    相关文章

      网友评论

        本文标题:canvas基础学习笔记(五)

        本文链接:https://www.haomeiwen.com/subject/kjmftxtx.html