js實現(xiàn)圓角矩形(非canvas)

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");
        // 動態(tài)
        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) {
        //初始化圓角矩形

        // 數(shù)量
        let len = params.len || 100;
        // 設(shè)置圓角矩形內(nèi)矩形寬高 ,
        let rectW = params.rectW || 700;
        let rectH = params.rectH || 900;
        // 中心
        let cx = params.p.x || 0;
        let cy = params.p.y || 0;

        /*
         * 思路:圓角矩形可以看作一個矩形和左右兩個半圓組成,半徑為矩形的一半庄拇;
         * 圓周長+矩形兩邊的長度 / 總數(shù)量 計算出各邊應該存放的小車數(shù)量侮腹,以此數(shù)量為基準判斷該繪制哪一塊盗扇;
         *
         * o = (180 / arcLenSplit) * Math.PI / 180
         * l=nπr/180 弧長公式
         * l = n(圓心角)× π(圓周率)× r(半徑)/180=α(圓心角弧度數(shù))× r(半徑)
         * 這里的象限為4321腌逢,為(1,1),(1,-1),(-1,-1),(-1,1)
         * 
         */



        // 圓半徑
        let radius = rectH / 2;

        // 兩邊弧長相等為
        let arcLength = Math.PI * radius;
        // 圓弧*2 + 矩形頂邊底邊長度除以總數(shù)量
        let split = ((arcLength * 2) + (rectW * 2)) / len;
        // 矩形邊長可以存放數(shù)量莲兢,均分
        let sideLenCount = Math.round(rectW / split);
        //弧長可以存放小車數(shù)量 
        let arcLenSplit = Math.round(arcLength / split);
        // 
        let lineSplit = rectW / sideLenCount

        //每一個BOX對應的角度;
        // var avd = 180 / arcLenSplit;
        //每一個BOX對應的弧度;
        // let o = avd * Math.PI / 180;


        // 再次嘗試聚唐,改掉以角度劃分為以數(shù)量來劃分庆锦,
        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 }


        //思路:計算矩形周長,處以數(shù)量值;先從左下角開始艇搀,每次疊加x尿扯,如果超過矩形下方長度,則切換至圓形弧度繪制焰雕,還是只能以是否在矩形上來判斷該繪制矩形橫軸或者圓形
        for (var j = 1; j <= len; j++) {
            if (j <= sideLenCount) {
                //繪制矩形底邊 外面為計算總共拆分衷笋,里面重新計算分到的 邊長/數(shù)量
                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)) {
                // 繪制右側(cè)圓弧
                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>
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末矩屁,一起剝皮案震驚了整個濱河市辟宗,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌吝秕,老刑警劉巖泊脐,帶你破解...
    沈念sama閱讀 217,907評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異烁峭,居然都是意外死亡容客,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評論 3 395
  • 文/潘曉璐 我一進店門约郁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來缩挑,“玉大人,你說我怎么就攤上這事鬓梅」┲茫” “怎么了?”我有些...
    開封第一講書人閱讀 164,298評論 0 354
  • 文/不壞的土叔 我叫張陵绽快,是天一觀的道長芥丧。 經(jīng)常有香客問我,道長谎僻,這世上最難降的妖魔是什么娄柳? 我笑而不...
    開封第一講書人閱讀 58,586評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮艘绍,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘秫筏。我一直安慰自己诱鞠,他們只是感情好,可當我...
    茶點故事閱讀 67,633評論 6 392
  • 文/花漫 我一把揭開白布这敬。 她就那樣靜靜地躺著航夺,像睡著了一般。 火紅的嫁衣襯著肌膚如雪崔涂。 梳的紋絲不亂的頭發(fā)上阳掐,一...
    開封第一講書人閱讀 51,488評論 1 302
  • 那天,我揣著相機與錄音,去河邊找鬼缭保。 笑死汛闸,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的艺骂。 我是一名探鬼主播诸老,決...
    沈念sama閱讀 40,275評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼钳恕!你這毒婦竟也來了别伏?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,176評論 0 276
  • 序言:老撾萬榮一對情侶失蹤忧额,失蹤者是張志新(化名)和其女友劉穎厘肮,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體睦番,經(jīng)...
    沈念sama閱讀 45,619評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡轴脐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,819評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了抡砂。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片大咱。...
    茶點故事閱讀 39,932評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖注益,靈堂內(nèi)的尸體忽然破棺而出碴巾,到底是詐尸還是另有隱情,我是刑警寧澤丑搔,帶...
    沈念sama閱讀 35,655評論 5 346
  • 正文 年R本政府宣布厦瓢,位于F島的核電站,受9級特大地震影響啤月,放射性物質(zhì)發(fā)生泄漏煮仇。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,265評論 3 329
  • 文/蒙蒙 一谎仲、第九天 我趴在偏房一處隱蔽的房頂上張望浙垫。 院中可真熱鬧,春花似錦郑诺、人聲如沸夹姥。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,871評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽辙售。三九已至,卻和暖如春飞涂,著一層夾襖步出監(jiān)牢的瞬間旦部,已是汗流浹背祈搜。 一陣腳步聲響...
    開封第一講書人閱讀 32,994評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留士八,地道東北人容燕。 一個月前我還...
    沈念sama閱讀 48,095評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像曹铃,于是被迫代替她去往敵國和親缰趋。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,884評論 2 354

推薦閱讀更多精彩內(nèi)容