美文网首页
js实现圆角矩形(非canvas)

js实现圆角矩形(非canvas)

作者: 无明 | 来源:发表于2019-05-17 13:02 被阅读0次
    image

    代码

    <!DOCTYPE html>
    <html>
    
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title>矩形</title>
        <link rel="stylesheet" href="">
        <style>
            .juxing{
                /* 加上css会很奇怪-。-*/
                /* transition:all 0.1s ease-in; */
            }
        </style>
    </head>
    
    <body>
        <button type="button" onclick="start()">点击</button>
        <script>
        const len = 50;
        let array = [];
        let time = null;
    
        function start() {
            clearInterval(time);
            time = setInterval(() => {
                huanwei();
            }, 100);
        }
    
        function huanwei() {
            array.unshift(array.pop());
            var els = document.querySelectorAll('.juxing');
            for (let i = 0; i < len; i++) {
                let el = document.getElementById('ip' + (i + 1));
                if (array[i] && array[i].point) {
                    let point = array[i].point;
                    el.style.left = point.x + 'px';
                    el.style.top = point.y + 'px';
                }
            }
        }
    
        function createNode(name, p) {
            // 填充div
            let x = p.x;
            let y = p.y;
    
            var createDiv = document.createElement("div");
            // 动态
            createDiv.id = name;
            createDiv.style.left = p.x + 'px';
            createDiv.style.top = p.y + 'px';
            createDiv.innerHTML = name;
            // 固定
            if (name !== 'yuan') {
                // 存储非圆心的所有坐标点
                createDiv.className = "juxing"
                let obj = {
                    id: name,
                    point: { x: p.x, y: p.y }
                }
                array.push(obj);
            }
            createDiv.style.position = "absolute";
            createDiv.style.width = "30px";
            createDiv.style.height = "30px";
            createDiv.style.borderRadius = "30px";
            // border-radius: 30px;
            createDiv.style.background = "pink";
            createDiv.style.border = "1pxsolidred";
            document.body.appendChild(createDiv);
        }
    
        initNode({
            len: len,
            rectW: 400,
            rectH: 300,
            p: {
                x: 400,
                y: 200
            }
        });
    
        function initNode(params) {
            //初始化圆角矩形
    
            // 数量
            let len = params.len || 100;
            // 设置圆角矩形内矩形宽高 ,
            let rectW = params.rectW || 700;
            let rectH = params.rectH || 900;
            // 中心
            let cx = params.p.x || 0;
            let cy = params.p.y || 0;
    
            /*
             * 思路:圆角矩形可以看作一个矩形和左右两个半圆组成,半径为矩形的一半;
             * 圆周长+矩形两边的长度 / 总数量 计算出各边应该存放的小车数量,以此数量为基准判断该绘制哪一块;
             *
             * o = (180 / arcLenSplit) * Math.PI / 180
             * l=nπr/180 弧长公式
             * l = n(圆心角)× π(圆周率)× r(半径)/180=α(圆心角弧度数)× r(半径)
             * 这里的象限为4321,为(1,1),(1,-1),(-1,-1),(-1,1)
             * 
             */
    
    
    
            // 圆半径
            let radius = rectH / 2;
    
            // 两边弧长相等为
            let arcLength = Math.PI * radius;
            // 圆弧*2 + 矩形顶边底边长度除以总数量
            let split = ((arcLength * 2) + (rectW * 2)) / len;
            // 矩形边长可以存放数量,均分
            let sideLenCount = Math.round(rectW / split);
            //弧长可以存放小车数量 
            let arcLenSplit = Math.round(arcLength / split);
            // 
            let lineSplit = rectW / sideLenCount
    
            //每一个BOX对应的角度;
            // var avd = 180 / arcLenSplit;
            //每一个BOX对应的弧度;
            // let o = avd * Math.PI / 180;
    
    
            // 再次尝试,改掉以角度划分为以数量来划分,
            var count = 0;
            var count2 = 0;
    
            // 画圆心,主要绘制的时候观察使用,后期删除
            createNode('yuan', { x: cx, y: cy });
            // 左下角
            let p1 = { x: -rectW / 2, y: rectH / 2, i: 0 };
            let p2 = { x: rectW / 2, y: -rectH / 2, i: 0 }
    
    
            //思路:计算矩形周长,处以数量值;先从左下角开始,每次叠加x,如果超过矩形下方长度,则切换至圆形弧度绘制,还是只能以是否在矩形上来判断该绘制矩形横轴或者圆形
            for (var j = 1; j <= len; j++) {
                if (j <= sideLenCount) {
                    //绘制矩形底边 外面为计算总共拆分,里面重新计算分到的 边长/数量
                    let x = p1.x + getSplit(lineSplit, p1.i)
                    let y = p1.y;
                    p1.i++;
                    createNode('ip' + j, { x: x + cx, y: y + cy });
                } else if (j > sideLenCount && j <= (sideLenCount + arcLenSplit)) {
                    // 绘制右侧圆弧
                    let ang = 180 / arcLenSplit;
                    let hd = getSplit(ang, count) * Math.PI / 180;
                    count++;
                    let yuanx = radius * Math.sin(hd) + cx + (rectW / 2);
                    let yuany = radius * Math.cos(hd) + cy;
                    createNode('ip' + j, { x: yuanx, y: yuany });
                } else if (j > (sideLenCount + arcLenSplit) && j <= (sideLenCount + sideLenCount + arcLenSplit)) {
                    // 矩形顶部
                    let x = p2.x - getSplit(lineSplit, p2.i)
                    y = p2.y;
                    p2.i++;
                    createNode('ip' + j, { x: x + cx, y: y + cy });
                } else {
                    //剩余
                    let remaining = len - (sideLenCount * 2) - arcLenSplit;
                    let ang = getSplit(180 / remaining, count2) * Math.PI / 180;
                    // 貌似是加上180度弧度的意思?
                    let hd = ang + (Math.PI / 180 * 180);
                    count2++;
                    let yuanx = radius * Math.sin(hd) + cx - (rectW / 2);
                    let yuany = radius * Math.cos(hd) + cy;
                    createNode('ip' + j, { x: yuanx, y: yuany });
                }
            }
    
            function getSplit(split, count) {
                // 2,6,10,14方式均分排列
                return (split / 2) + (count * split)
            }
    
        }
        </script>
    </body>
    
    </html>
    

    相关文章

      网友评论

          本文标题:js实现圆角矩形(非canvas)

          本文链接:https://www.haomeiwen.com/subject/wyinaqtx.html