• Canvas统计图表(多边形,蜘蛛网,渐变色)


        let c = document.getElementById("myc");
        let ctx = c.getContext("2d");
    
        // 随机值记录
        let randomRes = [0, 0, 0, 0, 0, 0];
        //const randomRes = [3, 0, 0, 0, 0, 0];
        // 颜色值
        let COLOR_INIT = "#737373";
        // 单个梯形高度
        let onceHeight = 30;
    
        // 声明画布大小,及窗口文档的显示区的高度和宽度,以像素记
        c.width = 600;
        c.height = 600;
        // 将坐标原点移至画布中心
        ctx.translate(c.width/2,c.height/2);
        // r多边形半径,n多边形个数,deg:多边形与夹角的度数,layerCount:多边形层数
        let r=onceHeight, n=6, deg=360/n, layerCount=4;
        // 初始坐标点
        let prevPoint = {x: 0, y: r};
        // 初始渐变色层级点
        let prevLinearPoint = {x: 0, y: 0};
        // 渐变色坐标点记录
        let linearPointArray = [];
        // 指数结果坐标点记录
        let randomResPoint = [];
        // 上一个结果组
        let prevRandomRes = [];
        
        var mmm = ["CB2329", "1853B7", "C3253A", "7C0A20"];
        var mmmmm = 0;
        setInterval(() => {
            mmmmm === mmm.length && (mmmmm = 0);
            console.log(mmm[mmmmm++])
            setResult([getRandom(), getRandom(), getRandom(), getRandom(), getRandom(), getRandom()], ["粒子1", "粒子2", "粒子3", "粒子4", "粒子5", "粒子6"], mmm[mmmmm++]);
        }, 1500)
        
    
        /**
         * 设置结果
         * @param(randomResArr) array[int] 比例值 0-4
         * @param(textArr) array[string] 文字说明
         * @param(colorHex) string Hex基准颜色
         */
        function setResult(randomResArr, textArr, colorHex) {
            COLOR_INIT = colorHex;
            prevRandomRes = randomRes;
            randomRes = randomResArr;
            var timer = setInterval(() => {
                drawStatistics(textArr);
                console.log("run");
            }, 16);
            // 偷个懒
            setTimeout(() => {
                clearInterval(timer);
            }, 600);
        }
    
        function drawBg (textArr) {
            r = onceHeight;
            prevPoint = {x: 0, y: r};
            prevLinearPoint = {x: 0, y: 0};
            linearPointArray = [];
            randomResPoint = []; // 指数坐标点记录
            // 多边形线的颜色
            ctx.strokeStyle="#fff";
            // 多边形线的宽度
            ctx.lineWidth=1;
            ctx.globalAlpha = 1;
            ctx.globalCompositeOperation="destination-over";
    
            // 绘制多个线段
            for(let j=0;j<=layerCount;j++){
                // 恢复初始坐标点
                prevPoint = {x: 0, y: r};
                // 临时坐标变量
                let temporary = {};
    
                for(let i=1;i<=n;i++){
                    let currentLinearPoint = {x: angleDistance(r)*Math.sin(getrad((i*2-1)*(deg/2))), y: angleDistance(r)*Math.cos((i*2-1)*getrad(deg/2))};
                    let prevPointTemporary = {x: prevPoint.x, y: prevPoint.y};
                    let grd = null;
                    
                    try {
                        grd = ctx.createLinearGradient(linearPointArray[j-1][i-1].x, linearPointArray[j-1][i-1].y, currentLinearPoint.x, currentLinearPoint.y);
                    } catch (err) {
                        grd = ctx.createLinearGradient(0, 0, currentLinearPoint.x, currentLinearPoint.y);
                    }
    
                    linearPointArray[j] ? linearPointArray[j].push({x: currentLinearPoint.x, y: currentLinearPoint.y}) : linearPointArray[j] = [{x: currentLinearPoint.x, y: currentLinearPoint.y}];
                    
                    grd.addColorStop(0, getLightColor(COLOR_INIT, 0.6));
                    grd.addColorStop(1, getLightColor(COLOR_INIT, 0.9));
                    ctx.fillStyle = grd;
                    // 开始路径
                    ctx.beginPath();
                    ctx.moveTo(0,0);
                    ctx.lineTo(prevPoint.x, prevPoint.y);
                    prevPoint = {x: r*Math.sin(getrad(i*deg)), y: r*Math.cos(i*getrad(deg))};
                    ctx.lineTo(prevPoint.x, prevPoint.y);
                    // 结束路径
                    ctx.closePath();
                    // 绘制线段
                    ctx.stroke();
                    // 填充
                    ctx.fill();
    
                    switch (i) {
                        case 1:
                            if (j === randomRes[0]) {
                                temporary = {index: 1, x: prevPoint.x, y: prevPoint.y};
                                randomResPoint.push(temporary);
                            }
                            if (j === 4) {
                                ctx.beginPath();
                                ctx.fillStyle = "#333";
                                ctx.textBaseline = "top";
                                ctx.textAlign = "center";
                                ctx.fillText(textArr[0], prevPointTemporary.x, prevPointTemporary.y);
                                ctx.closePath();
                            }
                        break;
                        case 2:
                            if (j === randomRes[1]) {
                                temporary = {index: 2, x: prevPoint.x, y: prevPoint.y};
                                randomResPoint.push(temporary);
                            }
                            if (j === 4) {
                                ctx.beginPath();
                                ctx.fillStyle = "#333";
                                ctx.textBaseline = "middle";
                                ctx.textAlign = "left";
                                ctx.fillText(textArr[1], prevPointTemporary.x, prevPointTemporary.y);
                                ctx.closePath();
                            }
                        break;
                        case 3:
                            if (j === randomRes[2]) {
                                temporary = {index: 3, x: prevPoint.x, y: prevPoint.y};
                                randomResPoint.push(temporary);
                            }
                            if (j === 4) {
                                ctx.beginPath();
                                ctx.fillStyle = "#333";
                                ctx.textBaseline = "middle";
                                ctx.textAlign = "left";
                                ctx.fillText(textArr[2], prevPointTemporary.x, prevPointTemporary.y);
                                ctx.closePath();
                            }
                        break;
                        case 4:
                            if (j === randomRes[3]) {
                                temporary = {index: 4, x: prevPoint.x, y: prevPoint.y};
                                randomResPoint.push(temporary);
                            }
                            if (j === 4) {
                                ctx.beginPath();
                                ctx.fillStyle = "#333";
                                ctx.textBaseline = "bottom";
                                ctx.textAlign = "center";
                                ctx.fillText(textArr[3], prevPointTemporary.x, prevPointTemporary.y);
                                ctx.closePath();
                            }
                        break;
                        case 5:
                            if (j === randomRes[4]) {
                                temporary = {index: 5, x: prevPoint.x, y: prevPoint.y};
                                randomResPoint.push(temporary);
                            }
                            if (j === 4) {
                                ctx.beginPath();
                                ctx.fillStyle = "#333";
                                ctx.textBaseline = "middle";
                                ctx.textAlign = "right";
                                ctx.fillText(textArr[4], prevPointTemporary.x, prevPointTemporary.y);
                                ctx.closePath();
                            }
                        break;
                        case 6:
                            if (j === randomRes[5]) {
                                temporary = {index: 6, x: prevPoint.x, y: prevPoint.y};
                                randomResPoint.push(temporary);
                            }
                            if (j === 4) {
                                ctx.beginPath();
                                ctx.fillStyle = "#333";
                                ctx.textBaseline = "middle";
                                ctx.textAlign = "right";
                                ctx.fillText(textArr[5], prevPointTemporary.x, prevPointTemporary.y);
                                ctx.closePath();
                            }
                        break;
                        default :
                    }
                }
                // 递增层级半径
                r += onceHeight;
            }
        }
    
        function drawStatistics(textArr) {
            ctx.clearRect(-c.width / 2, -c.height / 2, c.width * 2, c.height * 2); // 清除画布
    
            // 画背景
            drawBg (textArr);
            // 画结果图
            let grdRadial=ctx.createRadialGradient(0,0,0,0,0,r);
            grdRadial.addColorStop(0,getLightColor(COLOR_INIT, 0.6));
            grdRadial.addColorStop(1,getDarkColor(COLOR_INIT, 0.3));
            // ctx.translate(c.width/2,c.height/2);
            ctx.globalCompositeOperation="source-over";
            ctx.lineWidth=2;
            ctx.strokeStyle=getLightColor(COLOR_INIT, 0.5);
            ctx.beginPath();
            ctx.fillStyle = grdRadial;
            ctx.globalAlpha = 0.8;
            let result = randomResPoint.sort((a, b) => (a.index - b.index));
    
    
            for(let randomIdx=0; randomIdx<result.length; randomIdx++) {
                let currentIncremnet = 0;
                if (prevRandomRes.length) {
                    prevRandomRes[randomIdx] += (randomRes[randomIdx] - prevRandomRes[randomIdx]) / 10;
                }
    
                randomIdx === 0 ? ctx.moveTo(
                    prevRandomRes.length ? 0 : result[randomIdx].x,
                    prevRandomRes.length ? (prevRandomRes[randomIdx]+1)*onceHeight : result[0].y
                ) : ctx.lineTo(
                    prevRandomRes.length ? ((prevRandomRes[randomIdx]+1)*onceHeight)*Math.sin(getrad(randomIdx*deg)) : result[randomIdx].x,
                    prevRandomRes.length ? ((prevRandomRes[randomIdx]+1)*onceHeight)*Math.cos(randomIdx*getrad(deg)) : result[randomIdx].y
                );
                
            }
            ctx.closePath();
            ctx.stroke();
            ctx.fill();
        }
    
        console.log("randomRes", randomRes);
        console.log(randomResPoint);
    
        // 封装求弧度的方法 度->弧度
        function getrad(deg){
            return deg/180*Math.PI;
        }
        // 封装计算渐变色倾斜角度
        function angleDistance(rAngle) {
            return rAngle*Math.cos(getrad(deg/2));
        }
        // 获取随机指数
        function getRandom() {
            return Math.floor(Math.random() * 5)
        }
    
        // hex颜色转rgb颜色
        function HexToRgb (str) {
            var r = /^#?[0-9A-F]{6}$/;
            // test方法检查在字符串中是否存在一个模式,如果存在则返回true,否则返回false
            if (!r.test(str)) return window.alert("输入错误的hex");
            // replace替换查找的到的字符串
            str = str.replace("#", "");
            // match得到查询数组
            var hxs = str.match(/../g);
            // alert('bf:'+hxs)
            for (var i = 0; i < 3; i++) hxs[i] = parseInt(hxs[i], 16);
            // alert(parseInt(80, 16))
            // console.log(hxs);
            return hxs;
        }
        // GRB颜色转Hex颜色
        function RgbToHex (a, b, c) {
            var r = /^d{1,3}$/;
            if (!r.test(a) || !r.test(b) || !r.test(c)) return window.alert("输入错误的rgb颜色值");
            var hexs = [a.toString(16), b.toString(16), c.toString(16)];
            for (var i = 0; i < 3; i++) if (hexs[i].length == 1) hexs[i] = "0" + hexs[i];
            return "#" + hexs.join("");
        }
    
        // 得到hex颜色值为color的加深颜色值,level为加深的程度,限0-1之间
        function getDarkColor(color, level) {
            var r = /^#?[0-9A-F]{6}$/;
            if (!r.test(color)) return window.alert("输入错误的hex颜色值");
            var rgbc = this.HexToRgb(color);
            // floor 向下取整
            for (var i = 0; i < 3; i++) rgbc[i] = Math.floor(rgbc[i] * (1 - level));
            return this.RgbToHex(rgbc[0], rgbc[1], rgbc[2]);
        }
        // 得到hex颜色值为color的减淡颜色值,level为加深的程度,限0-1之间
        function getLightColor(color, level) {
            var r = /^#?[0-9A-F]{6}$/;
            if (!r.test(color)) return window.alert("输入错误的hex颜色值");
            var rgbc = this.HexToRgb(color);
            for (var i = 0; i < 3; i++) rgbc[i] = Math.floor((255 - rgbc[i]) * level + rgbc[i]);
            return this.RgbToHex(rgbc[0], rgbc[1], rgbc[2]);
        }
  • 相关阅读:
    python 项目实例
    flash教程
    flask request
    systemd-unit
    kubernets HA集群手动部署
    zookeeper(1)-简单介绍
    apache与nginx原理
    技术文章整理
    CMS垃圾回收器
    Zookeeper
  • 原文地址:https://www.cnblogs.com/universe-cosmo/p/14638511.html
Copyright © 2020-2023  润新知