我正在尝试整理一个用于设置定价的GUI 有三个类别以图形方式表示,以及两个我们想要设置买入/卖出价格的滑块。
作为一项练习,我将一些原型划分为here on jsFiddle 请快速浏览一下,它会比我的话曾经可以更有效地解释它 (请原谅我的JS ......还没有重构它)
由于我们的目标是让滑块在HTML输入中设置浮动,我倾向于SVG。
(我预计该位置将代表定义的$$范围的百分比,因此我们可以推断出特定的$$值)
非常感谢任何和所有帮助。
答案 0 :(得分:0)
这是我制作的一个使用SVG设置四个输入的演示,反之亦然:
http://phrogz.net/svg/complex-plane-picker.xhtml
前两个输入是X和Y(实部和复杂分量);底部两个是极坐标(幅度和角度)。
那里可能存在的代码多于你需要的代码(当你靠近边缘/中间时自动缩放,绘制更新的轴刻度),这可能会使它作为演示而不是有用而更加混乱。
一般而言,您需要:
keyup
或change
或input
事件中设置事件监听器,并更新SVG以进行相应匹配。.value
。作为提示,在拖动过程中不要尝试检测可拖动元素本身的mousemove
。如果鼠标移到此外,您将停止获取拖动事件,它将无法跟上。相反,我通常使用这个逻辑:
mousedown
上:
mousemove
处理程序
mouseup
处理程序
mousemove
上:
mouseup
上:
mousemove
处理程序。以下是完整的源代码,万一我的网站出现故障:
<!DOCTYPE HTML>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"><head>
<meta http-equiv="content-type" content="application/xhtml+xml; charset=utf-8" />
<title>SVG Complex Plane Input</title>
<style type="text/css" media="screen">
html, body { background:#eee; margin:0 }
p { margin:0.5em; text-align:center }
.complex-plane-picker svg { width:200px; height:200px; display:block; margin:1em auto; stroke-linejoin:round; stroke-linecap:round; pointer-events:all; }
.complex-plane-picker rect.bg { fill:#fff; }
.complex-plane-picker .axes * { stroke:#ccc; fill:none }
.complex-plane-picker .dot { fill:#090; fill-opacity:0.4; stroke:#000; stroke-opacity:0.6; cursor:move; }
.complex-plane-picker input { width:6em; }
.complex-plane-picker .labels { stroke:none; font-size:6px; font-family:'Verdana'; text-anchor:middle; alignment-baseline:middle; }
.complex-plane-picker .scalers { pointer-events:all; }
</style>
</head><body>
<p>Drag the dot to set the complex value.<br/> TODO: Hold down shift to affect only the magnitude. Hold down alt to affect only the angle. Hold down both to snap to the nearest real- or imaginary-only value.</p>
<div class="complex-plane-picker">
<p class="rectangular"><input type="number" value="0" class='real' />+<input type="number" value="0" class='imaginary' />i</p>
<svg viewBox="-50 -50 100 100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" baseProfile="full">
<rect class="bg" x="-50" y="-50" width="100" height="100" />
<g class="scalers">
<rect x="-5" y="-5" width="10" height="10" fill="#ffc"/>
<rect x="-45" y="-45" width="90" height="90" fill="none" stroke="#ffc" stroke-width="10" />
</g>
<g class="axes">
<g>
<line x1="-49" y1="0" x2="49" y2="0" />
<polyline points="-44,5 -49,0 -44,-5" />
<polyline points="44,5 49,0 44,-5" />
</g>
<g transform="rotate(90)">
<line x1="-49" y1="0" x2="49" y2="0" />
<polyline points="-44,5 -49,0 -44,-5" />
<polyline points="44,5 49,0 44,-5" />
</g>
</g>
<g class="labels" id="labels">
<text x="0" y="0">0</text>
<text x="0" y="0">0</text>
<text x="0" y="0">0</text>
<text x="0" y="0">0</text>
</g>
<use class="labels" xlink:href="#labels" transform="rotate(90)" />
<circle class="dot" r="4" />
</svg>
<p class="polar"><input type="number" value="0" class='magnitude' />@<input type="number" value="0" class='angle'/>°</p>
</div>
<script type="text/javascript"><![CDATA[
var svg = document.getElementsByTagName('svg')[0];
var svgNS = svg.getAttribute('xmlns');
var pt = svg.createSVGPoint();
function mxy(evt){
pt.x = evt.clientX;
pt.y = evt.clientY;
return pt.matrixTransform(svg.getScreenCTM().inverse());
}
var dot = document.querySelector('.complex-plane-picker .dot');
var real = document.querySelector('.real');
var imag = document.querySelector('.imaginary');
var size = document.querySelector('.magnitude');
var angl = document.querySelector('.angle');
var labels = svg.querySelectorAll('.complex-plane-picker #labels text');
var scale, maxValue;
var updateScale = function(newScale){
scale = newScale;
maxValue = 50*scale;
var tickSize=1e-6;
var e=-5;
var f=-1;
var fs = [1,2,5]
while (tickSize/scale < 10){
if (++f%fs.length==0) ++e;
tickSize = fs[f%fs.length]*Math.pow(10,e);
}
for (var i=labels.length;i;--i){
labels[i-1].firstChild.nodeValue = (tickSize*i).toString().replace(/(\.0*[^0]+)0{3,}.*/,'$1');
labels[i-1].setAttribute('y', -tickSize*i/scale);
}
// updateRectangularFromDot();
// updatePolarFromDot();
};
var rescaleAsNeeded = function(x,y,jump){
var scaleFactor = 1.03;
if (jump && (x>maxValue || y>maxValue || (x<maxValue*0.1 && y<maxValue*0.1))){
updateScale(Math.max(x,y)*2/50);
} else if (x>maxValue*0.8 || y>maxValue*0.8) updateScale(scale*scaleFactor);
else if (x<maxValue*0.1 && y<maxValue*0.1) updateScale(scale/scaleFactor);
};
var updateFromRectangular = function(){
var x = real.value*1;
var y = imag.value*1;
rescaleAsNeeded(x,y,true);
dot.cx.baseVal.value = x/scale;
dot.cy.baseVal.value = -y/scale;
updatePolarFromDot();
};
real.addEventListener('input',updateFromRectangular,false);
imag.addEventListener('input',updateFromRectangular,false);
var updateFromPolar = function(){
var hyp = size.value*1;
var rad = angl.value*Math.PI/180;
var x = Math.cos(rad)*hyp;
var y = Math.sin(rad)*hyp;
rescaleAsNeeded(x,y,true);
dot.cx.baseVal.value = x/scale;
dot.cy.baseVal.value = -y/scale;
updateRectangularFromDot();
};
size.addEventListener('input',updateFromPolar,false);
angl.addEventListener('input',updateFromPolar,false);
var updateRectangularFromDot = function(){
real.value = ( dot.cx.baseVal.value*scale).toFixed(2);
imag.value = (-dot.cy.baseVal.value*scale).toFixed(2);
};
var updatePolarFromDot = function(){
var x = dot.cx.baseVal.value*scale;
var y = -dot.cy.baseVal.value*scale;
size.value = Math.sqrt(x*x+y*y).toFixed(2);
angl.value = (Math.atan2(y,x)*180/Math.PI).toFixed(1);
}
var dragging = false;
dot.addEventListener('mousedown',function(evt){
var offset = mxy(evt);
dragging = true;
offset.x = dot.cx.baseVal.value - offset.x;
offset.y = dot.cy.baseVal.value - offset.y;
var scaleTimer;
var move = function(evt){
clearTimeout(scaleTimer);
var now = mxy(evt);
var x = offset.x + now.x;
var y = -(offset.y + now.y);
dot.cx.baseVal.value = x;
dot.cy.baseVal.value = -y;
x = Math.abs(x)*scale, y=Math.abs(y)*scale;
var oldScale = scale;
rescaleAsNeeded(x,y);
updatePolarFromDot();
updateRectangularFromDot();
if (oldScale != scale) scaleTimer = setTimeout(function(){move(evt)},1000/30);
};
document.documentElement.style.userSelect =
document.documentElement.style.MozUserSelect =
document.documentElement.style.webkitUserSelect = 'none';
svg.addEventListener('mousemove',move,false);
document.documentElement.addEventListener('mouseup',function(){
dragging = false;
clearTimeout(scaleTimer);
svg.removeEventListener('mousemove',move,false);
document.documentElement.style.userSelect =
document.documentElement.style.MozUserSelect =
document.documentElement.style.webkitUserSelect = '';
},false);
},false);
dot.addEventListener('dblclick',function(){
dot.cx.baseVal.value = dot.cy.baseVal.value = 0;
updateScale(1.0);
updatePolarFromDot();
updateRectangularFromDot();
},false);
updateScale(1.0);
]]></script>
</body></html>