2015-03-13 77 views

回答

2

餅圖段是一個真正的楔。你有幾種方法來測試一個楔子。

一種方法是數學方法:

  • 測試鼠標是否由楔形創建一個圓的半徑之內。

  • 如果半徑測試爲真,則計算鼠標與圓心的中心點的角度。

  • 將該角度與每個楔塊進行比較。如果角度在特定楔形弧的起始角度和結束角度之間,則鼠標位於該楔形內。

另一種方法是使用內置的路徑命中測試方法畫布:isPointInPath

  • 重新定義一個楔子。沒有必要實際擊中或填充該楔形物。只需執行從beginPathclosePath的命令即可。

  • 使用context.isPointInPath(mouseX,mouseY)來命中 - 如果鼠標在楔子內部。

  • 如果isPointInPath返回true,則發現鼠標下方的楔形。如果沒有,則重新定義&命中每個其他楔子。

這裏的東西我編碼徘徊時前陣子擊中檢驗一個餅圖的楔形,並在單擊時楔形移動楔形掉下來的餡餅。

它使用isPointInPath方法做點擊測試:

var canvas = document.getElementById("canvas"); 
 
var ctx = canvas.getContext("2d"); 
 
ctx.lineJoin = "round"; 
 

 
var $canvas = $("#canvas"); 
 
var canvasOffset = $canvas.offset(); 
 
var offsetX = canvasOffset.left; 
 
var offsetY = canvasOffset.top; 
 
var scrollX = $canvas.scrollLeft(); 
 
var scrollY = $canvas.scrollTop(); 
 

 
function Wedge(cx, cy, radius, startAngleDeg, endAngleDeg, fill, stroke, linewidth) { 
 
    this.cx = cx; 
 
    this.cy = cy; 
 
    this.radius = radius; 
 
    this.startAngle = startAngleDeg * Math.PI/180; 
 
    this.endAngle = endAngleDeg * Math.PI/180; 
 
    this.fill = fill; 
 
    this.stroke = stroke; 
 
    this.lineWidth = linewidth; 
 
    this.offsetX = 0; 
 
    this.offsetY = 0; 
 
    this.rr = radius * radius; 
 

 

 
    this.centerX = cx; 
 
    this.centerY = cy; 
 

 
    this.midAngle = this.startAngle + (this.endAngle - this.startAngle)/2; 
 
    this.offsetDistance = 15; 
 
    this.explodeX = this.offsetDistance * Math.cos(this.midAngle); 
 
    this.explodeY = this.offsetDistance * Math.sin(this.midAngle); 
 
    this.isExploded = false; 
 

 

 

 
}; 
 
Wedge.prototype.draw = function(fill, stroke) { 
 
    this.define(); 
 
    this.fillStroke(fill, stroke); 
 
    ctx.beginPath(); 
 
    ctx.arc(this.cx, this.cy, this.radius, 0, Math.PI * 2); 
 
    ctx.closePath(); 
 
    ctx.lineWidth = 0.50; 
 
    ctx.stroke(); 
 
} 
 
Wedge.prototype.fillStroke = function(fill, stroke) { 
 
    ctx.fillStyle = fill || this.fill; 
 
    ctx.fill(); 
 
    ctx.strokeStyle = stroke, this.stroke; 
 
    ctx.lineWidth = this.lineWidth; 
 
    ctx.stroke(); 
 
} 
 
Wedge.prototype.define = function() { 
 
    var x = this.cx + this.offsetX; 
 
    var y = this.cy + this.offsetY; 
 
    ctx.beginPath(); 
 
    ctx.arc(x, y, this.radius, this.startAngle, this.endAngle); 
 
    ctx.lineTo(x, y); 
 
    ctx.closePath(); 
 
} 
 
Wedge.prototype.ptAtAngle = function(radianAngle) { 
 
    var xx = (this.cx + this.offsetX) + this.radius * Math.cos(radianAngle); 
 
    var yy = (this.cy + this.offsetY) + this.radius * Math.sin(radianAngle); 
 
    return ({ 
 
    x: x, 
 
    y: y 
 
    }); 
 
} 
 
Wedge.prototype.explode = function(isExploded) { 
 
    this.isExploded = isExploded; 
 
    this.offsetX = isExploded ? this.explodeX : 0; 
 
    this.offsetY = isExploded ? this.explodeY : 0; 
 
    this.draw(); 
 
} 
 
Wedge.prototype.isPointInside = function(x, y) { 
 
    var dx = x - (this.cx + this.offsetX); 
 
    var dy = y - (this.cy + this.offsetY); 
 
    if (dx * dx + dy * dy > this.rr) { 
 
    return (false); 
 
    } 
 
    var angle = (Math.atan2(dy, dx) + Math.PI * 2) % (Math.PI * 2); 
 
    return (angle >= this.startAngle && angle <= this.endAngle); 
 
} 
 
Wedge.prototype.marker = function(pos) { 
 
    ctx.beginPath(); 
 
    ctx.arc(pos.x, pos.y, 3, 0, Math.PI * 2); 
 
    ctx.closePath(); 
 
    ctx.fillStyle = "red"; 
 
    ctx.fill(); 
 
} 
 

 

 
function handleMouseDown(e) { 
 
    e.preventDefault(); 
 
    mouseX = parseInt(e.clientX - offsetX); 
 
    mouseY = parseInt(e.clientY - offsetY); 
 

 
    clear(); 
 
    for (var i = 0; i < wedges.length; i++) { 
 
    var wedge = wedges[i].wedge; 
 
    if (wedge.isPointInside(mouseX, mouseY)) { 
 
     wedge.explode(!wedge.isExploded); 
 
    } 
 
    wedge.draw(); 
 
    } 
 
} 
 

 
function handleMouseUp(e) { 
 
    e.preventDefault(); 
 
    mouseX = parseInt(e.clientX - offsetX); 
 
    mouseY = parseInt(e.clientY - offsetY); 
 

 
    // Put your mouseup stuff here 
 
    isDown = false; 
 
} 
 

 
function handleMouseOut(e) { 
 
    e.preventDefault(); 
 
    mouseX = parseInt(e.clientX - offsetX); 
 
    mouseY = parseInt(e.clientY - offsetY); 
 

 
    // Put your mouseOut stuff here 
 
    isDown = false; 
 
} 
 

 
function handleMouseMove(e) { 
 
    e.preventDefault(); 
 
    mouseX = parseInt(e.clientX - offsetX); 
 
    mouseY = parseInt(e.clientY - offsetY); 
 

 
    for (var i = 0; i < wedges.length; i++) { 
 
    var wedge = wedges[i].wedge; 
 
    if (wedge.isPointInside(mouseX, mouseY)) { 
 
     wedge.draw("black"); 
 
    } else { 
 
     wedge.draw(); 
 
    } 
 
    } 
 

 

 
} 
 

 
$("#canvas").mousedown(function(e) { 
 
    handleMouseDown(e); 
 
}); 
 
$("#canvas").mousemove(function(e) { 
 
    handleMouseMove(e); 
 
}); 
 
$("#canvas").mouseup(function(e) { 
 
    handleMouseUp(e); 
 
}); 
 
$("#canvas").mouseout(function(e) { 
 
    handleMouseOut(e); 
 
}); 
 

 
function clear() { 
 
    ctx.clearRect(0, 0, canvas.width, canvas.height); 
 
} 
 

 
var PI2 = Math.PI * 2; 
 
var cx = 150; 
 
var cy = 150; 
 
var r = 100; 
 
var line = 2; 
 
var stroke = "black"; 
 
var wedges = []; 
 
wedges.push({ 
 
    percent: 18, 
 
    fill: "red" 
 
}); 
 
wedges.push({ 
 
    percent: 30, 
 
    fill: "blue" 
 
}); 
 
wedges.push({ 
 
    percent: 25, 
 
    fill: "green" 
 
}); 
 
wedges.push({ 
 
    percent: 13, 
 
    fill: "purple" 
 
}); 
 
wedges.push({ 
 
    percent: 14, 
 
    fill: "gold" 
 
}); 
 
var rAngle = 0; 
 
for (var i = 0; i < wedges.length; i++) { 
 
    var wedge = wedges[i]; 
 
    var angle = 360 * wedge.percent/100; 
 
    wedge.wedge = new Wedge(cx, cy, r, rAngle, rAngle + angle, wedge.fill, "black", 1); 
 
    wedge.wedge.draw(); 
 
    rAngle += angle; 
 
} 
 

 
window.onscroll = function(e) { 
 
    var BB = canvas.getBoundingClientRect(); 
 
    offsetX = BB.left; 
 
    offsetY = BB.top; 
 
}
body { 
 
    background-color: ivory; 
 
} 
 
#canvas { 
 
    border: 1px solid red; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> 
 
<h4>Hover wedge to highlight it<br>Click wedge to explode that wedge</h4> 
 
<canvas id="canvas" width=300 height=300></canvas>

相關問題