js圆角矩形旋转(div拼凑)
<!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>
最后效果