多次重复使用相同的 canvas 上下文不好吗?
Is it bad to reuse the same canvas context multiple times?
我正在使用 HTML5 canvas
编写模拟器。我制作了一个助手 class 来包含有关 canvas 的信息。目前看起来是这样的:
class Canvas {
context;
width;
height;
constructor(HTMLCanvas) {
this.context = HTMLCanvas.getContext("2d");
this.width = HTMLCanvas.width;
this.height = HTMLCanvas.height;
}
clear() {
this.context.clearRect(0, 0, this.width, this.height);
}
}
每次我在 canvas 上绘制时,我都会重复使用相同的上下文。这是一个坏主意吗?会不会有不可预见的后果?
简单地说:不,那绝对没问题。
为多种目的使用相同的 canvas 上下文很好(事实上,比破坏和重新创建 canvas 只是为了清除和重绘它更可取),但这似乎有些对立到 class,如此处所示。
类 应该 封装 数据,但由于 HTMLCanvas
参数,此处的设置会产生错误的封装感。事实上,如果您创建此 class 的多个实例,它们都共享相同的上下文,当多个 Canvas
实例相互破坏时,可能会导致 class 的客户端出现混乱情况状态。
隐藏 canvas clearRect
函数参数的好处似乎可以忽略不计。当然,您可以添加更多功能以更好地激发它,但仍然存在潜在的数据共享问题以及整个企业的不明确 benefit/payoff 即使共享固定。
下面是我的意思的演示:
class Canvas {
constructor(HTMLCanvas) {
this.context = HTMLCanvas.getContext("2d");
this.width = HTMLCanvas.width;
this.height = HTMLCanvas.height;
}
clear() {
this.context.clearRect(0, 0, this.width, this.height);
}
}
const canvas = document.createElement("canvas");
document.body.append(canvas);
const canvas1 = new Canvas(canvas);
const canvas2 = new Canvas(canvas);
canvas1.context.fillRect(0, 0, 30, 30);
canvas2.context.fillRect(30, 30, 30, 30);
很难看出这里的好处。作为您 class 的客户,我分配了 2 个完整的对象,但它们基本上是同一个 canvas 的视图,导致利用一个对象影响另一个对象 canvas。调用 clear
会擦除两个 canvases 并且实际上没有每个实例的唯一数据可言。我必须明确地提供两个单独的 canvases 才能正常使用,而且在看到任何好处之前,我已经陷入了一个更加冗长和潜在混乱的坑中。
另一个微妙的地方是 class 似乎混淆了 canvases 和上下文。 clear
其实是context操作,所以这里的Canvas
class好像是朝着canvas和context合二为一的组合界面走的。由于大多数 canvas 应用程序主要与上下文一起工作并且仅将 canvas 用于 height/width 引用,这实际上创建了一个很好的关注点分离,将 DOM/canvas 从实体 classes(球、球员、敌人等)负责在任意上下文中绘制自己,而无需了解上下文来自的基础 DOM 对象。
长话短说:
- 你还需要这个吗?画布已经是具有漂亮界面的对象,可能不需要另一层抽象。如果您想抽象常用的绘图函数,可以考虑应用程序中的实体(例如“玩家”实体)并创建使用上下文作为参数的每个实体
draw
函数。
- 如果您确实觉得您的设计需要它,请考虑将 canvas 本身设置为不注入构造函数的“私有”成员。相反,也许传入构造函数将附加 canvas 的父 DOM 元素。
在没有像 React 这样的框架的情况下在 DOM 上编写抽象是很棘手的!
我正在使用 HTML5 canvas
编写模拟器。我制作了一个助手 class 来包含有关 canvas 的信息。目前看起来是这样的:
class Canvas {
context;
width;
height;
constructor(HTMLCanvas) {
this.context = HTMLCanvas.getContext("2d");
this.width = HTMLCanvas.width;
this.height = HTMLCanvas.height;
}
clear() {
this.context.clearRect(0, 0, this.width, this.height);
}
}
每次我在 canvas 上绘制时,我都会重复使用相同的上下文。这是一个坏主意吗?会不会有不可预见的后果?
简单地说:不,那绝对没问题。
为多种目的使用相同的 canvas 上下文很好(事实上,比破坏和重新创建 canvas 只是为了清除和重绘它更可取),但这似乎有些对立到 class,如此处所示。
类 应该 封装 数据,但由于 HTMLCanvas
参数,此处的设置会产生错误的封装感。事实上,如果您创建此 class 的多个实例,它们都共享相同的上下文,当多个 Canvas
实例相互破坏时,可能会导致 class 的客户端出现混乱情况状态。
隐藏 canvas clearRect
函数参数的好处似乎可以忽略不计。当然,您可以添加更多功能以更好地激发它,但仍然存在潜在的数据共享问题以及整个企业的不明确 benefit/payoff 即使共享固定。
下面是我的意思的演示:
class Canvas {
constructor(HTMLCanvas) {
this.context = HTMLCanvas.getContext("2d");
this.width = HTMLCanvas.width;
this.height = HTMLCanvas.height;
}
clear() {
this.context.clearRect(0, 0, this.width, this.height);
}
}
const canvas = document.createElement("canvas");
document.body.append(canvas);
const canvas1 = new Canvas(canvas);
const canvas2 = new Canvas(canvas);
canvas1.context.fillRect(0, 0, 30, 30);
canvas2.context.fillRect(30, 30, 30, 30);
很难看出这里的好处。作为您 class 的客户,我分配了 2 个完整的对象,但它们基本上是同一个 canvas 的视图,导致利用一个对象影响另一个对象 canvas。调用 clear
会擦除两个 canvases 并且实际上没有每个实例的唯一数据可言。我必须明确地提供两个单独的 canvases 才能正常使用,而且在看到任何好处之前,我已经陷入了一个更加冗长和潜在混乱的坑中。
另一个微妙的地方是 class 似乎混淆了 canvases 和上下文。 clear
其实是context操作,所以这里的Canvas
class好像是朝着canvas和context合二为一的组合界面走的。由于大多数 canvas 应用程序主要与上下文一起工作并且仅将 canvas 用于 height/width 引用,这实际上创建了一个很好的关注点分离,将 DOM/canvas 从实体 classes(球、球员、敌人等)负责在任意上下文中绘制自己,而无需了解上下文来自的基础 DOM 对象。
长话短说:
- 你还需要这个吗?画布已经是具有漂亮界面的对象,可能不需要另一层抽象。如果您想抽象常用的绘图函数,可以考虑应用程序中的实体(例如“玩家”实体)并创建使用上下文作为参数的每个实体
draw
函数。 - 如果您确实觉得您的设计需要它,请考虑将 canvas 本身设置为不注入构造函数的“私有”成员。相反,也许传入构造函数将附加 canvas 的父 DOM 元素。
在没有像 React 这样的框架的情况下在 DOM 上编写抽象是很棘手的!