6.2.1_描边与填充绘制器

6.2.1_描边与填充绘制器

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>描边与填充绘制器-使用精灵</title>
        <style>
            body{
                background: #ddd;
            }
            #canvas{
                background: #fff;
                cursor: pointer;
                margin: 10px;
                -webkit-box-shadow: 3px 3px 6px rgba(0,0,0,0.5);
                -moz-box-shadow: 3px 3px 6px rgba(0,0,0,0.5);
                box-shadow: 3px 3px 6px rgba(0,0,0,0.5);
            }
        </style>
    </head>
    <body>
        <canvas id="canvas" width="600" height="600"></canvas>
    </body>
    <!-- 精灵对象 -->
    <script>
        var Sprite = function(name,painter,behaviors){
            if(name !== undefined){ this.name = name; }
            if(painter !== undefined){ this.painter = painter; }

            this.top = 0;
            this.left = 0;
            this.width = 10;
            this.height = 10;
            this.velocityX = 0;
            this.velocityY = 0;
            this.visible = true;
            this.animating = false;
            this.behaviors = behaviors || [];

        }

        Sprite.prototype = {
            paint:function(context){
                if(this.painter !== undefined && this.visible){
                    this.painter.paint(this,context);
                }
            },
            update:function(context,time){
                for(var i=0;i<this.behaviors.length;i++){
                    this.behaviors[i].execute(this,context,time);
                }
            }
        }
    </script>
    <!-- 
        享元模式:使用一个对象来表示多个概念,就是享元模式。
              如本例只有一个实例的bll的精灵对象,但是确绘制了三个表针及表盘中心

    -->
    <script>
        var canvas = document.getElementById('canvas');
        var context = canvas.getContext('2d');

        var clock_radius = canvas.width/2 - 15;
        var hour_hand_truncation = 35;

        var ballPainter = {
            paint:function(sprite,context){
                var x = sprite.left+sprite.width/2;
                var y = sprite.top + sprite.height/2;
                var width = sprite.width;
                var height = sprite.height;
                var radius = sprite.width/2;

                context.save();
                context.beginPath();
                context.arc(x,y,radius,0,Math.PI*2,false);
                context.clip();

                context.shadowColor = 'rgb(0,0,0)';
                context.shadowOffsetX = -4;
                context.shadowOffsetY = -4;
                context.shadowBlur = 8;

                context.fillStyle ='rgba(218,165,32,0.1)';
                context.fill();

                context.lineWidth = 2;
                context.strokeStyle = 'rgb(100,100,195)';
                context.stroke();

                context.restore();

            }
        }

        var ball = new Sprite('ball',ballPainter);

        //初始化
        context.lineWidth = 0.5;
        context.strokeStyle = 'rgba(0,0,0,0.2)';
        context.shadowColor = 'rgba(0,0,0,0.5)';
        context.shadowOffsetX = 2;
        context.shadowOffsetY = 2;
        context.shadowBlur = 4;

        drawGrid('lightgray',10,10);
        window.requestAnimationFrame(animate);



        function animate(){
            context.clearRect(0,0,canvas.width,canvas.height);
            drawGrid('lightgray',10,10);
            drawClock();
            window.requestAnimationFrame(animate);
        }

        //绘制表
        function drawClock(){
            drawClockFace();
            drawHands();
        }

        //绘制表针们
        function drawHands(){
            var date = new Date();
            var hour = date.getHours();

            //秒针
            ball.width = 20;
            ball.height =20;
            drawHand(date.getSeconds(),false);

            //分针

            context.save();
            context.lineWidth =1;
            ball.width = 30;
            ball.height = 30;
            drawHand(date.getMinutes(),false);
            context.restore();

            //时针
            context.save();
            context.lineWidth =2;
            hour = hour>12? hour-12:hour;
            ball.width = 40;
            ball.height = 40;
            drawHand(hour*5 + (date.getMinutes()/60)*5,true);
            context.restore();

            //表心
            ball.width = 10;
            ball.height = 10;
            ball.left = canvas.width/2 - ball.width/2;
            ball.top = canvas.height/2 - ball.height/2;
            ballPainter.paint(ball,context);
        }

        //绘制表针
        function drawHand(time,isHour){
            var angle = (Math.PI*2)*time/60 - Math.PI/2;
            var handRudius = isHour? clock_radius - hour_hand_truncation:clock_radius;

            lineEnd = { //线与球的交汇处
                x:canvas.width/2+Math.cos(angle)*(handRudius - ball.width/2),
                y:canvas.height/2+Math.sin(angle)*(handRudius - ball.width/2)
            };

            context.beginPath();
            context.moveTo(canvas.width/2,canvas.height/2);
            context.lineTo(lineEnd.x,lineEnd.y);
            context.stroke();

            ball.left = canvas.width/2 + Math.cos(angle)*handRudius - ball.width/2;
            ball.top = canvas.height/2 +Math.sin(angle)*handRudius - ball.height/2;

            ball.paint(context);
        }
        //绘制表盘
        function drawClockFace(){
            context.beginPath();
            context.arc(canvas.width/2,canvas.height/2,clock_radius,0,Math.PI*2,false);
            context.save();
            context.strokeStyle = 'rgba(0,0,0,0.2)';
            context.stroke();
            context.restore();
        }

        //网格线
        function drawGrid(color, stepX, stepY) {
            context.save();
            context.shadowColor = undefined;
            context.shadowOffsetX = 0;
            context.shadowOffsetY = 0;
            context.shadowBlur = 0;

            context.strokeStyle = color;
            context.lineWidth = 0.5;
            context.fillStyle = '#fff';
            context.fillRect(0, 0, canvas.width, canvas.height);

            for(var i = stepX + 0.5; i < context.canvas.width; i += stepX) {
                context.beginPath();
                context.moveTo(i, 0);
                context.lineTo(i, context.canvas.height);
                context.stroke();
            }

            for(var i = stepY + 0.5; i < context.canvas.height; i += stepY) {
                context.beginPath();
                context.moveTo(0, i);
                context.lineTo(context.canvas.width, i);
                context.stroke();
            }
            context.restore();
        }
    </script>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值