【Canavs与艺术】绘制蓝白绶带大卫之星勋章

【图例】

【代码】

<!DOCTYPE html>
<html lang="utf-8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<head>
     <title>用Canvas绘制蓝白绶带大卫之星勋章</title>
     <style type="text/css">
     .centerlize{
        margin:0 auto;
        width:1200px;
     }
     </style>
     </head>

     <body onload="init();">
        <div class="centerlize">
            <canvas id="myCanvas" width="512px" height="512px" style="border:1px dotted black;">
                如果看到这段文字说您的浏览器尚不支持HTML5 Canvas,请更换浏览器再试.
            </canvas>
        </div>
     </body>
</html>
<script type="text/javascript">
<!--
/*****************************************************************
* 将全体代码(从<!DOCTYPE到script>)拷贝下来,粘贴到文本编辑器中,
* 另存为.html文件,再用chrome浏览器打开,就能看到实现效果。
******************************************************************/

// canvas的绘图环境
var ctx;

// 高宽
const WIDTH=512;
const HEIGHT=512;

// 舞台对象
var stage;

//-------------------------------
// 初始化
//-------------------------------
function init(){
    // 获得canvas对象
    var canvas=document.getElementById('myCanvas');  
    canvas.width=WIDTH;
    canvas.height=HEIGHT;

    // 初始化canvas的绘图环境
    ctx=canvas.getContext('2d');  
    ctx.translate(WIDTH/2,HEIGHT/2);// 原点平移到画布中央

    // 准备
    stage=new Stage();    
    stage.init();

    // 开幕
    animate();
}

// 播放动画
function animate(){    
    stage.update();    
    stage.paintBg(ctx);
    stage.paintFg(ctx);     

    // 循环
    if(true){
        window.requestAnimationFrame(animate);   
    }
}

// 舞台类
function Stage(){
    // 初始化
    this.init=function(){
        
    }

    // 更新
    this.update=function(){
        
    }

    // 画背景
    this.paintBg=function(ctx){
        ctx.clearRect(-WIDTH/2,-HEIGHT/2,WIDTH,HEIGHT);// 清屏    
        
        //--以下为绶带部分
        ctx.save();
        // 绘制轮廓
        ctx.beginPath();
        ctx.moveTo(-90,-180);
        ctx.arc(-90,-170,10,-Math.PI/2,-Math.PI,true);
        ctx.lineTo(-100,-170);
        ctx.lineTo(-100,-80);
        ctx.lineTo(-10,-40);
        ctx.lineTo(10,-40);
        ctx.lineTo(100,-80);
        ctx.lineTo(100,-170);
        ctx.arc(90,-170,10,0,-Math.PI/2,true);
        ctx.lineTo(90,-180);
        ctx.lineTo(-90,-180);
        ctx.closePath();
        ctx.strokeStyle="black";
        ctx.stroke();

        // 用上面的轮廓去剪切下面的三色块
        ctx.clip();        

        // 三色块
        ctx.fillStyle="white";
        ctx.fillRect(-100,-180,200,140);
        ctx.fillStyle="red";
        ctx.fillRect(-100,-180,40,140);
        ctx.fillStyle="blue";
        ctx.fillRect(-40,-180,80,140);
        ctx.fillStyle="red";
        ctx.fillRect(60,-180,40,140);

        ctx.restore();

        // 折角渐变部分
        var gnt=ctx.createLinearGradient(-100,-170,-100,-80);
        gnt.addColorStop(0,"rgba(255,255,255,0.1)");
        gnt.addColorStop(0.05,"rgba(233,233,233,0.3)");
        gnt.addColorStop(0.15,"rgba(200,200,200,0.2)");
        gnt.addColorStop(1,"rgba(255,255,255,0.1)");
        ctx.fillStyle=gnt;
        ctx.fillRect(-100,-170,200,90);

        ctx.beginPath();
        ctx.arc(0,-28,10,0,Math.PI*2,true);
        ctx.closePath();
        ctx.strokeStyle="rgb(177,121,46)";
        ctx.stroke();

        //--- 以下为勋章部分
        // 外圈六角星底
        ctx.beginPath();
        var arr=getSixStarArray(0,100,120);
        for(var i=0;i<arr.length;i++){
            ctx.lineTo(arr[i].x,arr[i].y);
        }
        ctx.closePath();
        ctx.lineWidth=4;
        ctx.strokeStyle="yellow";
        ctx.stroke();
        var gnt2=ctx.createLinearGradient(0,20,0,220);        
        gnt2.addColorStop(0,"rgb(212,171,29)");
        gnt2.addColorStop(1,"rgb(116,82,36)");
        ctx.fillStyle=gnt2;
        ctx.fill();

        // 内圈
        ctx.beginPath();
        var arr=getSixStarArray(0,100,90);
        for(var i=0;i<arr.length;i++){
            ctx.lineTo(arr[i].x,arr[i].y);
        }
        ctx.closePath();
        ctx.fillStyle="yellow";
        ctx.fill();

        // 带明暗效果的六角星
        var flag=true;
        var arr=getSixStarArray(0,100,88);
        var colors=["rgb(213,163,32)","rgb(251,220,51)","rgb(204,149,23)",
                    "rgb(232,190,26)","rgb(233,191,53)","rgb(221,181,23)",                    
                    "rgb(250,233,70)","rgb(255,233,98)","rgb(186,144,32)",
                    "rgb(169,126,34)","rgb(216,177,22)","rgb(144,106,35)",
                    ];
        for(var i=0;i<arr.length;i++){
            ctx.beginPath();
            ctx.lineTo(0,100);
            ctx.lineTo(arr[i].x,arr[i].y);
            ctx.lineTo(arr[i+1].x,arr[i+1].y);
            ctx.closePath();
            ctx.fillStyle=flag?"rgb(255,233,98)":"rgb(186,144,32)";
            flag=!flag;
            ctx.fill();
        }
    }

    // 画前景
    this.paintFg=function(ctx){
        
    }
}

//-----------------------------------
// 函数:得到大卫六角星的顶点数组
// x:横坐标
// y:纵坐标
// radius:大卫星的顶点半径
//-----------------------------------
function getSixStarArray(x,y,radius){
    var arr=[];

    var innerRadius=radius/1.732;
    for(var i=0;i<=12;i++){
        var theta=i*Math.PI/6+Math.PI/6;
        var point={};

        if(i%2==0){
            point.x=radius*Math.cos(theta);
            point.y=radius*Math.sin(theta);
        }else{
            point.x=innerRadius*Math.cos(theta);
            point.y=innerRadius*Math.sin(theta);
        }

        point.x+=x;
        point.y+=y;

        arr.push(point);
    }

    return arr;
}


/*---------------------------------------------
在疲劳时给自己加杯咖啡,
在懈怠时看看励志的文章,
在工作家庭琐事烦扰时吃点忘忧散,
在目标遥遥无期时哼哼歌前进。
----------------------------------------------*/
//-->
</script>

END

 

posted @ 2014-07-27 23:04  逆火狂飙  阅读(270)  评论(0编辑  收藏  举报
生当作人杰 死亦为鬼雄 至今思项羽 不肯过江东