Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TextBubbleSkin.js -- expose Bubble Styles #14

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 44 additions & 43 deletions src/TextBubbleSkin.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,6 @@
const CanvasMeasurementProvider = require('./util/canvas-measurement-provider');
const Skin = require('./Skin');

const BubbleStyle = {
MAX_LINE_WIDTH: 170, // Maximum width, in Scratch pixels, of a single line of text

MIN_WIDTH: 50, // Minimum width, in Scratch pixels, of a text bubble
STROKE_WIDTH: 4, // Thickness of the stroke around the bubble. Only half's visible because it's drawn under the fill
PADDING: 10, // Padding around the text area
CORNER_RADIUS: 16, // Radius of the rounded corners
TAIL_HEIGHT: 12, // Height of the speech bubble's "tail". Probably should be a constant.

FONT: 'Helvetica', // Font to render the text with
FONT_SIZE: 14, // Font size, in Scratch pixels
FONT_HEIGHT_RATIO: 0.9, // Height, in Scratch pixels, of the text, as a proportion of the font's size
LINE_HEIGHT: 16, // Spacing between each line of text

COLORS: {
BUBBLE_FILL: 'white',
BUBBLE_STROKE: 'rgba(0, 0, 0, 0.15)',
TEXT_FILL: '#575E75'
}
};

const MAX_SCALE = 10;

class TextBubbleSkin extends Skin {
Expand Down Expand Up @@ -64,6 +43,28 @@
/** @type {boolean} */
this._textureDirty = true;

/** @type {object} */
this.BubbleStyle = {
MAX_LINE_WIDTH: 170, // Maximum width, in Scratch pixels, of a single line of text

MIN_WIDTH: 50, // Minimum width, in Scratch pixels, of a text bubble
STROKE_WIDTH: 4, // Thickness of the stroke around the bubble. Only half's visible because it's drawn under the fill

Check failure on line 51 in src/TextBubbleSkin.js

View workflow job for this annotation

GitHub Actions / build

This line has a length of 128. Maximum allowed is 120
PADDING: 10, // Padding around the text area
CORNER_RADIUS: 16, // Radius of the rounded corners
TAIL_HEIGHT: 12, // Height of the speech bubble's "tail". Probably should be a constant.

FONT: 'Helvetica', // Font to render the text with
FONT_SIZE: 14, // Font size, in Scratch pixels
FONT_HEIGHT_RATIO: 0.9, // Height, in Scratch pixels, of the text, as a proportion of the font's size
LINE_HEIGHT: 16, // Spacing between each line of text

COLORS: {
BUBBLE_FILL: 'white',
BUBBLE_STROKE: 'rgba(0, 0, 0, 0.15)',
TEXT_FILL: '#575E75'
}
};

this.measurementProvider = new CanvasMeasurementProvider(this._canvas.getContext('2d'));
this.textWrapper = renderer.createTextWrapper(this.measurementProvider);

Expand Down Expand Up @@ -112,14 +113,14 @@
* Re-style the canvas after resizing it. This is necessary to ensure proper text measurement.
*/
_restyleCanvas () {
this._canvas.getContext('2d').font = `${BubbleStyle.FONT_SIZE}px ${BubbleStyle.FONT}, sans-serif`;
this._canvas.getContext('2d').font = `${this.BubbleStyle.FONT_SIZE}px ${this.BubbleStyle.FONT}, sans-serif`;
}

/**
* Update the array of wrapped lines and the text dimensions.
*/
_reflowLines () {
this._lines = this.textWrapper.wrapText(BubbleStyle.MAX_LINE_WIDTH, this._text);
this._lines = this.textWrapper.wrapText(this.BubbleStyle.MAX_LINE_WIDTH, this._text);

// Measure width of longest line to avoid extra-wide bubbles
let longestLineWidth = 0;
Expand All @@ -128,14 +129,14 @@
}

// Calculate the canvas-space sizes of the padded text area and full text bubble
const paddedWidth = Math.max(longestLineWidth, BubbleStyle.MIN_WIDTH) + (BubbleStyle.PADDING * 2);
const paddedHeight = (BubbleStyle.LINE_HEIGHT * this._lines.length) + (BubbleStyle.PADDING * 2);
const paddedWidth = Math.max(longestLineWidth, this.BubbleStyle.MIN_WIDTH) + (this.BubbleStyle.PADDING * 2);
const paddedHeight = (this.BubbleStyle.LINE_HEIGHT * this._lines.length) + (this.BubbleStyle.PADDING * 2);

this._textAreaSize.width = paddedWidth;
this._textAreaSize.height = paddedHeight;

this._size[0] = paddedWidth + BubbleStyle.STROKE_WIDTH;
this._size[1] = paddedHeight + BubbleStyle.STROKE_WIDTH + BubbleStyle.TAIL_HEIGHT;
this._size[0] = paddedWidth + this.BubbleStyle.STROKE_WIDTH;
this._size[1] = paddedHeight + this.BubbleStyle.STROKE_WIDTH + this.BubbleStyle.TAIL_HEIGHT;

this._textDirty = false;
}
Expand Down Expand Up @@ -165,7 +166,7 @@
ctx.clearRect(0, 0, this._canvas.width, this._canvas.height);

ctx.scale(scale, scale);
ctx.translate(BubbleStyle.STROKE_WIDTH * 0.5, BubbleStyle.STROKE_WIDTH * 0.5);
ctx.translate(this.BubbleStyle.STROKE_WIDTH * 0.5, this.BubbleStyle.STROKE_WIDTH * 0.5);

// If the text bubble points leftward, flip the canvas
ctx.save();
Expand All @@ -176,16 +177,16 @@

// Draw the bubble's rounded borders
ctx.beginPath();
ctx.moveTo(BubbleStyle.CORNER_RADIUS, paddedHeight);
ctx.arcTo(0, paddedHeight, 0, paddedHeight - BubbleStyle.CORNER_RADIUS, BubbleStyle.CORNER_RADIUS);
ctx.arcTo(0, 0, paddedWidth, 0, BubbleStyle.CORNER_RADIUS);
ctx.arcTo(paddedWidth, 0, paddedWidth, paddedHeight, BubbleStyle.CORNER_RADIUS);
ctx.arcTo(paddedWidth, paddedHeight, paddedWidth - BubbleStyle.CORNER_RADIUS, paddedHeight,
BubbleStyle.CORNER_RADIUS);
ctx.moveTo(this.BubbleStyle.CORNER_RADIUS, paddedHeight);
ctx.arcTo(0, paddedHeight, 0, paddedHeight - this.BubbleStyle.CORNER_RADIUS, this.BubbleStyle.CORNER_RADIUS);
ctx.arcTo(0, 0, paddedWidth, 0, this.BubbleStyle.CORNER_RADIUS);
ctx.arcTo(paddedWidth, 0, paddedWidth, paddedHeight, this.BubbleStyle.CORNER_RADIUS);
ctx.arcTo(paddedWidth, paddedHeight, paddedWidth - this.BubbleStyle.CORNER_RADIUS, paddedHeight,
this.BubbleStyle.CORNER_RADIUS);

// Translate the canvas so we don't have to do a bunch of width/height arithmetic
ctx.save();
ctx.translate(paddedWidth - BubbleStyle.CORNER_RADIUS, paddedHeight);
ctx.translate(paddedWidth - this.BubbleStyle.CORNER_RADIUS, paddedHeight);

// Draw the bubble's "tail"
if (this._bubbleType === 'say') {
Expand All @@ -212,9 +213,9 @@
// Un-translate the canvas and fill + stroke the text bubble
ctx.restore();

ctx.fillStyle = BubbleStyle.COLORS.BUBBLE_FILL;
ctx.strokeStyle = BubbleStyle.COLORS.BUBBLE_STROKE;
ctx.lineWidth = BubbleStyle.STROKE_WIDTH;
ctx.fillStyle = this.BubbleStyle.COLORS.BUBBLE_FILL;
ctx.strokeStyle = this.BubbleStyle.COLORS.BUBBLE_STROKE;
ctx.lineWidth = this.BubbleStyle.STROKE_WIDTH;

ctx.stroke();
ctx.fill();
Expand All @@ -223,16 +224,16 @@
ctx.restore();

// Draw each line of text
ctx.fillStyle = BubbleStyle.COLORS.TEXT_FILL;
ctx.font = `${BubbleStyle.FONT_SIZE}px ${BubbleStyle.FONT}, sans-serif`;
ctx.fillStyle = this.BubbleStyle.COLORS.TEXT_FILL;
ctx.font = `${this.BubbleStyle.FONT_SIZE}px ${this.BubbleStyle.FONT}, sans-serif`;
const lines = this._lines;
for (let lineNumber = 0; lineNumber < lines.length; lineNumber++) {
const line = lines[lineNumber];
ctx.fillText(
line,
BubbleStyle.PADDING,
BubbleStyle.PADDING + (BubbleStyle.LINE_HEIGHT * lineNumber) +
(BubbleStyle.FONT_HEIGHT_RATIO * BubbleStyle.FONT_SIZE)
this.BubbleStyle.PADDING,
this.BubbleStyle.PADDING + (this.BubbleStyle.LINE_HEIGHT * lineNumber) +
(this.BubbleStyle.FONT_HEIGHT_RATIO * this.BubbleStyle.FONT_SIZE)
);
}

Expand Down
Loading