UNPKG

@awayjs/graphics

Version:
213 lines (212 loc) 10.2 kB
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 };