zoukankan      html  css  js  c++  java
  • canvas 水滴图、液体进度条、仿加速球、圆球水波图

    效果如图

    代码如下:

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <title>test</title>
        <style>
            body {
            display: flex;
            flex-flow: column wrap;
            justify-content: center;
            align-items: center;
          }
          #c {
            margin-top: 20px;      
          }
          input[type=range]::before {content: attr(min);  color: #000; padding-right: 5px;}
          input[type=range]::after { content: attr(max); color: #000; padding-left: 5px;}
        </style>
    </head>
    
    <body>
        <canvas id="c">当前浏览器不支持canvas 请升级!</canvas>
        <input type="range" name="range" min="0" max="100" step="1">
    </body>
    <script>
    let canvas = document.getElementById("c")
    let ctx = canvas.getContext("2d")
    let oRange = document.getElementsByName("range")[0];
    let M = Math
    let Sin = M.sin
    let Cos = M.cos
    let Sqrt = M.sqrt
    let Pow = M.pow
    let PI = M.PI
    let Round = M.round
    let oW = canvas.width = 250
    let oH = canvas.height = 250
    let lineWidth = 2 // 线宽
    let r = (oW / 2) // 大半径
    let cR = r - 10 * lineWidth
    ctx.beginPath()
    ctx.lineWidth = lineWidth
    
    // 水波动画初始参数
    let axisLength = 2 * r - 16 * lineWidth // Sin 图形长度
    let unit = axisLength / 9 // 波浪宽
    let range = .4 // 浪幅
    let nowrange = range
    let xoffset = 8 * lineWidth // x 轴偏移量
    let data = ~~(oRange.value) / 100 // 数据量
    let sp = 0 // 周期偏移量
    let nowdata = 0
    let waveupsp = 0.006 // 水波上涨速度
    
    // 圆动画初始参数
    let arcStack = [] // 圆栈
    let bR = r - 8 * lineWidth
    let soffset = -(PI / 2) // 圆动画起始位置
    let circleLock = true // 起始动画锁
    
    // 获取圆动画轨迹点集
    for (var i = soffset; i < soffset + 2 * PI; i += 1 / (8 * PI)) {
        arcStack.push([
            r + bR * Cos(i),
            r + bR * Sin(i)
        ])
    }
    // 圆起始点
    let cStartPoint = arcStack.shift();
    ctx.strokeStyle = "#1c86d1";
    ctx.moveTo(cStartPoint[0], cStartPoint[1]);
    // 开始渲染
    render();
    
    function drawSine() {
        ctx.beginPath();
        ctx.save();
        var Stack = []; // 记录起始点和终点坐标
        for (var i = xoffset; i <= xoffset + axisLength; i += 20 / axisLength) {
            var x = sp + (xoffset + i) / unit;
            var y = Sin(x) * nowrange;
            var dx = i;
            var dy = 2 * cR * (1 - nowdata) + (r - cR) - (unit * y);
            ctx.lineTo(dx, dy);
            Stack.push([dx, dy])
        }
        // 获取初始点和结束点
        var startP = Stack[0]
        var endP = Stack[Stack.length - 1]
        ctx.lineTo(xoffset + axisLength, oW);
        ctx.lineTo(xoffset, oW);
        ctx.lineTo(startP[0], startP[1])
        ctx.fillStyle = "#fbec99";
        ctx.fill();
        ctx.restore();
    }
    
    function drawText() {
        ctx.globalCompositeOperation = 'source-over';
        var size = 0.4 * cR;
        ctx.font = 'bold ' + size + 'px Microsoft Yahei';
        let txt = (nowdata.toFixed(2) * 100).toFixed(0) + '`%';
        var fonty = r + size / 2;
        var fontx = r - size * 0.8;
        ctx.fillStyle = "#f6b71e";
        ctx.textAlign = 'center';
        ctx.fillText(txt, r + 5, r + 20)
    }
    //最外面淡黄色圈
    function drawCircle() {
        ctx.beginPath();
        ctx.lineWidth = 15;
        ctx.strokeStyle = '#fff89d';
        ctx.arc(r, r, cR + 7, 0, 2 * Math.PI);
        ctx.stroke();
        ctx.restore();
    }
    //灰色圆圈
    function grayCircle() {
        ctx.beginPath();
        ctx.lineWidth = 10;
        ctx.strokeStyle = '#eaeaea';
        ctx.arc(r, r, cR - 5, 0, 2 * Math.PI);
        ctx.stroke();
        ctx.restore();
        ctx.beginPath();
    }
    //橘黄色进度圈
    function orangeCircle() {
        ctx.beginPath();
        ctx.strokeStyle = '#fbdb32';
        //使用这个使圆环两端是圆弧形状
        ctx.lineCap = 'round';
        ctx.arc(r, r, cR - 5, 0 * (Math.PI / 180.0) - (Math.PI / 2), (nowdata * 360) * (Math.PI / 180.0) - (Math.PI / 2));
        ctx.stroke();
        ctx.save()
    }
    //裁剪中间水圈
    function clipCircle() {
        ctx.beginPath();
        ctx.arc(r, r, cR - 10, 0, 2 * Math.PI, false);
        ctx.clip();
    }
    //渲染canvas
    function render() {
        ctx.clearRect(0, 0, oW, oH);
        //最外面淡黄色圈
        drawCircle();
        //灰色圆圈  
        grayCircle();
        //橘黄色进度圈
        orangeCircle();
        //裁剪中间水圈  
        clipCircle();
        // 控制波幅
        oRange.addEventListener("change", function() {
            data = ~~(oRange.value) / 100;
        }, 0);
        if (data >= 0.85) {
            if (nowrange > range / 4) {
                var t = range * 0.01;
                nowrange -= t;
            }
        } else if (data <= 0.1) {
            if (nowrange < range * 1.5) {
                var t = range * 0.01;
                nowrange += t;
            }
        } else {
            if (nowrange <= range) {
                var t = range * 0.01;
                nowrange += t;                                                                                          
            }
            if (nowrange >= range) {
                var t = range * 0.01;
                nowrange -= t;
            }
        }
        if ((data - nowdata) > 0) {
            nowdata += waveupsp;
        }
        if ((data - nowdata) < 0) {
            nowdata -= waveupsp
        }
        sp += 0.07;
        // 开始水波动画
        drawSine();
        // 写字
        drawText();
        requestAnimationFrame(render)
    }
    </script>
    

    传送门:https://github.com/guoyoujin/WaterMoire
    传送门:https://www.cnblogs.com/CyLee/p/10591011.html

  • 相关阅读:
    vue-fullcalendar插件
    iframe 父框架调用子框架的函数
    关于调试的一点感想
    hdfs 删除和新增节点
    hadoop yarn 实战错误汇总
    Ganglia 安装 No package 'ck' found
    storm on yarn(CDH5) 部署笔记
    spark on yarn 安装笔记
    storm on yarn安装时 提交到yarn失败 failed
    yarn storm spark
  • 原文地址:https://www.cnblogs.com/smart-girl/p/11242572.html
Copyright © 2011-2022 走看看