【发布时间】:2017-06-29 21:32:03
【问题描述】:
我正在尝试在不使用图像的情况下在 HTML5 Canvas 中生成基本的瓷砖和楼梯。
这是我到目前为止所做的:
但我正在尝试重现:
我不知道该怎么做。
这是我当前的代码:
class IsometricGraphics {
constructor(canvas, thickness) {
this.Canvas = canvas;
this.Context = canvas.getContext("2d");
if(thickness) {
this.thickness = thickness;
} else {
this.thickness = 2;
}
}
LeftPanelWide(x, y, fillStyle) {
this.Context.fillStyle = fillStyle;
for(var i = 0; i < 16; i++) {
this.Context.fillRect(x + i * 2, y + i * 1, 2, this.thickness * 4);
}
}
RightPanelWide(x, y, fillStyle) {
this.Context.fillStyle = fillStyle;
for(var i = 0; i < 16; i++) {
this.Context.fillRect(x + (i * 2), y + 15 - (i * 1), 2, this.thickness * 4);
}
}
UpperPanelWide(x, y, fillStyle) {
this.Context.fillStyle = fillStyle;
for(var i = 0; i < 17; i++) {
this.Context.fillRect(x + 16 + 16 - (i * 2), y + i - 2, i * 4, 1);
}
for(var i = 0; i < 16; i++) {
this.Context.fillRect(x + i * 2, y + (32 / 2) - 1 + i, ((32 / 2) - i) * 4, 1);
}
}
UpperPanelWideBorder(x, y, fillStyle) {
this.Context.fillStyle = fillStyle;
var y = y + 2;
for(var i = 0; i < 17; i++) {
this.Context.fillRect(x + 17 + 16 - (i * 2) - 2, y + i - 2, (i == 17) ? 1 : 2, 1);
this.Context.fillRect(x + 17 + 16 + (i * 2) - 2, y + i - 2, (i == 17) ? 1 : 2, 1);
}
for(var i = 0; i < 32 / 2; i++) {
this.Context.fillRect(x + i * 2, y + 16 - 1 + i, 2, 1);
this.Context.fillRect(x + 62 - i * 2, y + 16 - 1 + i, 2, 1);
}
}
RightUpperPanelSmall(x, y, fillStyle) {
this.Context.fillStyle = fillStyle;
for(var i = 0; i < 32 / 2 + 4; i++) {
this.Context.fillRect(x + (i * 2), (i >= 4) ? (i - 1) + y : 3 - i + 3 + y, 2, (i >= 4) ? (i <= 20 - 5) ? 8 : (20 - i) * 2 - 1 : 1 + (i * 2));
}
}
LeftUpperPanelSmall(x, y, fillStyle) {
this.Context.fillStyle = fillStyle;
for(var i = 0; i < 32 / 2 + 4; i++) {
this.Context.fillRect(x + (i * 2), (i >= 16) ? y + (i - 16) : 16 + y - (i * 1) - 1, 2, (i >= 4) ? (i >= 16) ? 8 - (i - 16) - (i - 16) - 1 : 8 : 8 * i - (i * 6) + 1);
}
}
LeftPanelSmall(x, y, fillStyle) {
this.Context.fillStyle = fillStyle;
for(var i = 0; i < 8 / 2; i++) {
this.Context.fillRect(x + i * 2, y + i * 1, 2, this.thickness * 4);
}
}
RightPanelSmall(x, y, fillStyle) {
this.Context.fillStyle = fillStyle;
for(var i = 0; i < 8 / 2; i++) {
this.Context.fillRect(x + (i * 2), y + 3 - (i * 1), 2, this.thickness * 4);
}
}
}
class IsoGenerator {
constructor() {
var Canvas = document.querySelector("canvas");
var Context = Canvas.getContext("2d");
//Context.scale(5, 5);
this.Context = Context;
this.IsometricGraphics = new IsometricGraphics(Canvas, 2);
}
StairLeft(x, y, Color1, Color2, Color3) {
for(var i = 0; i < 4; i++) {
this.IsometricGraphics.RightPanelWide((x + 8) + (i * 8), (y + 4) + (i * 12), Color1);
this.IsometricGraphics.LeftUpperPanelSmall(x + (i * 8), y + (i * 12), Color2);
this.IsometricGraphics.LeftPanelSmall((i * 8) + x, (16 + (i * 12)) + y, Color3);
}
}
StairRight(x, y, Color1, Color2, Color3) {
for(var i = 0; i < 4; i++) {
this.IsometricGraphics.LeftPanelWide(x + 24 - (i * 8), (4 + (i * 12)) + y, Color1);
this.IsometricGraphics.RightUpperPanelSmall(x + 24 - (i * 8), y + (i * 12) - 3, Color2);
this.IsometricGraphics.RightPanelSmall(x + 56 - (i * 8), (16 + (i * 12)) + y, Color3);
}
}
Tile(x, y, Color1, Color2, Color3, Border) {
this.IsometricGraphics.LeftPanelWide(x, 18 + y, Color1);
this.IsometricGraphics.RightPanelWide(x + 32, 18 + y, Color2);
this.IsometricGraphics.UpperPanelWide(x, 2 + y, Color3);
if(Border) {
this.IsometricGraphics.UpperPanelWideBorder(x, y, Border);
}
}
}
var Canvas = document.querySelector("canvas");
var Context = Canvas.getContext("2d");
Context.scale(3, 3);
new IsoGenerator().Tile(0, 0, "#B3E5FC", "#2196F3", "#03A9F4")
new IsoGenerator().StairLeft(70, 0, "#B3E5FC", "#2196F3", "#03A9F4")
new IsoGenerator().StairRight(70 * 2, 0, "#B3E5FC", "#2196F3", "#03A9F4")
// What I'm trying to reproduce: http://i.imgur.com/YF4xyz9.png
<canvas width="1000" height="1000"></canvas>
【问题讨论】:
-
首先,整洁!我的第一个想法是把它想象成一堆堆叠的第一个平台,每个平台都变小了。我现在正在根据您的代码寻找答案。
-
如果在我今晚有时间继续工作之前你没有得到答案,这就是我要去的方向。
new IsoGenerator().Stack(0, 0, 4, "#B3E5FC", "#2196F3", "#03A9F4")然后 Tile 需要多取 x, y。 stack的z index是Tiles的个数。 -
@mkaatman 谢谢!为什么需要 z 索引?只需使用像
for(var i = 4; i >= 0; i--)这样的反向循环,然后最后会绘制最小的图块/平台 -
@mkaatman 我做了一些实验,如果这可以帮助你jsfiddle.net/xvak0jh1/1
-
我想我在想你会从顶部开始,你可以随心所欲地堆高。如果您只想要 4,那么您可能可以对其进行硬编码。
标签: javascript html canvas isometric axonometric