@awayjs/graphics
Version:
AwayJS graphics classes
213 lines (212 loc) • 10.2 kB
JavaScript
import { assert } from './utilities';
import { DataBuffer } from './DataBuffer';
var PathSegment = /** @class */ (function () {
function PathSegment(commands, data, morphData, prev, next, isReversed) {
this.commands = commands;
this.data = data;
this.morphData = morphData;
this.prev = prev;
this.next = next;
this.isReversed = isReversed;
this.isValidFill = true;
this.id = PathSegment._counter++;
}
PathSegment.FromDefaults = function (isMorph) {
var commands = new DataBuffer();
var data = new DataBuffer();
commands.endian = data.endian = 'auto';
var morphData = null;
if (isMorph) {
morphData = new DataBuffer();
morphData.endian = 'auto';
}
return new PathSegment(commands, data, morphData, null, null, false);
};
PathSegment.prototype.moveTo = function (x, y) {
this.commands.writeUnsignedByte(9 /* PathCommand.MoveTo */);
this.data.write2Ints(x, y);
};
PathSegment.prototype.morphMoveTo = function (x, y, mx, my) {
this.moveTo(x, y);
this.morphData.write2Ints(mx, my);
};
PathSegment.prototype.lineTo = function (x, y) {
this.commands.writeUnsignedByte(10 /* PathCommand.LineTo */);
this.data.write2Ints(x, y);
};
PathSegment.prototype.morphLineTo = function (x, y, mx, my) {
this.lineTo(x, y);
this.morphData.write2Ints(mx, my);
};
PathSegment.prototype.curveTo = function (cpx, cpy, x, y) {
this.commands.writeUnsignedByte(11 /* PathCommand.CurveTo */);
this.data.write4Ints(cpx, cpy, x, y);
};
PathSegment.prototype.morphCurveTo = function (cpx, cpy, x, y, mcpx, mcpy, mx, my) {
this.curveTo(cpx, cpy, x, y);
this.morphData.write4Ints(mcpx, mcpy, mx, my);
};
/**
* Returns a shallow copy of the segment1 with the "isReversed" flag set.
* Reversed segments play themselves back in reverse when they're merged into the final
* non-segmented path1.
* Note: Don't modify the original, or the reversed copy, after this operation!
*/
PathSegment.prototype.toReversed = function () {
assert(!this.isReversed);
return new PathSegment(this.commands, this.data, this.morphData, null, null, true);
};
PathSegment.prototype.clone = function () {
return new PathSegment(this.commands, this.data, this.morphData, null, null, this.isReversed);
};
PathSegment.prototype.storeStartAndEnd = function () {
var data = this.data.ints;
var endPoint1 = data[0] + ',' + data[1];
var endPoint2Offset = (this.data.length >> 2) - 2;
var endPoint2 = data[endPoint2Offset] + ',' + data[endPoint2Offset + 1];
if (!this.isReversed) {
this.startPoint = endPoint1;
this.endPoint = endPoint2;
}
else {
this.startPoint = endPoint2;
this.endPoint = endPoint1;
}
};
PathSegment.prototype.connectsTo = function (other) {
//assert(other !== this);
if (other === this)
return false;
assert(this.endPoint);
assert(other.startPoint);
return this.endPoint === other.startPoint;
};
PathSegment.prototype.startConnectsTo = function (other) {
if (other === this)
return false;
// assert(other !== this);
return this.startPoint === other.startPoint;
};
PathSegment.prototype.flipDirection = function () {
var tempPoint = '';
tempPoint = this.startPoint;
this.startPoint = this.endPoint;
this.endPoint = tempPoint;
this.isReversed = !this.isReversed;
};
PathSegment.prototype.serializeAJS = function (shape, morphShape, lastPosition) {
// mark that this is morp source, this should disable some optimisation for regular shapes
if (morphShape) {
morphShape.morphSource = shape.morphSource = true;
}
//console.log("serializeAJS segment1");
if (this.isReversed) {
this._serializeReversedAJS(shape, morphShape, lastPosition);
return;
}
var commands = this.commands.bytes;
// Note: this *must* use `this.data.length`, because buffers will have padding.
var dataLength = this.data.length >> 2;
var morphData = this.morphData ? this.morphData.ints : null;
var data = this.data.ints;
// If the segment1's first moveTo goes to the current coordinates, we have to skip it.
var offset = 0;
if (data[0] === lastPosition.x && data[1] === lastPosition.y && !morphShape) {
offset++;
}
var commandsCount = this.commands.length;
var dataPosition = offset * 2;
for (var i = offset; i < commandsCount; i++) {
switch (commands[i]) {
case 9 /* PathCommand.MoveTo */:
//console.log("moveTo",data[dataPosition]/20, data[dataPosition+1]/20);
shape.moveTo(data[dataPosition] / 20, data[dataPosition + 1] / 20);
if (morphShape) {
morphShape.moveTo(morphData[dataPosition] / 20, morphData[dataPosition + 1] / 20);
}
break;
case 10 /* PathCommand.LineTo */:
//console.log("lineTo",data[dataPosition]/20, data[dataPosition+1]/20);
shape.lineTo(data[dataPosition] / 20, data[dataPosition + 1] / 20);
if (morphShape) {
morphShape.lineTo(morphData[dataPosition] / 20, morphData[dataPosition + 1] / 20);
}
break;
case 11 /* PathCommand.CurveTo */:
//console.log("curveTo",data[dataPosition]/20, data[dataPosition+1]/20,data[dataPosition+2]/20, data[dataPosition+3]/20);
shape.curveTo(data[dataPosition] / 20, data[dataPosition + 1] / 20, data[dataPosition + 2] / 20, data[dataPosition + 3] / 20);
if (morphShape) {
morphShape.curveTo(morphData[dataPosition] / 20, morphData[dataPosition + 1] / 20, morphData[dataPosition + 2] / 20, morphData[dataPosition + 3] / 20);
}
//shape.curveTo(data[dataPosition]/20, data[dataPosition+1]/20, data[dataPosition+2]/20, data[dataPosition+3]/20 );
dataPosition += 2;
break;
}
dataPosition += 2;
}
//assert(dataPosition === dataLength);
lastPosition.x = data[dataLength - 2];
lastPosition.y = data[dataLength - 1];
};
PathSegment.prototype._serializeReversedAJS = function (shape, morphShape, lastPosition) {
//console.log("_serializeReversedAJS segment1");
// For reversing the fill0 segments, we rely on the fact that each segment1
// starts with a moveTo. We first write a new moveTo with the final drawing command's
// target coordinates (if we don't skip it, see below). For each of the following
// commands, we take the coordinates of the command originally *preceding*
// it as the new target coordinates. The final coordinates we target will be
// the ones from the original first moveTo.
// Note: these *must* use `this.{data,commands}.length`, because buffers will have padding.
var commandsCount = this.commands.length;
var dataPosition = (this.data.length >> 2) - 2;
var commands = this.commands.bytes;
assert(commands[0] === 9 /* PathCommand.MoveTo */);
var data = this.data.ints;
var morphData = this.morphData ? this.morphData.ints : null;
// Only write the first moveTo if it doesn't go to the current coordinates.
if (data[dataPosition] !== lastPosition.x || data[dataPosition + 1] !== lastPosition.y) {
shape.moveTo(data[dataPosition] / 20, data[dataPosition + 1] / 20);
if (morphShape) {
morphShape.moveTo(morphData[dataPosition] / 20, morphData[dataPosition + 1] / 20);
}
}
if (commandsCount === 1) {
lastPosition.x = data[0];
lastPosition.y = data[1];
return;
}
for (var i = commandsCount; i-- > 1;) {
dataPosition -= 2;
switch (commands[i]) {
case 9 /* PathCommand.MoveTo */:
//console.log("moveTo",data[dataPosition]/20, data[dataPosition+1]/20);
shape.moveTo(data[dataPosition] / 20, data[dataPosition + 1] / 20);
if (morphShape) {
morphShape.moveTo(morphData[dataPosition] / 20, morphData[dataPosition + 1] / 20);
}
break;
case 10 /* PathCommand.LineTo */:
//console.log("lineTo",data[dataPosition]/20, data[dataPosition+1]/20);
shape.lineTo(data[dataPosition] / 20, data[dataPosition + 1] / 20);
if (morphShape) {
morphShape.lineTo(morphData[dataPosition] / 20, morphData[dataPosition + 1] / 20);
}
break;
case 11 /* PathCommand.CurveTo */:
dataPosition -= 2;
//console.log("curveTo",data[dataPosition+2]/20, data[dataPosition+3]/20,data[dataPosition]/20, data[dataPosition+1]/20);
shape.curveTo(data[dataPosition + 2] / 20, data[dataPosition + 3] / 20, data[dataPosition] / 20, data[dataPosition + 1] / 20);
if (morphShape) {
morphShape.curveTo(morphData[dataPosition + 2] / 20, morphData[dataPosition + 3] / 20, morphData[dataPosition] / 20, morphData[dataPosition + 1] / 20);
}
break;
}
}
//assert(dataPosition === 0);
lastPosition.x = data[0];
lastPosition.y = data[1];
};
PathSegment._counter = 0;
return PathSegment;
}());
export { PathSegment };