canvas画多圈数据和点击下载事件

来源:互联网 发布:淘宝直通车怎么测图 编辑:程序博客网 时间:2024/06/03 17:52
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        *{
            margin:0;
            padding:0;
        }
        html,body{
            width:100%;
            height:100%;
        }
        #canvas{
            position:relative;
            margin:0 auto;
        }
    </style>
    <script>
        /* requestAnimationFrame.js
         * by zhangxinxu 2013-09-30
        */
        (function() {
            var lastTime = 0;
            var vendors = ['webkit', 'moz','ms','o'];
            for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
                window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame'];
                window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] ||    // name has changed in Webkit
                                              window[vendors[x] + 'CancelRequestAnimationFrame'];
            }
            if (!window.requestAnimationFrame) {
                window.requestAnimationFrame = function(callback, element) {
                    var currTime = new Date().getTime();
                    var timeToCall = Math.max(0, 16.7 - (currTime - lastTime));
                    var id = window.setTimeout(function() {
                        callback(currTime + timeToCall);
                    }, timeToCall);
                    lastTime = currTime + timeToCall;
                    return id;
                };
            }
            if (!window.cancelAnimationFrame) {
                window.cancelAnimationFrame = function(id) {
                    clearTimeout(id);
                };
            }
        }());
    </script>
</head>
<body>
    <div id="canvas" style="width:500px;height:500px;"></div>
</body>
</html>
<script>
    var jquery = (function(){
        var $ = function(id){
            return document.getElementById(id) || id;
        };
        return $;
    }());


    var test = (function($){
        var extend = function(target,source){
            for(var key in source){
                if(key in target){
                    target[key] = source[key];
                }
            }
            return target;
        }
        var getPosition = function(ev){    //获取当前鼠标的坐标
            var x, y;  
            if (ev.layerX || ev.layerX == 0) {  
                x = ev.layerX;  
                y = ev.layerY;  
            } else if (ev.offsetX || ev.offsetX == 0) { // Opera  
                x = ev.offsetX;  
                y = ev.offsetY;  
            }  
            return {x: x, y: y};  
        }
        /**
         * 获取mimeType
         * @param  {String} type the old mime-type
         * @return the new mime-type
         */
        var _fixType = function(type) {  //获取图片的mime类型
            type = type.toLowerCase().replace(/jpg/i, 'jpeg');
            var r = type.match(/png|jpeg|bmp|gif/)[0];
            return 'image/' + r;
        };
        /**
         * 在本地进行文件保存
         * @param  {String} data     要保存到本地的图片base64数据
         * @param  {String} filename 文件名
         */
        var saveFile = function(data, filename){
            var save_link = document.createElementNS('http://www.w3.org/1999/xhtml', 'a');
            save_link.href = data;
            save_link.download = filename;
           
            var event = document.createEvent('MouseEvents');
            event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
            save_link.dispatchEvent(event);
        };




        var addEvent = function(obj,event,func){
            //addEventListener中的第三个参 数是useCapture, 一个bool类型。当为false时为冒泡获取(由里向外),true为capture方式(由外向里)。
            obj.addEventListener ? obj.addEventListener(event,func,false) : obj.attachEvent("on"+event,function(){func.call(obj);});
        }


        var init = function(opt){
            this.option = {
                element : null,


            }
            
            extend(this.option,opt);
            this.initialize();
        }
        init.prototype = {
            initialize : function(){
                this.canvas = this.createcanvas();
                this.ctx = this.canvas.getContext("2d");
                this.reset();
                this.render();  //渲染
            },
            render : function(){
                this.ctx.save();
                this.ctx.fillStyle = "#273341";
                this.ctx.fillRect(0,0,this.canvas.width,this.canvas.height);
                this.ctx.restore();  //绘制背景


                this.drawCircle(0,360,this.rotate1,"#323d4b");  //外彩色扇形背景圆


                this.drawCircle(0,30,this.rotate1,"#4c17e2");  //外彩色扇形圆
                this.drawCircle(45,55,this.rotate1,"#1777e2");  //外彩色扇形圆
                this.drawCircle(90,110,this.rotate1,"#17cde2");  //外彩色扇形圆
                this.drawCircle(135,146,this.rotate1,"#3fc371");  //外彩色扇形圆
                this.drawCircle(180,198,this.rotate1,"#ffbc3a");  //外彩色扇形圆
                this.drawCircle(225,231,this.rotate1,"#e27217");  //外彩色扇形圆
                this.drawCircle(270,290,this.rotate1,"#e217a1");  //外彩色扇形圆
                this.drawCircle(315,335,this.rotate1,"#b017e2");  //外彩色扇形圆


                this.drawCircle(0,360,this.rotate1-(this.canvas.width/15),"#273341"); //内覆盖扇形背景圆


                this.drawCircle(0,45,this.rotate2,"#4c17e2");  //内彩色扇形圆
                this.drawCircle(45,90,this.rotate2,"#1777e2");  //内彩色扇形圆
                this.drawCircle(90,135,this.rotate2,"#17cde2");  //内彩色扇形圆
                this.drawCircle(135,180,this.rotate2,"#3fc371");  //内彩色扇形圆
                this.drawCircle(180,225,this.rotate2,"#ffbc3a");  //内彩色扇形圆
                this.drawCircle(225,270,this.rotate2,"#e27217");  //内彩色扇形圆
                this.drawCircle(270,315,this.rotate2,"#e217a1");  //内彩色扇形圆
                this.drawCircle(315,360,this.rotate2,"#b017e2");  //内彩色扇形圆


                this.drawCircle(0,360,this.rotate1-(this.canvas.width/6),"#273341"); //内覆盖扇形背景圆


                this.drawLine(0,this.canvas.width/2,this.canvas.width,this.canvas.width/2);  //交叉背景线
                this.drawLine(this.canvas.width/2,0,this.canvas.width/2,this.canvas.width);  //交叉背景线
                this.drawLine(0,0,this.canvas.width,this.canvas.width);  //交叉背景线
                this.drawLine(this.canvas.width,0,0,this.canvas.width);  //交叉背景线


                // this.drawCircle(0,45,this.rotate2,"#4c17e2");


                this.drawText("注册",18,28,"center",this.smcircle.radius);  //内圆的文字,开始角度,结束角度,水平对齐,半径
                this.drawText("登录中",53,83,"center",this.smcircle.radius); //内圆的文字,开始角度,结束角度,水平对齐,半径
                this.drawText("登录人员",97,127,"center",this.smcircle.radius); //内圆的文字,开始角度,结束角度,水平对齐,半径
                this.drawText("登录",152,162,"center",this.smcircle.radius); //内圆的文字,开始角度,结束角度,水平对齐,半径
                this.drawText("操作",197,207,"center",this.smcircle.radius); //内圆的文字,开始角度,结束角度,水平对齐,半径
                this.drawText("管理员",238,258,"center",this.smcircle.radius); //内圆的文字,开始角度,结束角度,水平对齐,半径
                this.drawText("后台管理",277,308,"center",this.smcircle.radius); //内圆的文字,开始角度,结束角度,水平对齐,半径
                this.drawText("运营数据",322,353,"center",this.smcircle.radius); //内圆的文字,开始角度,结束角度,水平对齐,半径


                this.drawText("60.5%",24,38,"center",this.circle.radius-(this.canvas.width/4.2));  //外圆的文字,开始角度,结束角度,水平对齐,半径
                this.drawText("17.8%",70,83,"center",this.circle.radius-(this.canvas.width/4.2)); //外圆的文字,开始角度,结束角度,水平对齐,半径
                this.drawText("    6",100,128,"center",this.circle.radius-(this.canvas.width/4.2)); //外圆的文字,开始角度,结束角度,水平对齐,半径
                this.drawText("  4.2.3",163,173,"center",this.circle.radius-(this.canvas.width/4.2)); //外圆的文字,开始角度,结束角度,水平对齐,半径
                this.drawText(" 1570",208,218,"center",this.circle.radius-(this.canvas.width/4.2)); //外圆的文字,开始角度,结束角度,水平对齐,半径
                this.drawText(" 21.6",253,263,"center",this.circle.radius-(this.canvas.width/4.2)); //外圆的文字,开始角度,结束角度,水平对齐,半径
                this.drawText("17.1%",294,308,"center",this.circle.radius-(this.canvas.width/4.2)); //外圆的文字,开始角度,结束角度,水平对齐,半径
                this.drawText("55.5%",339,353,"center",this.circle.radius-(this.canvas.width/4.2)); //外圆的文字,开始角度,结束角度,水平对齐,半径


                this.addEventDownload();  //添加下载事件


            },
            addEventDownload : function(){  
                var _this = this;
                _this.drawDownloadText();  //绘制下载字样


                addEvent(this.canvas,"mousemove",function(e){  //给矩形添加鼠标移动事件
                    var target = getPosition(e);  //获取鼠标点击的坐标
                    // console.log(target);
                    if(_this.ctx.isPointInPath(target.x,target.y)){  //如果在矩形里面


                        _this.canvas.style.cursor = "pointer";  //将鼠标变成 手指形状
                    }else{
                        _this.canvas.style.cursor = "default";


                    }
                })
                
                addEvent(this.canvas,"click",function(e){  //给矩形添加点击事件
                    var target = getPosition(e);  //获取鼠标点击的坐标
                    // console.log(target);
                    if(_this.ctx.isPointInPath(target.x,target.y)){  //如果在矩形里面
                        //把下载的字样隐藏
                        _this.ctx.save();
                        _this.ctx.fillStyle = "#273341";
                        _this.ctx.rect(_this.canvas.width-135,0,125,25);  
                        _this.ctx.fill();
                        _this.ctx.restore();


                        // 图片导出为 png 格式
                        var type = 'png';
                        var imgData = _this.canvas.toDataURL(type);  //获取canvas的图片base64数据


                        _this.drawDownloadText();  //重新绘制下载字样


                        // 加工image data,替换mime type
                        imgData = imgData.replace(_fixType(type),'image/octet-stream');


                        // 下载后的问题名
                        var filename = 'baidufe_' + (new Date()).getTime() + '.' + type;
                        // download
                        saveFile(imgData,filename);
                    }
                });


            },
            drawDownloadText : function(){
                this.ctx.save();
                this.ctx.fillStyle = "white";
                this.ctx.font = "20px 微软雅黑";
                this.ctx.textAlign = "center";
                this.ctx.textBaseline = "middle";
                this.ctx.translate(this.canvas.width-75,12);
                this.ctx.fillText("点击这里下载",0,0);
                this.ctx.restore();  //创建下载字样


                this.ctx.save();
                // this.ctx.fillStyle = "black";
                this.ctx.rect(this.canvas.width-135,0,125,25);  //创建一个矩形覆盖在文字上,因为事件只能获取矩形的坐标
                // this.ctx.fill();
                this.ctx.restore();
            },


            drawText : function(a,b,c,d,radius){   //参数: 输出的字符串 , 开始角度 , 结束角度 , textAlign
                var angleMinus = (b*Math.PI/180-c*Math.PI/180)/(a.length-1),
                angle = parseFloat(b*Math.PI/180),
                index = 0,
                character;


                while(index < a.length){
                    this.ctx.save();
                    this.ctx.fillStyle = "white";
                    this.ctx.font = "20px 微软雅黑";
                    this.ctx.textAlign = d;
                    this.ctx.textBaseline = "middle";
                    character = a.charAt(index);
                    this.ctx.beginPath();  
                    this.ctx.translate(
                        this.smcircle.x+Math.cos(angle)*radius,
                        this.smcircle.y+Math.sin(angle)*radius,
                    );  //平移
                    this.ctx.rotate(Math.PI/2 + angle);  //旋转
                    this.ctx.fillText(character,0,0);
                    angle -= angleMinus;
                    index++;
                    this.ctx.closePath();
                    this.ctx.restore();
                }
            },
            drawLine : function(a,b,c,d){  //参数: 起始坐标x , 起始坐标y , 结束坐标 x, 结束坐标 y
                this.ctx.save();
                this.ctx.beginPath();
                this.ctx.moveTo(a,b);  //起始坐标
                this.ctx.lineTo(c,d);  //终点坐标
                this.ctx.strokeStyle = "#273341";
                this.ctx.closePath();
                this.ctx.lineWidth = 10;  //线条粗细
                this.ctx.stroke();
                this.ctx.restore();
            },
            drawCircle : function(a,b,r,color){   //参数: 起始度数,结束度数,半径,颜色
                this.ctx.save();
                this.ctx.beginPath();
                this.ctx.fillStyle = color;
                this.ctx.moveTo(this.circle.x,this.circle.y);
                this.ctx.arc(this.circle.x,this.circle.y,r,a*Math.PI/180,b*Math.PI/180,false);
                this.ctx.closePath();
                // this.ctx.stroke();  //stroke是线条颜色   ,
                this.ctx.fill();  //fill是填充颜色   ,
                this.ctx.restore();
            },
            reset : function(){
                this.rotate1 = this.canvas.width/2;
                this.rotate2 = this.rotate1-(this.canvas.width/10);
                this.circle = {
                    x:this.canvas.width/2,
                    y:this.canvas.height/2,
                    radius:Math.sqrt(Math.pow(this.canvas.width,2)+Math.pow(this.canvas.height,2))/2
                };
                this.smcircle = {
                    x:this.circle.x,
                    y:this.circle.y,
                    radius:this.rotate1-(this.canvas.width/7.5)
                };


            },
            createcanvas : function(){
                var canvas = document.createElement("CANVAS");
                canvas.innerHTML = "您的浏览器不支持canvas,赶紧换一个吧!";
                $(this.option.element).appendChild(canvas);
                canvas.width = parseInt($(this.option.element).style.width);
                canvas.height = parseInt($(this.option.element).style.height);
                return canvas;
            }
        }
        return init;  //暴露一个方法给调用


    }(jquery || {}));


    window.onload = function(){
        var option = {
            element : "canvas"
        }
        new test(option);  //初始化test类
    }


</script>