我正在寻找一个javascript(jQuery for preference)控件,它允许选择一个圆的一部分。我不能使用标准的jQuery滑块,因为它是线性的;我正在从事的基础模型是一个旋转系统,我试图说在用户可选的角度范围内(如发动机中的凸轮轴)开启了某些功能。任何人都可以指向任何代码,让我从一开始?圆形范围选择控件
Q
圆形范围选择控件
1
A
回答
4
我已经试验了一段时间,使这个代码:
function Dial(id, size, properties) {
var props = properties || {};
var dial = this;
var div = $(id);
var canvas = $("<canvas width=\""+size+"\" height=\""+size+"\"></canvas>");
var ctx = canvas.appendTo(div)[0].getContext("2d");
canvas = canvas[0];
var pi2 = Math.PI*2;
this.label = props.label;
this.from = (props.from==null ? 0 : props.from) % pi2;
if (this.from > Math.PI)
this.from -= pi2;
else if (this.from < -Math.PI)
this.from += pi2;
this.to = (props.to==null ? 2 : props.to) % pi2;
if (this.to > Math.PI)
this.to -= pi2;
else if (this.to < -Math.PI)
this.to += pi2;
this.selectedFrom = false;
this.selectedTo = false;
this.radius = size/2-10;
if (props.change)
div.bind("change", props.change);
if (props.startchange)
div.bind("startchange", props.startchange);
if (props.stopchange)
div.bind("stopchange", props.stopchange);
this.reset = function(from, to) {
this.from = from % pi2;
if (this.from > Math.PI)
this.from -= pi2;
else if (this.from < -Math.PI)
this.from += pi2;
this.to = to % pi2;
if (this.to > Math.PI)
this.to -= pi2;
else if (this.to < -Math.PI)
this.to += pi2;
this.selectedFrom = this.selectedTo = false;
this.movingFrom = this.movingTo = false;
this.draw();
};
this.draw = function() {
ctx.save();
ctx.clearRect(0,0,size,size);
ctx.translate(size/2,size/2);
ctx.beginPath();
ctx.strokeStyle = "silver";
ctx.lineWidth = 5;
ctx.arc(0, 0, this.radius, 0, 2*Math.PI);
ctx.stroke();
ctx.beginPath();
ctx.strokeStyle = "black";
ctx.lineWidth = 9;
var f = 1.5 * Math.PI - this.from;
var t = 1.5 * Math.PI - this.to;
ctx.arc(0, 0, this.radius, f, t, true);
ctx.stroke();
ctx.beginPath();
ctx.lineWidth = 1;
ctx.fillStyle = this.selectedFrom ? "red" : "green";
ctx.strokeStyle = this.selectedFrom ? "black" : "silver";
ctx.arc(-this.radius*Math.sin(this.from),
-this.radius*Math.cos(this.from),
8, 0, 2*Math.PI);
ctx.fill();
ctx.stroke();
ctx.beginPath();
ctx.fillStyle = this.selectedTo ? "red" : "green";
ctx.strokeStyle = this.selectedTo ? "black" : "silver";
ctx.arc(-this.radius*Math.sin(this.to),
-this.radius*Math.cos(this.to),
8, 0, 2*Math.PI);
ctx.fill();
ctx.stroke();
if (this.label) {
ctx.strokeStyle = "black";
ctx.fillStyle = "black";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText(this.label, 0, 0);
}
ctx.restore();
};
var getMousePos = function(canvas, evt){
// get canvas position
var obj = canvas;
var top = 0;
var left = 0;
while (obj && obj.tagName != 'BODY') {
top += obj.offsetTop;
left += obj.offsetLeft;
obj = obj.offsetParent;
}
// return relative mouse position
var mouseX = evt.clientX - left + window.pageXOffset;
var mouseY = evt.clientY - top + window.pageYOffset;
return {
x: mouseX,
y: mouseY
};
};
if (!Math.hypot) {
Math.hypot = function(x,y) {
return Math.sqrt(x*x + y*y);
};
}
var inTo = function(pos) {
return Math.hypot(size/2-dial.radius*Math.sin(dial.to)-pos.x,
size/2-dial.radius*Math.cos(dial.to)-pos.y) <= 8;
};
var inFrom = function(pos) {
return Math.hypot(size/2-dial.radius*Math.sin(dial.from)-pos.x,
size/2-dial.radius*Math.cos(dial.from)-pos.y) <= 8;
};
canvas.addEventListener("mousemove", function(evt) {
var pos = getMousePos(canvas, evt);
var redraw = false;
if (dial.movingFrom) {
if (pos.x == size/2 && pos.y == size/2)
return;
dial.from = Math.atan2(size/2-pos.x,size/2-pos.y);
redraw = true;
div.trigger("change", [dial.from, dial.to]);
} else if (dial.movingTo) {
if (pos.x == size/2 && pos.y == size/2)
return;
dial.to = Math.atan2(size/2-pos.x,size/2-pos.y);
redraw = true;
div.trigger("change", [dial.from, dial.to]);
} else if (inTo(pos)) {
// In "To" handle
if (dial.selectedFrom) {
dial.selectedFrom = false;
redraw = true;
}
if (!dial.selectedTo) {
dial.selectedTo = true;
redraw = true;
}
} else if (inFrom(pos)) {
// In "From" handle
if (!dial.selectedFrom) {
dial.selectedFrom = true;
redraw = true;
}
if (dial.selectedTo) {
dial.selectedTo = false;
redraw = true;
}
} else {
// In neither handle
if (dial.selectedFrom) {
dial.selectedFrom = false;
redraw = true;
}
if (dial.selectedTo) {
dial.selectedTo = false;
redraw = true;
}
}
if (redraw) {
dial.draw();
}
}, false);
canvas.addEventListener("mousedown", function(evt) {
var pos = getMousePos(canvas, evt);
if (inTo(pos)) {
dial.movingTo = true;
div.trigger("startchange", ["to"]);
} else if (inFrom(pos)) {
dial.movingFrom = true;
div.trigger("startchange", ["from"]);
}
}, false);
canvas.addEventListener("mouseup", function(evt) {
if (dial.movingTo) {
div.trigger("stopchange", ["to", dial.to]);
} else if (dial.movingFrom) {
div.trigger("stopchange", ["from", dial.from]);
}
dial.movingTo = dial.movingFrom = false;
}, false);
this.draw();
};
,然后可以通过应用它:
new Dial("#dial", 150);
$("#dial").bind("change", function(e, from, to) {
console.log("from="+from+", to="+to);
});
它的丑陋,无法访问,但它确实提供了我需要什么。
0
+0
唉,不。这只是输出。我正在寻找直接与它互动。 (太遗憾了,它看起来很漂亮。) –
+0
我可能做错了什么,但它不会为我显示任何东西(在Safari中),即使我添加了背景图片。 –
+0
他的演示缺少knob.png - 我认为它是一个多图像文件。我稍后会看看 – mplungjan
相关问题
- 1. 序号范围范围圆形带()
- 2. 有没有办法控制范围选择器的范围?
- 3. 圆形范围内的匹配日期
- 4. 范围和选择
- 5. 选择由范围
- 6. Mysql范围选择
- 7. gmaps4rails选择范围
- 8. 选择从范围
- 9. jq:选择范围
- 10. 日期范围选择器 - 24小时范围选择
- 11. 圆形滑块选择
- 12. 使用python范围选择一个范围的文件
- 13. 检测向量数组中的圆弧和圆形的范围
- 14. ASP.NET MVC3中的期间范围选择控件
- 15. 选择超出范围Telerik的radcombobox控件
- 16. 在highstock控件上选择自定义日期范围
- 17. monthcalendar控件选择的范围不能正确绘制
- 18. 使用EnableVisualStyles的MonthCalendar控件选择范围?
- 19. GWT日期范围选择小部件
- 20. 选择范围下的条件
- 21. jQuery插件选择器访问范围
- 22. hightcharts范围选择器的Onclick事件
- 23. 双击事件选择范围?
- 24. 选择数据范围
- 25. 选择日期范围
- 26. CQL多范围选择
- 27. 选择从范围功能
- 28. 选择日期范围
- 29. 范围选择和Mozilla
- 30. MySQL。选择年份范围
[RaphaelJS](http://raphaeljs.com/)可能有些帮助! – Arj
@ a12jun我没有问题绘制我需要的东西。我只是想避免自己编写所有的代码。 –
好吧,我想也许他们可能是一个插件,它可以做你想做的事情 – Arj