我正在尋找一個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