简化绘制 canvas
Simplify draw on canvas
忘掉函数之外的一些东西(只是为了在 fiddle 上说清楚,它是更大代码的一部分。
基本上我有这部分:
var drawDataSet = function (dataset) {
context.lineWidth = 1;
context.save();
context.beginPath();
var angle = (Math.PI) / (dataset.data.length / 2);
for (var i = 0; i < dataset.data.length; i++) {
var height = ((canvas.height / 2 * dataset.data[i]) / 100);
context.lineTo(Math.cos(angle * i) * height, -Math.sin(angle * i) * height);
}
var height = ((canvas.height / 2 * dataset.data[0]) / 100);
context.lineTo(height, 0);
context.closePath();
context.strokeStyle = dataset.strokeColor;
context.stroke();
context.fillStyle = dataset.fillColor;
context.fill();
context.fillStyle = dataset.pointfillColor;
context.fillStyle = dataset.pointStrokeColor;
for (var i = 0; i < dataset.data.length; i++) {
var height = ((canvas.height / 2 * dataset.data[i]) / 100);
drawPoint(Math.cos(angle * i) * height, -Math.sin(angle * i) * height, 3);
}
context.restore();
}
drawPoint = function (x,y,w) {
context.beginPath();
context.arc(x, y, w, 0, 2 * Math.PI, true);
context.stroke();
context.fill();
context.closePath();
}
我想知道是否有更简单更好的方法来画同样的东西
实际上我在不同的位置做了两次完全相同的循环。这是因为如果我在同一个循环中绘制所有内容,一切都会中断,因为 closePath
关闭了所有路径。如果我删除 closePath
,它只会破坏填充和描边。
是否可以将 drawPoint
和 drawLine
放在同一个循环中?
从技术上讲,是的...
您可以在一个循环中合并您的抽奖
通过在绘制当前线和点时保存和恢复上下文,您可以通过一个循环同时绘制线和点。并且必须进行一些合成,以保持你的线条落后于你的点。
var canvas=document.getElementById("canvas");
var context=canvas.getContext("2d");
var points=[ {x:25,y:50},{x:100,y:25},{x:150,y:85},{x:125,y:100},{x:25,y:50} ];
var lastX,lastY;
lastX=points[0].x;
lastY=points[0].y;
for(var i=1;i<points.length;i++){
var p=points[i];
drawLine(lastX,lastY,p.x,p.y,'green');
drawPoint(p.x,p.y,3,'blue','red');
lastX=p.x;
lastY=p.y;
}
function drawLine(x0,y0,x1,y1,stroke){
context.save();
context.globalCompositeOperation='destination-over';
context.lineWidth=2;
context.beginPath();
context.moveTo(x0,y0);
context.lineTo(x1,y1);
context.strokeStyle=stroke;
context.stroke();
context.restore();
}
function drawPoint(x,y,w,fill,stroke) {
context.save();
context.lineWidth=2;
context.beginPath();
context.arc(x, y, w, 0, 2 * Math.PI, true);
context.strokeStyle=stroke;
context.fillStyle=fill;
context.stroke();
context.fill();
context.closePath();
context.restore();
}
body{ background-color:white; }
#canvas{border:1px solid red;}
<canvas id="canvas" width=300 height=300></canvas>
或者,如果您愿意为两个 strokeStyle fillStyle 使用一种颜色,您可以在单个 beginPath
中绘制线条和点。
但是...如果您在单独的循环中绘制线和点,性能会更好
保存和恢复上下文的成本适中。
由于您不断地保存和恢复,与不保存和恢复的情况下执行 2 个循环相比,您会损失性能。
忘掉函数之外的一些东西(只是为了在 fiddle 上说清楚,它是更大代码的一部分。
基本上我有这部分:
var drawDataSet = function (dataset) {
context.lineWidth = 1;
context.save();
context.beginPath();
var angle = (Math.PI) / (dataset.data.length / 2);
for (var i = 0; i < dataset.data.length; i++) {
var height = ((canvas.height / 2 * dataset.data[i]) / 100);
context.lineTo(Math.cos(angle * i) * height, -Math.sin(angle * i) * height);
}
var height = ((canvas.height / 2 * dataset.data[0]) / 100);
context.lineTo(height, 0);
context.closePath();
context.strokeStyle = dataset.strokeColor;
context.stroke();
context.fillStyle = dataset.fillColor;
context.fill();
context.fillStyle = dataset.pointfillColor;
context.fillStyle = dataset.pointStrokeColor;
for (var i = 0; i < dataset.data.length; i++) {
var height = ((canvas.height / 2 * dataset.data[i]) / 100);
drawPoint(Math.cos(angle * i) * height, -Math.sin(angle * i) * height, 3);
}
context.restore();
}
drawPoint = function (x,y,w) {
context.beginPath();
context.arc(x, y, w, 0, 2 * Math.PI, true);
context.stroke();
context.fill();
context.closePath();
}
我想知道是否有更简单更好的方法来画同样的东西
实际上我在不同的位置做了两次完全相同的循环。这是因为如果我在同一个循环中绘制所有内容,一切都会中断,因为 closePath
关闭了所有路径。如果我删除 closePath
,它只会破坏填充和描边。
是否可以将 drawPoint
和 drawLine
放在同一个循环中?
从技术上讲,是的...
您可以在一个循环中合并您的抽奖
通过在绘制当前线和点时保存和恢复上下文,您可以通过一个循环同时绘制线和点。并且必须进行一些合成,以保持你的线条落后于你的点。
var canvas=document.getElementById("canvas");
var context=canvas.getContext("2d");
var points=[ {x:25,y:50},{x:100,y:25},{x:150,y:85},{x:125,y:100},{x:25,y:50} ];
var lastX,lastY;
lastX=points[0].x;
lastY=points[0].y;
for(var i=1;i<points.length;i++){
var p=points[i];
drawLine(lastX,lastY,p.x,p.y,'green');
drawPoint(p.x,p.y,3,'blue','red');
lastX=p.x;
lastY=p.y;
}
function drawLine(x0,y0,x1,y1,stroke){
context.save();
context.globalCompositeOperation='destination-over';
context.lineWidth=2;
context.beginPath();
context.moveTo(x0,y0);
context.lineTo(x1,y1);
context.strokeStyle=stroke;
context.stroke();
context.restore();
}
function drawPoint(x,y,w,fill,stroke) {
context.save();
context.lineWidth=2;
context.beginPath();
context.arc(x, y, w, 0, 2 * Math.PI, true);
context.strokeStyle=stroke;
context.fillStyle=fill;
context.stroke();
context.fill();
context.closePath();
context.restore();
}
body{ background-color:white; }
#canvas{border:1px solid red;}
<canvas id="canvas" width=300 height=300></canvas>
或者,如果您愿意为两个 strokeStyle fillStyle 使用一种颜色,您可以在单个 beginPath
中绘制线条和点。
但是...如果您在单独的循环中绘制线和点,性能会更好
保存和恢复上下文的成本适中。
由于您不断地保存和恢复,与不保存和恢复的情况下执行 2 个循环相比,您会损失性能。