Bruce个人博客

canvas-konva行星旋转案例

创建时间:2018-2-22 22:13:31 -最后修改时间:2018-2-22 22:13:31 -阅读:24 -评论:0

具体讲解:在stage上面绘制一个背景层和一个运动层,背景层保持不变,运动层会随着Animation设置的而运动,而且当鼠标经过运动层的圆圈时,运动速度会明显变慢,鼠标移开后,立马恢复原来运动速度。CSS3和HTML5放入一组中,该所属组顺时针旋转,JS所属组逆时针旋转;字体随着运动,自身反向旋转便能使其永远朝上显示。

demo-在线查看效果

实现代码

    var stage=new Konva.Stage({//创建舞台
        container:'container',
        width:window.innerWidth,
        height:window.innerHeight
    });
    //背景层
    var bgLayer=new Konva.Layer();
    stage.add(bgLayer);
    //开始创建圆形
    //中心点坐标
    var centX=stage.width()/2;
    var centY=stage.height()/2;
    //圆形的半径
    var innerRadius=126;
    var outerRadius=220;
    //虚线圆环
    var innerCircle=new Konva.Circle({
        x:centX,
        y:centY,
        radius:innerRadius,
        stroke:'#ccc',
        strokeWidth:4,
        dash: [10,4],//虚线
    });
    var outerCircle=new Konva.Circle({
        x:centX,
        y:centY,
        radius:outerRadius,
        stroke:'#ccc',
        strokeWidth:4,
        dash: [10,4],
    });
    bgLayer.add(innerCircle);
    bgLayer.add(outerCircle);
    //中心蓝色的圆圈
    var cenCircleText=new CircleText({
        x:centX,
        y:centY,
        innerRadius: 70,//内环的半径
        outerRadius: 88,
        innerStyle:'#525A82',
        outerStyle:'#E1E1E1',
        text:'web全栈',
    });
    cenCircleText.addToGroupOrLayer(bgLayer);
    bgLayer.draw();

    //创建动画层,这一层会运动
    var animateLayer=new Konva.Layer();
    stage.add(animateLayer);
    //第二层添加黄色和pink色的圆圈
    //2层的动画
    var L2Group=new Konva.Group({
        x:centX,//这样设置后,L2Group的中心坐标为CentX,CentY,因此CSS3的X坐标为innerRadius*……
        y:centY,
    });
    var L2_CircleText_CSS3=new CircleText({
        x:innerRadius*Math.cos(-60*Math.PI/180),
        y:innerRadius*Math.sin(-60*Math.PI/180),
        innerRadius: 30,//内环的半径
        outerRadius: 40,
        innerStyle:'orange',
        outerStyle:'#E1E1E1',
        text:'CSS3',
    });
    L2_CircleText_CSS3.addToGroupOrLayer(L2Group);
    var L2_CircleText_HTML5=new CircleText({
        x:innerRadius*Math.cos(180*Math.PI/180),
        y:innerRadius*Math.sin(180*Math.PI/180),
        innerRadius: 30,//内环的半径
        outerRadius: 40,
        innerStyle:'pink',
        outerStyle:'#E1E1E1',
        text:'HTML5',
    });
    L2_CircleText_HTML5.addToGroupOrLayer(L2Group);
    animateLayer.add(L2Group);
    //第三层的圆圈组装到一个组中
    var L3Group=new Konva.Group({
        x:centX,
        y:centY,
    });
    //第3层添加blue色的圆圈
    var L3_CircleText_JS=new CircleText({
        x:outerRadius*Math.cos(60*Math.PI/180),
        y:outerRadius*Math.sin(60*Math.PI/180),
        innerRadius: 40,//内环的半径
        outerRadius: 50,
        innerStyle:'#91BFF8',
        outerStyle:'#E1E1E1',
        text:'JS',
    });
    L3_CircleText_JS.addToGroupOrLayer(L3Group);
    //第3层添加blue色的圆圈
    var L3_CircleText_JQuery=new CircleText({
        x:outerRadius*Math.cos(240*Math.PI/180),
        y:outerRadius*Math.sin(240*Math.PI/180),
        innerRadius: 40,//内环的半径
        outerRadius: 50,
        innerStyle:'#DD7FB2',
        outerStyle:'#E1E1E1',
        text:'JQuery',
    });
    L3_CircleText_JQuery.addToGroupOrLayer(L3Group);
    animateLayer.add(L3Group);
    animateLayer.draw();

    //Konva的帧动画系统
    var rotateAnglePerSecond=60;//每秒钟旋转的角度
    var animate=new Konva.Animation(function(frame){
        //相当于setInterval;每隔一段时间执行该方法;此方法更加智能
        //计算当前帧需要旋转的角度,
        var rotateAngle=rotateAnglePerSecond*frame.timeDiff/1000;//timeDiff:两次执行的时间差;是动态变化的,根据浏览器性能变化旋转速度,上一帧和当前帧的时间差
        // var rotateAngle=2;
        //旋转的角度;每一帧旋转的角度
        L2Group.rotate(rotateAngle);//
        //让2层上面的所有圆自己自我反向旋转,以便字体永远正向朝上
        L2Group.getChildren().each(function(item,index){//获得所有子元素
            item.rotate(-rotateAngle);
        });
        L3Group.rotate(-rotateAngle);
        L3Group.getChildren().each(function(item,index){
            item.rotate(rotateAngle);
        });
    },animateLayer);//此处表示
    animate.start();
    //Konva事件系统
    animateLayer.on('mouseover',function(){
        rotateAnglePerSecond=10;
    });
    animateLayer.on('mouseout',function(){
        rotateAnglePerSecond=60;
    })

以面向过程的方式分装

注意:这个必须先引用


    function CircleText(option){
        this._init(option);
    }
    CircleText.prototype={
        _init:function(option){
            this.x=option.x||0;
            this.y=option.y||0;
            this.innerRadius=option.innerRadius||0;//内圆半径
            this.outerRadius=option.outerRadius||0;//圆环半径
            this.innerStyle=option.innerStyle||'red';//内部圆颜色
            this.outerStyle=option.outerStyle||'blue'//圆环颜色
            this.text=option.text||'canvas';//填充文字
            //让内圆,圆环,字体在一个组中,便于管理
            this.group=new Konva.Group({
                x:this.x,
                y:this.y,
            });
            //初始化一个内圆
            var innerCircle=new Konva.Circle({
                x:0,
                y:0,
                radius:this.innerRadius,
                fill:this.innerStyle,
                opacity:.7
            });
            this.group.add(innerCircle);
            //初始化一个圆环
            var outerRing=new Konva.Ring({
                x:0,
                y:0,
                innerRadius:this.innerRadius,
                outerRadius:this.outerRadius,
                fill:this.outerStyle,
                opacity:.4
            });
            this.group.add(outerRing);
            //初始化一个文字
            var text=new Konva.Text({
                x:0-this.outerRadius,
                y:-7,
                width:this.outerRadius*2,
                fill:'#fff',
                text:this.text,
                align:'center',
                fontSize:17,
                fontFamily: '微软雅黑',
                fontStyle:'bold'
            });
            this.group.add(text);
        },
        addToGroupOrLayer:function(arg){
            arg.add(this.group);
        }
    }

评论