'lineTo' 方法超出 canvas 维度时的性能
Performances of 'lineTo' method when going beyond canvas dimensions
使用 canvas 上下文,假设我调用 beginPath
然后两次 lineTo
与 x=-999, y=-999
和 x=50, y=50
最后 stroke
,它将从左上角到 (50,50) 点画一条线。
在这个过程中,线的左上外侧部分是从外面绘制还是[=36] =]从可见的 canvas 部分绘制,在我们的例子中 (0,0).
在第一种情况下,是否值得使用safeCoordinates
函数来保护坐标,特别是如果我们需要很多点,当例如,我们想绘制一个数学函数。
第二种情况好吧,完美。
参见上面的例子,我有两条没有安全坐标的红线和两条有安全坐标的绿线:
const canvas = document.querySelector('canvas');
const context = canvas.getContext('2d');
// Draw a line between two points
const drawLine = (color, fromX, fromY, toX, toY) => {
context.beginPath();
context.lineWidth = 5;
context.lineTo(fromX, fromY);
context.lineTo(toX, toY);
context.strokeStyle = color;
context.stroke();
}
// Without coordinates safing
drawLine('#F00', -999, -999, 50, 50);
drawLine('#F00', 150, 150, 999 + canvas.width, 999 + canvas.height);
const safeCoordinateX = value =>
value < 0 ? 0 : value > canvas.width ? canvas.width : value;
const safeCoordinateY = value =>
value < 0 ? 0 : value > canvas.height ? canvas.height : value;
const safeCoordinates = (fromX, fromY, toX, toY) =>
[safeCoordinateX(fromX), safeCoordinateY(fromY), safeCoordinateX(toX), safeCoordinateY(toY)];
// With coordinates safing
drawLine('#0F0', ...safeCoordinates(150, 50, 999 + canvas.width, -999));
drawLine('#0F0', ...safeCoordinates(50, 150, -999, 999 + canvas.height));
canvas {
border: 1px solid rgba(0, 0, 0, .5)
}
<canvas width=200 height=200 />
为了回答您的问题,我们需要一个基准。看下面,安全抽签比不安全抽签花费的时间更长。可能是你多算了算。
const canvas = document.querySelector('canvas');
const context = canvas.getContext('2d');
// Draw a line between two points
const drawLine = (color, fromX, fromY, toX, toY) => {
context.beginPath();
context.lineWidth = 5;
context.lineTo(fromX, fromY);
context.lineTo(toX, toY);
context.strokeStyle = color;
context.stroke();
}
const safeCoordinateX = value =>
value < 0 ? 0 : value > canvas.width ? canvas.width : value;
const safeCoordinateY = value =>
value < 0 ? 0 : value > canvas.height ? canvas.height : value;
const safeCoordinates = (fromX, fromY, toX, toY) =>
[safeCoordinateX(fromX), safeCoordinateY(fromY), safeCoordinateX(toX), safeCoordinateY(toY)];
function drawSafe() {
const t = Date.now();
drawLine('#0F0', ...safeCoordinates(150, 50, 999 + canvas.width, -999));
drawLine('#0F0', ...safeCoordinates(50, 150, -999, 999 + canvas.height));
return Date.now() - t;
}
function drawUnsafe() {
const t = Date.now();
drawLine('#F00', -999, -999, 50, 50);
drawLine('#F00', 150, 150, 999 + canvas.width, 999 + canvas.height);
return Date.now() - t;
}
function launchAndCalcTotTime(f) {
let t = 0;
for (let i = 0; i < 100000; i += 1) {
t += f();
}
return t;
}
console.log(`Safe draw took ${launchAndCalcTotTime(drawSafe)}ms`);
console.log(`Unsafe draw took ${launchAndCalcTotTime(drawUnsafe)}ms`);
canvas {
border: 1px solid rgba(0, 0, 0, .5)
}
<canvas width=200 height=200 />
为了确定这一点,您还可以尝试画一条额外的大线,看看它是否会改变结果。如果画了线,那么它应该减慢执行速度。但答案是否定的。
const canvas = document.querySelector('canvas');
const context = canvas.getContext('2d');
// Draw a line between two points
const drawLine = (color, fromX, fromY, toX, toY) => {
context.beginPath();
context.lineWidth = 5;
context.lineTo(fromX, fromY);
context.lineTo(toX, toY);
context.strokeStyle = color;
context.stroke();
}
const safeCoordinateX = value =>
value < 0 ? 0 : value > canvas.width ? canvas.width : value;
const safeCoordinateY = value =>
value < 0 ? 0 : value > canvas.height ? canvas.height : value;
const safeCoordinates = (fromX, fromY, toX, toY) =>
[safeCoordinateX(fromX), safeCoordinateY(fromY), safeCoordinateX(toX), safeCoordinateY(toY)];
function drawSafe() {
const t = Date.now();
drawLine('#0F0', ...safeCoordinates(150, 50, 999 + canvas.width, -999));
drawLine('#0F0', ...safeCoordinates(50, 150, -999, 999 + canvas.height));
return Date.now() - t;
}
function drawUnsafe() {
const t = Date.now();
drawLine('#F00', -999999999, -999999999, 5000000000, 500000000);
drawLine('#F00', 0, 0, 9990000000 + canvas.width, 9990000000 + canvas.height);
return Date.now() - t;
}
function launchAndCalcTotTime(f) {
let t = 0;
for (let i = 0; i < 100000; i += 1) {
t += f();
}
return t;
}
console.log(`Safe draw took ${launchAndCalcTotTime(drawSafe)}ms`);
console.log(`Unsafe draw took ${launchAndCalcTotTime(drawUnsafe)}ms`);
canvas {
border: 1px solid rgba(0, 0, 0, .5)
}
<canvas width=200 height=200 />
使用 canvas 上下文,假设我调用 beginPath
然后两次 lineTo
与 x=-999, y=-999
和 x=50, y=50
最后 stroke
,它将从左上角到 (50,50) 点画一条线。
在这个过程中,线的左上外侧部分是从外面绘制还是[=36] =]从可见的 canvas 部分绘制,在我们的例子中 (0,0).
在第一种情况下,是否值得使用
safeCoordinates
函数来保护坐标,特别是如果我们需要很多点,当例如,我们想绘制一个数学函数。第二种情况好吧,完美。
参见上面的例子,我有两条没有安全坐标的红线和两条有安全坐标的绿线:
const canvas = document.querySelector('canvas');
const context = canvas.getContext('2d');
// Draw a line between two points
const drawLine = (color, fromX, fromY, toX, toY) => {
context.beginPath();
context.lineWidth = 5;
context.lineTo(fromX, fromY);
context.lineTo(toX, toY);
context.strokeStyle = color;
context.stroke();
}
// Without coordinates safing
drawLine('#F00', -999, -999, 50, 50);
drawLine('#F00', 150, 150, 999 + canvas.width, 999 + canvas.height);
const safeCoordinateX = value =>
value < 0 ? 0 : value > canvas.width ? canvas.width : value;
const safeCoordinateY = value =>
value < 0 ? 0 : value > canvas.height ? canvas.height : value;
const safeCoordinates = (fromX, fromY, toX, toY) =>
[safeCoordinateX(fromX), safeCoordinateY(fromY), safeCoordinateX(toX), safeCoordinateY(toY)];
// With coordinates safing
drawLine('#0F0', ...safeCoordinates(150, 50, 999 + canvas.width, -999));
drawLine('#0F0', ...safeCoordinates(50, 150, -999, 999 + canvas.height));
canvas {
border: 1px solid rgba(0, 0, 0, .5)
}
<canvas width=200 height=200 />
为了回答您的问题,我们需要一个基准。看下面,安全抽签比不安全抽签花费的时间更长。可能是你多算了算。
const canvas = document.querySelector('canvas');
const context = canvas.getContext('2d');
// Draw a line between two points
const drawLine = (color, fromX, fromY, toX, toY) => {
context.beginPath();
context.lineWidth = 5;
context.lineTo(fromX, fromY);
context.lineTo(toX, toY);
context.strokeStyle = color;
context.stroke();
}
const safeCoordinateX = value =>
value < 0 ? 0 : value > canvas.width ? canvas.width : value;
const safeCoordinateY = value =>
value < 0 ? 0 : value > canvas.height ? canvas.height : value;
const safeCoordinates = (fromX, fromY, toX, toY) =>
[safeCoordinateX(fromX), safeCoordinateY(fromY), safeCoordinateX(toX), safeCoordinateY(toY)];
function drawSafe() {
const t = Date.now();
drawLine('#0F0', ...safeCoordinates(150, 50, 999 + canvas.width, -999));
drawLine('#0F0', ...safeCoordinates(50, 150, -999, 999 + canvas.height));
return Date.now() - t;
}
function drawUnsafe() {
const t = Date.now();
drawLine('#F00', -999, -999, 50, 50);
drawLine('#F00', 150, 150, 999 + canvas.width, 999 + canvas.height);
return Date.now() - t;
}
function launchAndCalcTotTime(f) {
let t = 0;
for (let i = 0; i < 100000; i += 1) {
t += f();
}
return t;
}
console.log(`Safe draw took ${launchAndCalcTotTime(drawSafe)}ms`);
console.log(`Unsafe draw took ${launchAndCalcTotTime(drawUnsafe)}ms`);
canvas {
border: 1px solid rgba(0, 0, 0, .5)
}
<canvas width=200 height=200 />
为了确定这一点,您还可以尝试画一条额外的大线,看看它是否会改变结果。如果画了线,那么它应该减慢执行速度。但答案是否定的。
const canvas = document.querySelector('canvas');
const context = canvas.getContext('2d');
// Draw a line between two points
const drawLine = (color, fromX, fromY, toX, toY) => {
context.beginPath();
context.lineWidth = 5;
context.lineTo(fromX, fromY);
context.lineTo(toX, toY);
context.strokeStyle = color;
context.stroke();
}
const safeCoordinateX = value =>
value < 0 ? 0 : value > canvas.width ? canvas.width : value;
const safeCoordinateY = value =>
value < 0 ? 0 : value > canvas.height ? canvas.height : value;
const safeCoordinates = (fromX, fromY, toX, toY) =>
[safeCoordinateX(fromX), safeCoordinateY(fromY), safeCoordinateX(toX), safeCoordinateY(toY)];
function drawSafe() {
const t = Date.now();
drawLine('#0F0', ...safeCoordinates(150, 50, 999 + canvas.width, -999));
drawLine('#0F0', ...safeCoordinates(50, 150, -999, 999 + canvas.height));
return Date.now() - t;
}
function drawUnsafe() {
const t = Date.now();
drawLine('#F00', -999999999, -999999999, 5000000000, 500000000);
drawLine('#F00', 0, 0, 9990000000 + canvas.width, 9990000000 + canvas.height);
return Date.now() - t;
}
function launchAndCalcTotTime(f) {
let t = 0;
for (let i = 0; i < 100000; i += 1) {
t += f();
}
return t;
}
console.log(`Safe draw took ${launchAndCalcTotTime(drawSafe)}ms`);
console.log(`Unsafe draw took ${launchAndCalcTotTime(drawUnsafe)}ms`);
canvas {
border: 1px solid rgba(0, 0, 0, .5)
}
<canvas width=200 height=200 />