Skip to content

Commit 2490507

Browse files
committed
Graphics canvas rendering
1 parent ad07334 commit 2490507

3 files changed

Lines changed: 169 additions & 135 deletions

File tree

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
module.exports = {
2+
ARC: 0,
3+
BEGIN_FILL: 1,
4+
END_FILL: 2,
5+
DRAW_CIRCLE: 3,
6+
DRAW_RECT: 4,
7+
LINE_TO: 5,
8+
MOVE_TO: 6
9+
};

v3/src/gameobjects/graphics/Graphics.js

Lines changed: 48 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -2,71 +2,8 @@ var Class = require('../../utils/Class');
22
var GameObject = require('../GameObject');
33
var Components = require('../../components');
44
var Render = require('./GraphicsRender');
5+
var Commands = require('./Commands');
56

6-
/* This is specific to Graphics internal */
7-
var GraphicsPointPool = [];
8-
var GraphicsPathPool = [];
9-
var MakeGraphicsPoint = function (x, y)
10-
{
11-
var point;
12-
if (GraphicsPointPool.length > 0)
13-
{
14-
point = GraphicsPointPool.pop();
15-
point.x = x;
16-
point.y = y;
17-
}
18-
else
19-
{
20-
point = new GraphicsPoint(x, y);
21-
}
22-
return point;
23-
};
24-
var MakeGraphicsPath = function (x, y, color) {
25-
var path;
26-
if (GraphicsPathPool.length > 0)
27-
{
28-
path = GraphicsPathPool.pop();
29-
path.points.length = 0;
30-
path.points.push({x: x, y: y});
31-
}
32-
else
33-
{
34-
path = new GraphicsPath(x, y);
35-
}
36-
path.color = color;
37-
return path;
38-
};
39-
var RecycleGraphicsPoint = function (point) {
40-
var index = GraphicsPointPool.indexOf(point);
41-
if (index < 0)
42-
{
43-
GraphicsPointPool.push(point);
44-
}
45-
};
46-
var RecycleGraphicsPath = function (path) {
47-
var index = GraphicsPathPool.indexOf(path);
48-
if (index < 0)
49-
{
50-
GraphicsPathPool.push(path);
51-
}
52-
};
53-
var GraphicsPoint = function (x, y)
54-
{
55-
this.x = x;
56-
this.y = y;
57-
};
58-
var GraphicsPath = function (x, y, color)
59-
{
60-
this.color = color;
61-
this.points = [];
62-
this.points.push(MakeGraphicsPoint(x, y));
63-
};
64-
var lerp = function (norm, min, max)
65-
{
66-
return (max - min) * norm + min;
67-
};
68-
var cos = Math.cos;
69-
var sin = Math.sin;
707
var Graphics = new Class({
718

729
Mixins: [
@@ -82,92 +19,68 @@ var Graphics = new Class({
8219
function Graphics (state, x, y)
8320
{
8421
GameObject.call(this, state);
85-
86-
this._lastPath = null;
87-
this._pathArray = [];
88-
this._lastColor = 0xFFFFFFFF;
89-
22+
this.commandBuffer = [];
9023
this.setPosition(x, y);
9124
},
9225

93-
arc: function (x, y, radius, startAngle, endAngle, anticlockwise) {
94-
var iteration = 0;
95-
var iterStep = 0.01;
96-
var tx = 0;
97-
var ty = 0;
98-
var ta = 0;
99-
var moveTo = this.moveTo;
100-
var lineTo = this.lineTo;
101-
while (iteration < 1) {
102-
ta = lerp(iteration, startAngle, endAngle);
103-
tx = x + cos(ta) * radius;
104-
ty = y + sin(ta) * radius;
105-
if (iteration === 0) {
106-
moveTo(tx, ty);
107-
} else {
108-
lineTo(tx, ty);
109-
}
110-
iteration += iterStep;
111-
}
26+
arc: function (x, y, radius, startAngle, endAngle, anticlockwise)
27+
{
28+
this.commandBuffer.push(
29+
Commands.ARC,
30+
x, y, radius, startAngle, endAngle, anticlockwise
31+
);
11232
},
11333

114-
beginFill: function (color) {
115-
this.clear();
116-
this._lastColor = color;
34+
beginFill: function (color)
35+
{
36+
this.commandBuffer.push(
37+
Commands.BEGIN_FILL,
38+
color
39+
);
11740
},
11841

119-
endFill: function () {
120-
var lastPath = this._lastPath;
121-
if (lastPath !== null && lastPath.point.length > 0)
122-
{
123-
var firstPoint = lastPath.points[0];
124-
var lastPoint = lastPath.points[lastPath.points.length - 1];
125-
lastPath.points.push(firstPoint);
126-
this.moveTo(lastPoint.x, lastPoint.y);
127-
}
42+
endFill: function ()
43+
{
44+
this.commandBuffer.push(
45+
Commands.END_FILL
46+
);
12847
},
12948

130-
clear: function () {
131-
var path;
132-
var points;
133-
var pathArray = this._pathArray;
134-
var pointIndex = 0;
135-
for (var pathIndex = 0, pathLength = pathArray.length; pathIndex < pathLength; ++pathIndex)
136-
{
137-
path = pathArray[pathIndex];
138-
points = path.points;
139-
RecycleGraphicsPoint(path);
140-
for (pointIndex = 0, pointsLength = points.length; pointIndex < pointsLength; ++pointIndex)
141-
{
142-
RecycleGraphicsPoint(points[pointIndex]);
143-
}
144-
points.length = 0;
145-
}
146-
pathArray.length = 0;
147-
this._lastColor = 0xFFFFFFFF;
148-
this._lastPath = null;
49+
drawCircle: function (x, y, radius)
50+
{
51+
this.commandBuffer.push(
52+
Commands.DRAW_CIRCLE,
53+
x, y, radius
54+
);
14955
},
15056

151-
drawCircle: function (x, y, diameter) {},
152-
153-
drawPolygon: function (path) {},
57+
drawRect: function (x, y, width, height)
58+
{
59+
this.commandBuffer.push(
60+
Commands.DRAW_RECT,
61+
x, y, width, height
62+
);
63+
},
15464

155-
drawRect: function (x, y, width, height) {},
65+
lineTo: function (x, y)
66+
{
67+
this.commandBuffer.push(
68+
Commands.LINE_TO,
69+
x, y
70+
);
71+
},
15672

157-
lineTo: function (x, y) {
158-
if (this._lastPath !== null)
159-
{
160-
this._lastPath.points.push(MakeGraphicsPath(x, y, this._lastColor));
161-
}
162-
else
163-
{
164-
this.moveTo(x, y);
165-
}
73+
moveTo: function (x, y)
74+
{
75+
this.commandBuffer.push(
76+
Commands.MOVE_TO,
77+
x, y
78+
);
16679
},
16780

168-
moveTo: function (x, y) {
169-
this._lastPath = MakeGraphicsPath(x, y, this._lastColor);
170-
this._pathArray.push(this._lastPath);
81+
clear: function ()
82+
{
83+
commandBuffer.length = 0;
17184
}
17285
});
17386

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,121 @@
1+
var Commands = require('./Commands');
2+
var PI2 = 2 * Math.PI;
13
var GraphicsCanvasRenderer = function (renderer, src, interpolationPercentage, camera)
24
{
35
if (this.renderMask !== this.renderFlags)
46
{
57
return;
68
}
9+
var cameraScrollX = camera.scrollX;
10+
var cameraScrollY = camera.scrollY;
11+
var srcX = src.x;
12+
var srcY = src.y;
13+
var srcScaleX = src.scaleX;
14+
var srcScaleY = src.scaleY;
15+
var srcRotation = src.rotation;
16+
var commandBuffer = src.commandBuffer;
17+
var ctx = renderer.currentContext;
18+
var value;
19+
20+
// Blend Mode
21+
if (renderer.currentBlendMode !== src.blendMode)
22+
{
23+
renderer.currentBlendMode = src.blendMode;
24+
ctx.globalCompositeOperation = renderer.blendModes[src.blendMode];
25+
}
26+
27+
// Alpha
28+
if (renderer.currentAlpha !== src.alpha)
29+
{
30+
renderer.currentAlpha = src.alpha;
31+
ctx.globalAlpha = src.alpha;
32+
}
33+
34+
// Smoothing
35+
if (renderer.currentScaleMode !== src.scaleMode)
36+
{
37+
renderer.currentScaleMode = src.scaleMode;
38+
}
39+
40+
ctx.save();
41+
ctx.translate(srcX, srcY);
42+
ctx.rotate(srcRotation);
43+
ctx.scale(srcScaleX, srcScaleY);
44+
ctx.fillStyle = '#fff';
45+
ctx.globalAlpha = src.alpha;
46+
47+
for (var index = 0, length = commandBuffer.length; index < length; ++index)
48+
{
49+
var commandID = commandBuffer[index];
50+
51+
switch(commandID)
52+
{
53+
case Commands.ARC:
54+
ctx.arc(
55+
commandBuffer[index + 1],
56+
commandBuffer[index + 2],
57+
commandBuffer[index + 3],
58+
commandBuffer[index + 4],
59+
commandBuffer[index + 5],
60+
commandBuffer[index + 6]
61+
);
62+
index += 6;
63+
break;
64+
case Commands.BEGIN_FILL:
65+
value = commandBuffer[index + 1];
66+
ctx.fillStyle = 'rgb(' + ((value & 0xFF0000) >>> 16) + ',' + ((value & 0xFF00) >>> 8) + ',' + (value & 0xFF) + ')';
67+
ctx.beginPath();
68+
index += 1;
69+
break;
70+
case Commands.END_FILL:
71+
ctx.fill();
72+
ctx.closePath();
73+
ctx.fillStyle = '#fff';
74+
break;
75+
case Commands.DRAW_CIRCLE:
76+
ctx.beginPath();
77+
ctx.arc(
78+
commandBuffer[index + 1],
79+
commandBuffer[index + 2],
80+
commandBuffer[index + 3],
81+
0,
82+
PI2
83+
);
84+
ctx.fill();
85+
ctx.closePath();
86+
index += 3;
87+
break;
88+
case Commands.DRAW_RECT:
89+
ctx.fillRect(
90+
commandBuffer[index + 1],
91+
commandBuffer[index + 2],
92+
commandBuffer[index + 3],
93+
commandBuffer[index + 4]
94+
);
95+
index += 4;
96+
break;
97+
case Commands.LINE_TO:
98+
ctx.lineTo(
99+
commandBuffer[index + 1],
100+
commandBuffer[index + 2]
101+
);
102+
index += 2;
103+
break;
104+
case Commands.MOVE_TO:
105+
ctx.moveTo(
106+
commandBuffer[index + 1],
107+
commandBuffer[index + 2]
108+
);
109+
index += 2;
110+
break;
111+
default:
112+
console.error('Phaser: Invalid Graphics Command ID ' + commandID);
113+
break;
114+
}
115+
}
116+
117+
ctx.restore();
118+
ctx.globalAlpha = 1.0;
7119
}
8120

9121
module.exports = GraphicsCanvasRenderer;

0 commit comments

Comments
 (0)