参考资料:https://juejin.cn/post/7266641059282927650
效果:
源码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>使用css3绘制任意角度扇形</title> <style> .sector { position: relative; display: inline-block; width: 80px; height: 80px; background-color: transparent; border-radius: 50%; overflow: hidden; transform: rotate(45deg); } .sector::before { display: inline-block; content: ''; width: 100%; height: 100%; background: linear-gradient(90deg, #4D84FF 25%,#eee 0, #eee 50%,#4D84FF 0, #4D84FF 75%,#eee 0); background-size: 30px; clip-path: polygon(50% 50%, 0 0, 100% 0); opacity: .7; } .sector::after { position: absolute; display: inline-block; content: ''; width: 80px; height: 80px; top: calc(50% - 40px); left: calc(50% - 40px); border-radius: 50%; background-color: #fff; z-index: 1; } </style> </head> <body> <div class="sector"></div> </body> <script> /** * @param {Number} radius: 半径 * @param {Number} minRadius: 内半径 * @param {Number} angles: 角度 * @param {Number} direct: 方向 **/ function drawPie({radius, minRadius, angles, direct, selector}) { let points = ['50% 50%', '0 0'], residue = angles%45? angles%45:45, percent = 0 direct = direct || 45; angles > 90 && points.push('100% 0'); angles > 180 && points.push('100% 100%'); angles > 270 && points.push('0 100%'); //let percent = (100/2) * (Math.tan(2*Math.PI/360 * residue).toFixed(4)); // tan算出来的是相对半径的占比 percent = (100/2) * (Math.tan(2*Math.PI/360 * residue).toFixed(4)); if(angles<=45) { points.push(percent + '%' + ' 0'); }else if(angles<=90) { points.push(percent + 50 + '%' + ' 0'); }else if(angles<=135) { points.push('100% ' + percent + '%'); }else if(angles<=180) { points.push('100% ' + (percent + 50) + '%'); }else if(angles<=225) { points.push(100 - percent + '%' + ' 100%'); }else if(angles<=270) { points.push(50 - percent + '%' + ' 100%'); }else if(angles<=315) { points.push('0 ' + (100 - percent) + '%'); }else if(angles<=360) { points.push('0 ' + (50 - percent) + '%'); } let path = 'polygon(' + points.join(', ') + ')'; // 外扇面 addCSSRule(selector + '::before', { 'clip-path': path }); // 内扇面 addCSSRule(selector + '::after', { 'clip-path': path, width: minRadius + 'px', height: minRadius + 'px', top: 'calc(50% - ' + minRadius/2 + 'px)', left: 'calc(50% - ' + minRadius/2 + 'px)' }); // 容器大小和方向 addCSSRule(selector, { width: radius + 'px', height: radius + 'px', transform: 'rotate(' + direct + 'deg)' }); } // 绘制扇面 drawPie({ selector: '.sector', radius: 400, minRadius: 180, angles: 120, direct: 100 }); function addCSSRule(selector, rules, index) { // 创建一个style元素 var style = document.createElement('style'); // 设置type属性为text/css style.type = 'text/css'; // 插入到head中 document.head.appendChild(style); // 获取sheet var sheet = style.sheet; // 如果index未提供,则添加到末尾 index = index || null; // 如果是CSS规则字符串 if (typeof rules === 'string') { // 直接添加 sheet.insertRule(selector + ' {' + rules + '}', index); } else { // 如果是一个对象 // 遍历对象中的所有属性 for (var prop in rules) { if (rules.hasOwnProperty(prop)) { // 将属性和值转换为字符串 var rule = prop + ': ' + rules[prop]; // 添加到样式表中 sheet.insertRule(selector + ' {' + rule + '}', index); } } } } /* addCSSRule('.my-other-class', 'color: red; background-color: yellow;', 0); // 添加到顶部 */ </script> </html>
标签:Math,background,100%,50%,param,扇面,angles,绘制,CSS From: https://www.cnblogs.com/xtreme/p/18354810