Skip to content

Commit

Permalink
A start on separating Tail creation from shape creation
Browse files Browse the repository at this point in the history
Also makes the bubble keep track of the inner shape and each tail.
  • Loading branch information
JohnThomson authored and Jeffrey Su committed Sep 27, 2019
1 parent e78f2a1 commit 44f1283
Showing 1 changed file with 26 additions and 37 deletions.
63 changes: 26 additions & 37 deletions src/bubble.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,12 @@ export default class Bubble {
// TODO: What is the best name for "spec"?
// TODO: This variable is dangerous. You dont' want people modifying this variable directly, cuz we need to persist the changes into bloom
public spec: BubbleSpec;
// the main shape of the bubble, including its border
private shape: Shape;
//private tails: Tail[] = [];
// a clone of shape with no border and an appropriate fill; drawn after all shapes
// to fill them in and erase any overlapping borders.
private innerShape: Shape;
private tails: Tail[] = [];

// Don't use new() to create Bubble elements. Use getInstance() instead.
// The reason why is because if multiple Bubble objects get created which correspond to the same element, they will have different member variables
Expand Down Expand Up @@ -135,6 +139,9 @@ export default class Bubble {
// Also position, which surprisingly is about 50,50...probably a center.
//contentHolder.fillColor = new Color("cyan");
contentHolder.strokeWidth = 0;
this.innerShape = shape.clone() as Shape;
//this.innerShape.bringToFront();
this.innerShape.fillColor = Comical.backColor;
const adjustSize = () => {
var contentWidth = this.content.offsetWidth;
var contentHeight = this.content.offsetHeight;
Expand All @@ -149,13 +156,16 @@ export default class Bubble {
contentWidth / holderWidth,
contentHeight / holderHeight
);
this.innerShape.scale(contentWidth / holderWidth,
contentHeight / holderHeight);
const contentLeft = this.content.offsetLeft;
const contentTop = this.content.offsetTop;
const contentCenter = new Point(
contentLeft + contentWidth / 2,
contentTop + contentHeight / 2
);
this.shape.position = contentCenter;
this.innerShape.position = contentCenter;

// Draw tails, if necessary
if (this.spec.tips.length > 0) {
Expand All @@ -175,36 +185,13 @@ export default class Bubble {
private drawTailAfterShapePlaced(desiredTip: Tip) {
const target = new Point(desiredTip.targetX, desiredTip.targetY);
const mid = new Point(desiredTip.midpointX, desiredTip.midpointY);
const start = new Point(this.content.offsetLeft + this.content.offsetWidth / 2,
this.content.offsetTop + this.content.offsetHeight / 2);

// TODO: Is there something less awkward than creating a new spec object?
const bubbleSpec: BubbleSpec = {
version: "1.0",
style: this.spec.style,
tips: [desiredTip],
level: 1
};

this.setBubbleSpec(bubbleSpec);

this.drawTailOnShapes(mid, target, [this.shape]);
}

// Given a list of shapes, which should initially have no stroke or fill color,
// draws them twice, once with a black outline, then again filled with our
// backColor. If the shapes overlap, this gives the effect of outlining the
// combined shape. Then we draw the draggable tail on top, also with merged outline.
public drawTailOnShapes(mid: Point, tip: Point, shapes: Item[]) {
const start = this.shape.position!;
const interiors: Path[] = [];
shapes.forEach(s => {
var copy = s.clone() as Path;
interiors.push(copy);
copy.bringToFront(); // already in front of s, want in front of all
copy.fillColor = Comical.backColor;
});
var stroke = new Color("black");
shapes.forEach(s => (s.strokeColor = stroke));
this.drawTail(start, mid, tip, interiors[0]);
const tail = this.drawTail(start, mid, target,);
tail.putStrokeBehind(this.innerShape);
// keep track of it; eventually adjustSize will adjust its start position.
this.tails.push(tail);
}

private static getShapeSvgString(bubbleStyle: string): string {
Expand Down Expand Up @@ -241,15 +228,16 @@ export default class Bubble {
public drawTail(
start: Point,
mid: Point,
tip: Point,
lineBehind?: Item | null
): void {
tip: Point
): Tail {
const tipHandle = Bubble.makeHandle(tip);
const curveHandle = Bubble.makeHandle(mid);
let tail = new Tail(start, tipHandle.position!, curveHandle.position!);
if (lineBehind) {
tail.putStrokeBehind(lineBehind);
}
let tail = new Tail(
start,
tipHandle.position!,
curveHandle.position!,
);

curveHandle.bringToFront();

let state = "idle";
Expand Down Expand Up @@ -297,6 +285,7 @@ export default class Bubble {
tipHandle.onMouseUp = curveHandle.onMouseUp = () => {
state = "idle";
};
return tail;
}

// TODO: Help? where should I be? I think this comes up with unique names.
Expand Down

0 comments on commit 44f1283

Please sign in to comment.