mirror of
https://github.com/photonstorm/phaser
synced 2024-12-01 00:49:41 +00:00
Added getStartPoint and draw methods to all curves and paths.
This commit is contained in:
parent
6631985a3e
commit
8a4fff945c
6 changed files with 298 additions and 68 deletions
|
@ -2,18 +2,20 @@
|
||||||
|
|
||||||
var Class = require('../utils/Class');
|
var Class = require('../utils/Class');
|
||||||
var LineCurve = require('./curves/line/LineCurve');
|
var LineCurve = require('./curves/line/LineCurve');
|
||||||
|
var SplineCurve = require('./curves/spline/SplineCurve');
|
||||||
|
var CubicBezierCurve = require('./curves/cubicbezier/CubicBezierCurve');
|
||||||
var Vector2 = require('../math/Vector2');
|
var Vector2 = require('../math/Vector2');
|
||||||
|
|
||||||
// Local cache vars
|
// Local cache vars
|
||||||
|
|
||||||
var tmpVec2A = new Vector2();
|
var tmpVec2A = new Vector2();
|
||||||
// var tmpVec2B = new Vector2();
|
var tmpVec2B = new Vector2();
|
||||||
|
|
||||||
var Path = new Class({
|
var Path = new Class({
|
||||||
|
|
||||||
initialize:
|
initialize:
|
||||||
|
|
||||||
function Path ()
|
function Path (x, y)
|
||||||
{
|
{
|
||||||
this.curves = [];
|
this.curves = [];
|
||||||
|
|
||||||
|
@ -21,29 +23,66 @@ var Path = new Class({
|
||||||
|
|
||||||
// Automatically closes the path
|
// Automatically closes the path
|
||||||
this.autoClose = false;
|
this.autoClose = false;
|
||||||
|
|
||||||
|
this.startPoint = new Vector2(x, y);
|
||||||
},
|
},
|
||||||
|
|
||||||
// If x2/y2 are not given then it creates a line between the previous curve end point (or 0x0) and x1,y1
|
// Creates a line curve from the previous end point to x/y
|
||||||
addLineCurve: function (x1, y1, x2, y2)
|
lineTo: function (x, y)
|
||||||
{
|
{
|
||||||
if (x2 === undefined && y2 === undefined)
|
if (x instanceof Vector2)
|
||||||
{
|
{
|
||||||
// Create a line from the previous end point to x1/y1
|
tmpVec2B.copy(x);
|
||||||
x2 = x1;
|
|
||||||
y2 = y1;
|
|
||||||
|
|
||||||
var end = this.getEndPoint(tmpVec2A);
|
|
||||||
|
|
||||||
this.curves.push(new LineCurve([ end.x, end.y, x2, y2 ]));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this.curves.push(new LineCurve([ x1, y1, x2, y2 ]));
|
tmpVec2B.set(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
var end = this.getEndPoint(tmpVec2A);
|
||||||
|
|
||||||
|
return this.add(new LineCurve([ end.x, end.y, tmpVec2B.x, tmpVec2B.y ]));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Creates a spline curve starting at the previous end point, using the given parameters
|
||||||
|
splineTo: function (points)
|
||||||
|
{
|
||||||
|
points.shift(this.getEndPoint());
|
||||||
|
|
||||||
|
return this.add(new SplineCurve(points));
|
||||||
|
},
|
||||||
|
|
||||||
|
// Creates a cubic bezier curve starting at the previous end point and ending at p3, using p1 and p2 as control points
|
||||||
|
cubicBezierTo: function (x, y, control1X, control1Y, control2X, control2Y)
|
||||||
|
{
|
||||||
|
var p0 = this.getEndPoint();
|
||||||
|
var p1;
|
||||||
|
var p2;
|
||||||
|
var p3;
|
||||||
|
|
||||||
|
// Assume they're all vec2s
|
||||||
|
if (x instanceof Vector2)
|
||||||
|
{
|
||||||
|
p1 = x;
|
||||||
|
p2 = y;
|
||||||
|
p3 = control1X;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p1 = new Vector2(control1X, control1Y);
|
||||||
|
p2 = new Vector2(control2X, control2Y);
|
||||||
|
p3 = new Vector2(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.add(new CubicBezierCurve(p0, p1, p2, p3));
|
||||||
|
},
|
||||||
|
|
||||||
|
// Creates an ellipse curve positioned at the previous end point, using the given parameters
|
||||||
|
// ellipseTo: function (xRadius, yRadius, startAngle, endAngle, clockwise, rotation)
|
||||||
|
// {
|
||||||
|
// function EllipseCurve (x, y, xRadius, yRadius, startAngle, endAngle, clockwise, rotation)
|
||||||
|
// },
|
||||||
|
|
||||||
add: function (curve)
|
add: function (curve)
|
||||||
{
|
{
|
||||||
this.curves.push(curve);
|
this.curves.push(curve);
|
||||||
|
@ -61,7 +100,7 @@ var Path = new Class({
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
out.set(0, 0);
|
out.copy(this.startPoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
|
@ -227,6 +266,16 @@ var Path = new Class({
|
||||||
}
|
}
|
||||||
|
|
||||||
return points;
|
return points;
|
||||||
|
},
|
||||||
|
|
||||||
|
draw: function (graphics, pointsTotal)
|
||||||
|
{
|
||||||
|
for (var i = 0; i < this.curves.length; i++)
|
||||||
|
{
|
||||||
|
this.curves[i].draw(graphics, pointsTotal);
|
||||||
|
}
|
||||||
|
|
||||||
|
return graphics;
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
// Based on the three.js Curve classes created by [zz85](http://www.lab4games.net/zz85/blog)
|
// Based on the three.js Curve classes created by [zz85](http://www.lab4games.net/zz85/blog)
|
||||||
|
|
||||||
var Clamp = require('../../math/Clamp');
|
|
||||||
var Vector2 = require('../../math/Vector2');
|
|
||||||
var Vector3 = require('../../math/Vector3');
|
|
||||||
var Matrix4 = require('../../math/Matrix4');
|
|
||||||
var Class = require('../../utils/Class');
|
var Class = require('../../utils/Class');
|
||||||
|
var Vector2 = require('../../math/Vector2');
|
||||||
|
|
||||||
// Local cache vars
|
// Local cache vars
|
||||||
|
|
||||||
|
@ -237,6 +234,29 @@ var Curve = new Class({
|
||||||
var t = this.getUtoTmapping(u);
|
var t = this.getUtoTmapping(u);
|
||||||
|
|
||||||
return this.getTangent(t, out);
|
return this.getTangent(t, out);
|
||||||
|
},
|
||||||
|
|
||||||
|
draw: function (graphics, pointsTotal)
|
||||||
|
{
|
||||||
|
if (pointsTotal === undefined) { pointsTotal = 32; }
|
||||||
|
|
||||||
|
var start = this.getStartPoint();
|
||||||
|
var points = this.getPoints(pointsTotal);
|
||||||
|
|
||||||
|
graphics.beginPath();
|
||||||
|
|
||||||
|
graphics.moveTo(start.x, start.y);
|
||||||
|
|
||||||
|
for (var i = 1; i < points.length; i++)
|
||||||
|
{
|
||||||
|
graphics.lineTo(points[i].x, points[i].y);
|
||||||
|
}
|
||||||
|
|
||||||
|
graphics.strokePath();
|
||||||
|
graphics.closePath();
|
||||||
|
|
||||||
|
// So you can chain graphics calls
|
||||||
|
return graphics;
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -13,14 +13,27 @@ var CubicBezierCurve = new Class({
|
||||||
|
|
||||||
initialize:
|
initialize:
|
||||||
|
|
||||||
function CubicBezierCurve (v0, v1, v2, v3)
|
function CubicBezierCurve (p0, p1, p2, p3)
|
||||||
{
|
{
|
||||||
Curve.call(this);
|
Curve.call(this);
|
||||||
|
|
||||||
this.v0 = v0;
|
if (Array.isArray(p0))
|
||||||
this.v1 = v1;
|
{
|
||||||
this.v2 = v2;
|
p3 = new Vector2(p0[6], p0[7]);
|
||||||
this.v3 = v3;
|
p2 = new Vector2(p0[4], p0[5]);
|
||||||
|
p1 = new Vector2(p0[2], p0[3]);
|
||||||
|
p0 = new Vector2(p0[0], p0[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.p0 = p0;
|
||||||
|
this.p1 = p1;
|
||||||
|
this.p2 = p2;
|
||||||
|
this.p3 = p3;
|
||||||
|
},
|
||||||
|
|
||||||
|
getStartPoint: function ()
|
||||||
|
{
|
||||||
|
return this.p0;
|
||||||
},
|
},
|
||||||
|
|
||||||
getResolution: function (divisions)
|
getResolution: function (divisions)
|
||||||
|
@ -32,12 +45,33 @@ var CubicBezierCurve = new Class({
|
||||||
{
|
{
|
||||||
if (out === undefined) { out = new Vector2(); }
|
if (out === undefined) { out = new Vector2(); }
|
||||||
|
|
||||||
var v0 = this.v0;
|
var p0 = this.p0;
|
||||||
var v1 = this.v1;
|
var p1 = this.p1;
|
||||||
var v2 = this.v2;
|
var p2 = this.p2;
|
||||||
var v3 = this.v3;
|
var p3 = this.p3;
|
||||||
|
|
||||||
return out.set(CubicBezier(t, v0.x, v1.x, v2.x, v3.x), CubicBezier(t, v0.y, v1.y, v2.y, v3.y));
|
return out.set(CubicBezier(t, p0.x, p1.x, p2.x, p3.x), CubicBezier(t, p0.y, p1.y, p2.y, p3.y));
|
||||||
|
},
|
||||||
|
|
||||||
|
draw: function (graphics, pointsTotal)
|
||||||
|
{
|
||||||
|
if (pointsTotal === undefined) { pointsTotal = 32; }
|
||||||
|
|
||||||
|
var points = this.getPoints(pointsTotal);
|
||||||
|
|
||||||
|
graphics.beginPath();
|
||||||
|
graphics.moveTo(this.p0.x, this.p0.y);
|
||||||
|
|
||||||
|
for (var i = 1; i < points.length; i++)
|
||||||
|
{
|
||||||
|
graphics.lineTo(points[i].x, points[i].y);
|
||||||
|
}
|
||||||
|
|
||||||
|
graphics.strokePath();
|
||||||
|
graphics.closePath();
|
||||||
|
|
||||||
|
// So you can chain graphics calls
|
||||||
|
return graphics;
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -23,21 +23,27 @@ var EllipseCurve = new Class({
|
||||||
|
|
||||||
Curve.call(this);
|
Curve.call(this);
|
||||||
|
|
||||||
this.x = x;
|
this.p0 = new Vector2(x, y);
|
||||||
this.y = y;
|
|
||||||
|
|
||||||
this.xRadius = xRadius;
|
this._xRadius = xRadius;
|
||||||
this.yRadius = yRadius;
|
this._yRadius = yRadius;
|
||||||
|
|
||||||
// Radians
|
// Radians
|
||||||
this.startAngle = DegToRad(startAngle);
|
this._startAngle = DegToRad(startAngle);
|
||||||
this.endAngle = DegToRad(endAngle);
|
this._endAngle = DegToRad(endAngle);
|
||||||
|
|
||||||
// Boolean (anti-clockwise direction)
|
// Boolean (anti-clockwise direction)
|
||||||
this.clockwise = clockwise;
|
this._clockwise = clockwise;
|
||||||
|
|
||||||
// The rotation of the arc
|
// The rotation of the arc
|
||||||
this.rotation = DegToRad(rotation);
|
this._rotation = DegToRad(rotation);
|
||||||
|
|
||||||
|
this._startPoint = this.getPoint(0);
|
||||||
|
},
|
||||||
|
|
||||||
|
getStartPoint: function ()
|
||||||
|
{
|
||||||
|
return this._startPoint;
|
||||||
},
|
},
|
||||||
|
|
||||||
getResolution: function (divisions)
|
getResolution: function (divisions)
|
||||||
|
@ -50,7 +56,7 @@ var EllipseCurve = new Class({
|
||||||
if (out === undefined) { out = new Vector2(); }
|
if (out === undefined) { out = new Vector2(); }
|
||||||
|
|
||||||
var twoPi = Math.PI * 2;
|
var twoPi = Math.PI * 2;
|
||||||
var deltaAngle = this.endAngle - this.startAngle;
|
var deltaAngle = this._endAngle - this._startAngle;
|
||||||
var samePoints = Math.abs(deltaAngle) < Number.EPSILON;
|
var samePoints = Math.abs(deltaAngle) < Number.EPSILON;
|
||||||
|
|
||||||
// ensures that deltaAngle is 0 .. 2 PI
|
// ensures that deltaAngle is 0 .. 2 PI
|
||||||
|
@ -76,7 +82,7 @@ var EllipseCurve = new Class({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.clockwise && ! samePoints)
|
if (this._clockwise && !samePoints)
|
||||||
{
|
{
|
||||||
if (deltaAngle === twoPi)
|
if (deltaAngle === twoPi)
|
||||||
{
|
{
|
||||||
|
@ -88,24 +94,126 @@ var EllipseCurve = new Class({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var angle = this.startAngle + t * deltaAngle;
|
var angle = this._startAngle + t * deltaAngle;
|
||||||
var x = this.x + this.xRadius * Math.cos(angle);
|
var x = this.p0.x + this._xRadius * Math.cos(angle);
|
||||||
var y = this.y + this.yRadius * Math.sin(angle);
|
var y = this.p0.y + this._yRadius * Math.sin(angle);
|
||||||
|
|
||||||
if (this.rotation !== 0)
|
if (this._rotation !== 0)
|
||||||
{
|
{
|
||||||
var cos = Math.cos(this.rotation);
|
var cos = Math.cos(this._rotation);
|
||||||
var sin = Math.sin(this.rotation);
|
var sin = Math.sin(this._rotation);
|
||||||
|
|
||||||
var tx = x - this.x;
|
var tx = x - this.p0.x;
|
||||||
var ty = y - this.y;
|
var ty = y - this.p0.y;
|
||||||
|
|
||||||
// Rotate the point about the center of the ellipse.
|
// Rotate the point about the center of the ellipse.
|
||||||
x = tx * cos - ty * sin + this.x;
|
x = tx * cos - ty * sin + this.p0.x;
|
||||||
y = tx * sin + ty * cos + this.y;
|
y = tx * sin + ty * cos + this.p0.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
return out.set(x, y);
|
return out.set(x, y);
|
||||||
|
},
|
||||||
|
|
||||||
|
x: {
|
||||||
|
get: function ()
|
||||||
|
{
|
||||||
|
return this.p0.x;
|
||||||
|
},
|
||||||
|
|
||||||
|
set: function (value)
|
||||||
|
{
|
||||||
|
this.p0.x = value;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
y: {
|
||||||
|
get: function ()
|
||||||
|
{
|
||||||
|
return this.p0.y;
|
||||||
|
},
|
||||||
|
|
||||||
|
set: function (value)
|
||||||
|
{
|
||||||
|
this.p0.y = value;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
xRadius: {
|
||||||
|
get: function ()
|
||||||
|
{
|
||||||
|
return this._xRadius;
|
||||||
|
},
|
||||||
|
|
||||||
|
set: function (value)
|
||||||
|
{
|
||||||
|
this._xRadius = value;
|
||||||
|
this.getPoint(0, this._startPoint);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
yRadius: {
|
||||||
|
get: function ()
|
||||||
|
{
|
||||||
|
return this._yRadius;
|
||||||
|
},
|
||||||
|
|
||||||
|
set: function (value)
|
||||||
|
{
|
||||||
|
this._yRadius = value;
|
||||||
|
this.getPoint(0, this._startPoint);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
startAngle: {
|
||||||
|
get: function ()
|
||||||
|
{
|
||||||
|
return this._startAngle;
|
||||||
|
},
|
||||||
|
|
||||||
|
set: function (value)
|
||||||
|
{
|
||||||
|
this._startAngle = DegToRad(value);
|
||||||
|
this.getPoint(0, this._startPoint);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
endAngle: {
|
||||||
|
get: function ()
|
||||||
|
{
|
||||||
|
return this._endAngle;
|
||||||
|
},
|
||||||
|
|
||||||
|
set: function (value)
|
||||||
|
{
|
||||||
|
this._endAngle = DegToRad(value);
|
||||||
|
this.getPoint(0, this._startPoint);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
clockwise: {
|
||||||
|
get: function ()
|
||||||
|
{
|
||||||
|
return this._clockwise;
|
||||||
|
},
|
||||||
|
|
||||||
|
set: function (value)
|
||||||
|
{
|
||||||
|
this._clockwise = value;
|
||||||
|
this.getPoint(0, this._startPoint);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
rotation: {
|
||||||
|
get: function ()
|
||||||
|
{
|
||||||
|
return this._rotation;
|
||||||
|
},
|
||||||
|
|
||||||
|
set: function (value)
|
||||||
|
{
|
||||||
|
this._rotation = DegToRad(value);
|
||||||
|
this.getPoint(0, this._startPoint);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -14,22 +14,27 @@ var LineCurve = new Class({
|
||||||
|
|
||||||
initialize:
|
initialize:
|
||||||
|
|
||||||
// vec2s
|
// vec2s or array
|
||||||
function LineCurve (v1, v2)
|
function LineCurve (p0, p1)
|
||||||
{
|
{
|
||||||
if (Array.isArray(v1))
|
|
||||||
{
|
|
||||||
v2 = new Vector2(v1[2], v1[3]);
|
|
||||||
v1 = new Vector2(v1[0], v1[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
Curve.call(this);
|
Curve.call(this);
|
||||||
|
|
||||||
this.v1 = v1;
|
if (Array.isArray(p0))
|
||||||
this.v2 = v2;
|
{
|
||||||
|
p1 = new Vector2(p0[2], p0[3]);
|
||||||
|
p0 = new Vector2(p0[0], p0[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.p0 = p0;
|
||||||
|
this.p1 = p1;
|
||||||
},
|
},
|
||||||
|
|
||||||
getResolution: function (divisions)
|
getStartPoint: function ()
|
||||||
|
{
|
||||||
|
return this.p0;
|
||||||
|
},
|
||||||
|
|
||||||
|
getResolution: function ()
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
},
|
},
|
||||||
|
@ -40,10 +45,10 @@ var LineCurve = new Class({
|
||||||
|
|
||||||
if (t === 1)
|
if (t === 1)
|
||||||
{
|
{
|
||||||
return out.copy(this.v2);
|
return out.copy(this.p1);
|
||||||
}
|
}
|
||||||
|
|
||||||
out.copy(this.v2).sub(this.v1).scale(t).add(this.v1);
|
out.copy(this.p1).sub(this.p0).scale(t).add(this.p0);
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
},
|
},
|
||||||
|
@ -56,9 +61,18 @@ var LineCurve = new Class({
|
||||||
|
|
||||||
getTangent: function ()
|
getTangent: function ()
|
||||||
{
|
{
|
||||||
var tangent = tmpVec2.copy(this.v2).sub(this.v1);
|
var tangent = tmpVec2.copy(this.p1).sub(this.p0);
|
||||||
|
|
||||||
return tangent.normalize();
|
return tangent.normalize();
|
||||||
|
},
|
||||||
|
|
||||||
|
// Override default Curve.draw because this is better than calling getPoints on a line!
|
||||||
|
draw: function (graphics)
|
||||||
|
{
|
||||||
|
graphics.lineBetween(this.p0.x, this.p0.y, this.p1.x, this.p1.y);
|
||||||
|
|
||||||
|
// So you can chain graphics calls
|
||||||
|
return graphics;
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -23,6 +23,11 @@ var SplineCurve = new Class({
|
||||||
this.points = points;
|
this.points = points;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getStartPoint: function ()
|
||||||
|
{
|
||||||
|
return this.points[0];
|
||||||
|
},
|
||||||
|
|
||||||
getResolution: function (divisions)
|
getResolution: function (divisions)
|
||||||
{
|
{
|
||||||
return divisions * this.points.length;
|
return divisions * this.points.length;
|
||||||
|
|
Loading…
Reference in a new issue