【发布时间】:2017-02-22 03:25:00
【问题描述】:
我正在将符号绘图库从 Java 移植到 Javascript。这些符号将被绘制到 HTML5 Canvas 对象中。符号具有坐标和形状(正方形、圆形、十字等)、大小和颜色的属性。
多年来,我一直在用 Java 编写这样一个可以工作的符号绘图库。在 Javascript 中,我很难使用颜色。符号通常以正确的形状和大小绘制,但并不总是以正确的颜色绘制。一个符号的颜色也可以“渗透”到我正在绘制的其他事物,例如图表轴(通常为黑色)。那么如何使绘制符号成为绘图的“原子”单元,以便对我正在绘制的其他事物没有副作用?我觉得我不理解路径和子路径的概念以及上下文存储的状态。我已经对这个问题的解决方案进行了广泛的搜索,但没有找到任何可行的方法。
这是我的符号库中的一些典型代码:
function plotSymbol(ctx, symbol, h, v, width, symcolor) {
var i;
if (width == 0) return;
if (symbol == Resources.PlotSymbolsEnum.SYMBOL_SQUARE) {
ctx.strokeStyle = symcolor;
ctx.strokeRect(h - width / 2.0, v - width / 2.0, width, width);
}
else if (symbol == Resources.PlotSymbolsEnum.SYMBOL_SQUAREFILLED) {
ctx.fillStyle = symcolor;
ctx.fillRect(h - width / 2.0, v - width / 2.0, width, width);
}
else if (symbol == Resources.PlotSymbolsEnum.SYMBOL_CIRCLE) {
var x = h - width / 2;
var y = v - width / 2;
drawCircle(ctx, x, y, width/2, 1, symcolor, false);
}
else if (symbol == Resources.PlotSymbolsEnum.SYMBOL_CIRCLEFILLED) {
var x = h - width / 2;
var y = v - width / 2;
drawCircle(ctx, x, y, width/2, 1, symcolor, true);
}
else if (symbol == Resources.PlotSymbolsEnum.SYMBOL_DIAMOND) {
var xpoints1 = [ h, h + width / 2, h, h - width / 2 ];
var ypoints1 = [ v - width / 2, v, v + width / 2, v ];
ctx.strokeStyle = symcolor;
ctx.beginPath();
ctx.moveTo(xpoints1[0], ypoints1[0]);
for (i = 1; i < xpoints1.length; i++) {
ctx.lineTo(xpoints1[i], ypoints1[i]);
}
// ctx.closePath();
ctx.stroke();
ctx.strokeStyle = 'black';
}
else if (symbol == Resources.PlotSymbolsEnum.SYMBOL_DIAMONDFILLED) {
var xpoints2 = [ h, h + width / 2, h, h - width / 2 ];
var ypoints2 = [ v - width / 2, v, v + width / 2, v ];
ctx.fillStyle = symcolor;
ctx.beginPath();
ctx.moveTo(xpoints2[0], ypoints2[0]);
for (i = 1; i < xpoints2.length; i++) {
ctx.lineTo(xpoints2[i], ypoints2[i]);
}
// ctx.closePath();
ctx.fill();
ctx.stroke();
ctx.fillStyle = 'white';
}
else if (symbol == Resources.PlotSymbolsEnum.SYMBOL_TRIANGLE) {
var xpoints3 = [ h - width / 2, h + width / 2, h ];
var ypoints3 = [ v + width / 2, v + width / 2, v - width / 2 ];
ctx.strokeStyle = symcolor;
ctx.beginPath();
ctx.moveTo(xpoints3[0], ypoints3[0]);
for (i = 1; i < xpoints3.length; i++) {
ctx.lineTo(xpoints3[i], ypoints3[i]);
}
// ctx.closePath();
ctx.stroke();
ctx.strokeStyle = 'black';
}
else if (symbol == Resources.PlotSymbolsEnum.SYMBOL_TRIANGLEFILLED) {
var xpoints3 = [ h - width / 2, h + width / 2, h ];
var ypoints3 = [ v + width / 2, v + width / 2, v - width / 2 ];
ctx.strokeStyle = symcolor;
ctx.beginPath();
ctx.moveTo(xpoints3[0], ypoints3[0]);
for (i = 1; i < xpoints3.length; i++) {
ctx.lineTo(xpoints3[i], ypoints3[i]);
}
// ctx.closePath();
ctx.fill();
ctx.stroke();
ctx.strokeStyle = 'black';
}
else if (symbol == Resources.PlotSymbolsEnum.SYMBOL_CROSS1) {
ctx.strokeStyle = symcolor;
width += 1;
ctx.beginPath();
ctx.moveTo(h - width / 2, v);
ctx.lineTo(h + width / 2, v);
ctx.moveTo(h, v - width / 2);
ctx.lineTo(h, v + width / 2);
// ctx.closePath();
ctx.stroke();
ctx.strokeStyle = 'black';
}
else if (symbol == Resources.PlotSymbolsEnum.SYMBOL_CROSS2) {
ctx.strokeStyle = symcolor;
ctx.beginPath();
ctx.moveTo(h - width / 2, v - width / 2);
ctx.lineTo(h + width / 2, v + width / 2);
ctx.moveTo(h - width / 2, v + width / 2);
ctx.lineTo(h + width / 2, v - width / 2);
// ctx.closePath();
ctx.stroke();
ctx.strokeStyle = 'black';
}
}
我已经注释掉了关闭路径,因为我并不总是希望形状返回到原始点。我想我最初把它们放进去是因为我误解了 closePath() 的作用,并认为它们会使绘制一个独立于其他符号的符号。
这就是它的名称:
ctx.save();
ctx.rect(left, y1, width, height);
ctx.clip();
.
.
.
y = this.mMonthlyMeans[i];
y = (y - yOrigin) * yScale;
y = Math.floor(y) + 0.5;
plotSymbol(ctx, theMeanSym, this.getPlotLeft() + xCtr, y, theMeanSymSize, theMeanSymbolColor);
ctx.strokeStyle = 'black'; // this call is perhaps unnecessary in properly written code but seems to head off some problems
.
.
.
ctx.restore() // to restore the clip
对于在 HTML5 Canvas 中正确执行此操作的任何建议和指示,我将不胜感激。它看起来不像只是将像素绘制到像 Java 这样的 Graphics2D 对象中那么简单,
【问题讨论】:
标签: javascript html canvas