我正在尝试创建一个带有径向线和范围为0-100的数字的比例。 这是我的代码:
<!DOCTYPE html>
<html>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<head>
<title>SVG Gauge</title>
</head>
<style>
#wrapper {
position: relative;
margin: auto;
}
#meter {
width: 100%;
height: 100%;
transform: rotateX(180deg);
}
.circle {
fill: none;
}
#mask {
stroke: #404040;
stroke-width: 60;
}
.blackie {
fill:none;
stroke: #000000;
stroke-width: 30;
}
.range {
stroke-width: 60;
}
.scale {
stroke: #cccccc;
}
#slider, #lbl {
position: absolute;
}
#slider {
cursor: pointer;
left: 0;
margin: auto;
right: 0;
top: 58%;
width: 94%;
}
#lbl {
background-color: #4B4C51;
border-radius: 2px;
color: white;
font-family: 'courier new';
font-size: 15pt;
font-weight: bold;
padding: 4px 4px 2px 4px;
right: -48px;
top: 57%;
}
#meter_needle {
height: 40%;
left: 0;
margin: auto;
position: absolute;
right: 0;
top: 10%;
transform-origin: bottom center;
transform: rotate(270deg);
}
</style>
<body>
<div id="wrapper">
<svg id="meter">
<g class="scale">
<defs>
<linearGradient id="grad" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" style="stop-color:rgb(102, 102, 255);stop-opacity:1" />
<stop offset="100%" style="stop-color:rgb(204, 204, 255);stop-opacity:1" />
</linearGradient>
</defs>
<circle id="high" class="circle range" cx="50%" cy="50%" stroke="url(#grad)">
</circle>
<circle id="mask" class="circle" cx="50%" cy="50%">
</circle>
<circle id="low" class="blackie" cx="50%" cy="50%" r="360">
</circle>
<circle id="outline_ends" class="circle outline" cx="50%" cy="50%">
</circle>
</g>
</svg>
<img id="meter_needle" src="gauge-needle.svg" alt="">
<input id="slider" type="range" min="0" max="100" value="0" />
<label id="lbl" id="value" for="">0%</label>
</div>
<script>
var r = 400;
var circles = document.querySelectorAll('.circle');
var total_circles = circles.length;
for (var i = 0; i < total_circles; i++) {
circles[i].setAttribute('r', r);
}
var meter_dimension = (r * 2) + 100;
var wrapper = document.querySelector('#wrapper');
wrapper.style.width = meter_dimension + 'px';
wrapper.style.height = meter_dimension + 'px';
var cf = 2 * Math.PI * r;
var semi_cf = cf / 2;
var z = 40 * Math.PI;
document.querySelector('#outline_ends')
.setAttribute('stroke-dasharray', 2 + ',' + (semi_cf - 2));
document.querySelector('#high')
.setAttribute('stroke-dasharray', semi_cf + ',' + cf);
document.querySelector('#mask')
.setAttribute('stroke-dasharray', semi_cf + ',' + cf);
document.querySelector('#low')
.setAttribute('stroke-dasharray', semi_cf - z + ',' + cf);
var slider = document.querySelector('#slider');
var lbl = document.querySelector("#lbl");
var svg = document.querySelector('#meter');
var high = document.querySelector('#high');
var mask = document.querySelector('#mask');
var low = document.querySelector('#low');
var meter_needle = document.querySelector('#meter_needle');
function range_change_event() {
var percent = slider.value;
var meter_value = semi_cf - ((percent * semi_cf) / 100);
mask.setAttribute('stroke-dasharray', meter_value + ',' + cf);
meter_needle.style.transform = 'rotate(' + (270 + ((percent * 180) / 100)) + 'deg)';
lbl.textContent = percent + '%';
}
slider.addEventListener('input', range_change_event);
</script>
</body>
</html>
我在网络上发现了很多关于HTML canvas和D3js的很好的示例,但没有基于SVG的示例。 我正在考虑创建一个元素“线”并将其添加到黑色弧上。 创建数字刻度的最简单方法是什么?
答案 0 :(得分:1)
创建数字刻度的最简单方法是什么?
设置svg圆缩放比例最简单的方法是为其半径设置动画
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="400" height="400" viewBox="0 0 400 400" >
<circle cx="200" cy="200" r="10" fill="none" stroke-width="2" stroke="purple" >
<animate attributeName="r" values="1;100;1" dur="4s" repeatCount="indefinite" />
</circle>
</svg>
答案 1 :(得分:1)
您在这里:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-250 -250 500 500" width="500" height="500" id="svg">
<defs>
<style>
line {
stroke: black;
stroke-width: 1px;
}
text {
fill: red;
text-anchor: middle;
font-size: 16px;
font-family: sans-serif;
}
rect {
fill: transparent;
}
#id {
display: none;
}
.origin {
fill: green;
}
.outer {
fill: none;
stroke: black;
}
</style>
</defs>
<circle r="5" cx="0" cy="0" class="origin"/>
<path d="M-180,0 a1,1 0 0,1 360,0" class="outer"/>
<g id="gauge" transform="rotate(-90)">
<g id="noon">
<rect x="-10" y="-220" width="20" height="100"/>
<line x1="0" y1="-190" x2="0" y2="-180"/>
<text x="0" y="-200"></text>
</g>
</g>
</svg>
<script>
for (i=0; i<=180; i = i + 18) {
var new_tick = noon.cloneNode(true);
new_tick.getElementsByTagName('text')[0].textContent = i/180 * 100;
new_tick.removeAttribute("id");
new_tick.setAttribute("transform", "rotate(" + i + " 0 0)");
gauge.appendChild(new_tick);
}
</script>
我认为这是不言而喻的。 (例如,RECT只是一个指南,如果您想更好地可视化每个G内部的内容,可以通过更改填充来打开它。)
如果您有任何后续问题,请告诉我。
如果有帮助,这里是一个Codepen:https://codepen.io/MSCAU/pen/OoQMdV