設計稿:
css
最後實現效果圖:
html
話很少說,直接上代碼!ajax
<!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"> <link rel="stylesheet" href="./css/bodyExam.css"> <title>體測報告</title> </head> <body> <div class="body_tu" id="drawing"> </div> </body> <script src="https://cdnjs.cloudflare.com/ajax/libs/svg.js/2.6.5/svg.js"></script> <script> var text_l = ['體重', 'BMI', '脂肪', '肌肉', '水分', '蛋白質', '皮下脂肪', '內臟脂肪', '骨量', '基礎代謝', '身體年齡', '靜態心率'] function pieer(text_list, source) { var winwidth = window.innerWidth var d_width = winwidth < 375 ? winwidth : 375 // 畫布大小 var viewboxwid = winwidth / 375 var trasx = (winwidth - 375) / 2 var d_hlaf = d_width / 2 // 一半 var circle_r = 103 var line_color = "#F0F0F0" var line_num = text_list.length var rotate_one = 360 / line_num var source = source var sourcelength = String(source).length var sourcetext = '綜合評分' var text_list = text_list function fontalign(basefontsize, num) { var font_item = basefontsize, font_left = 0, num_length = String(num).length if (String(num).indexOf('.') > -1) { font_left = (((num_length - 1) * font_item) + 6.67) / 2 } else { font_left = (num_length * font_item) / 2 } return font_left } function rad(params) { return params * Math.PI / 180 } var draw = SVG('drawing').size(d_width, d_width) // 定一畫布 draw.transform({ scale: viewboxwid > 1.2 ? 1.2 : viewboxwid }) document.getElementById('drawing').style.width = d_width var gradient = draw.gradient('linear', function (stop) { // 線性漸變 stop.at(0, '#27867B', 0.5) stop.at(1, '#97E7BB', 0.5) }) gradient.from(0, 1).to(0.5, 0) // 漸變位置更改 var panel = draw.gradient('linear', function (stop) { // 線性漸變 stop.at(0, '#69CAB7', 0.4) stop.at(1, '#0C4691', 0.05) }) panel.from(0, 1).to(0.5, 0) // 漸變位置更改 var group = draw.group() // 創建分組 var circle = group.circle(circle_r * 2).attr({ // 外部線條大圓環 cx: d_hlaf, cy: d_hlaf, fill: '#FFFFFF', stroke: line_color, 'stroke-width': 1 }) console.log(line_num) for (var i = 0; i < line_num; i++) { // 外部文字和蜘蛛網線 group.line(d_hlaf, d_hlaf - circle_r, d_hlaf, d_hlaf + circle_r).stroke({ width: 1, color: line_color }).transform({ rotation: rotate_one * i }) // group.text('體重').rotate(rotate_one * i, d_hlaf, d_hlaf) var fontitem = text_list[i] var xi = d_hlaf + (circle_r + 30) * Math.cos(rad(i * rotate_one - 90)) // 計算每一個文字的座標x var yi = d_hlaf + (circle_r + 30) * Math.sin(rad(i * rotate_one - 90)) // 計算每一個文字的座標y group.text(fontitem).transform({ x: xi - fontalign(12, fontitem), y: yi - 9 }).font({ size: 12, anchor: 'start', }) } var group1 = draw.group() group1.circle((circle_r - 28) * 2).attr({ // 中間圓環 cx: d_hlaf, cy: d_hlaf, fill: 'transparent', stroke: gradient, 'stroke-width': 20, }) var linec = '' var linearr = [] for (var i = 0; i < line_num; i++) { // 描點 // circle_r = 100% , ((circle_r - 10) / 2) = 0% var min = ((circle_r - 10) / 2) // 最小值 var r = Math.floor(Math.random() * (circle_r - min + 1) + min) var mindleMin = (circle_r - min) / 3 // 正常最小值 = mindleMin + min var mindleMax = (mindleMin * 2) + min // 正常最大值 var color = '#1AB394' if (r < (mindleMin + min)) { color = '#7AB8CF' } else if (r <= mindleMax) { color = '#1AB394' } else { color = '#F8AC59' } var xi = d_hlaf + (r) * Math.cos(rad(i * rotate_one - 90)) // 計算每一個點的座標x var yi = d_hlaf + (r) * Math.sin(rad(i * rotate_one - 90)) // 計算每一個點的座標y var x = d_hlaf + min * Math.cos(rad(i * rotate_one - 90)) // 計算每一個點的起始座標x var y = d_hlaf + min * Math.sin(rad(i * rotate_one - 90)) // 計算每一個點的起始座標y group.circle(5).attr({ // 外部線條大圓環 cx: xi, cy: yi, fill: color }) linec = linec + x + ',' + y + ' ' linearr.push([xi, yi]) } var polygon = group.polygon(linec).fill(panel) // 繪製折線 polygon.animate(800).plot(linearr) var group3 = draw.group() group3.circle(circle_r - 10).attr({ cx: d_hlaf, cy: d_hlaf, fill: '#ffffff', stroke: line_color, 'stroke-width': 1, }) var _left = fontalign(13.39, source) var soure = group3.text(function (add) { add.tspan(source).newLine().dx(0).fill('#1AB394') }).transform({ x: d_hlaf - _left, y: d_hlaf - 44 }) soure.font({ family: 'dincondensed-bold', size: 36, anchor: 'start', // leading: '1.5em' }) var font_left = fontalign(11, sourcetext) var font = group3.text(function (add) { add.tspan(sourcetext).newLine().dx(0).fill('#333333') }).transform({ x: d_hlaf - font_left, y: d_hlaf + 10 }) font.font({ size: 12, anchor: 'start', // leading: '1.5em' }) } pieer(text_l, 23.6) </script> </html>
直接複製粘貼就能看到效果。
此圖考察了svg的各類使用;其中包含了,繪製圓形、圓環,點,折線,多邊形,水平居中文字,三角函數計算座標。關於手機端適配方面,直接使用svg的viewbox來實現。由於svg是矢量圖形,不管放大縮小都不失真,因此能夠用適用各類設備且效果顯示出衆。
公司給的設計稿是375寬度,我就用了375.大家也能夠將d_width這個值直接設置爲屏幕寬度。
若是有bug請告之。dom