mirror of
https://github.com/google/blockly.git
synced 2026-01-09 18:10:08 +01:00
* chore: add linting for tsdoc * chore: don't require types on return * chore: remove redundant fileoverview from ts * chore: change return to returns and add some newlines * chore: remove license tag * chore: don't require params/return docs * chore: remove spurious struct tags * Revert "chore: change return to returns and add some newlines" This reverts commitd6d8656a45. * chore: don't auto-add param names * chore: disable require-param bc it breaks on this * return to returns and add line breaks * chore: configure additional jsdoc rules * chore: run format * Revert "chore: remove license tag" This reverts commit173455588a. * chore: allow license tag format * chore: only require jsdoc on exported items * chore: add missing jsdoc or silence where needed * chore: run format * chore: lint fixes
190 lines
5.5 KiB
TypeScript
190 lines
5.5 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright 2017 Google LLC
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
/**
|
|
* Object for configuring and updating a workspace grid in
|
|
* Blockly.
|
|
*
|
|
* @class
|
|
*/
|
|
import * as goog from '../closure/goog/goog.js';
|
|
goog.declareModuleId('Blockly.Grid');
|
|
|
|
import * as dom from './utils/dom.js';
|
|
import {Svg} from './utils/svg.js';
|
|
import {GridOptions} from './blockly_options.js';
|
|
|
|
|
|
/**
|
|
* Class for a workspace's grid.
|
|
*
|
|
* @alias Blockly.Grid
|
|
*/
|
|
export class Grid {
|
|
/**
|
|
* The scale of the grid, used to set stroke width on grid lines.
|
|
* This should always be the same as the workspace scale.
|
|
*/
|
|
private scale_ = 1;
|
|
private readonly spacing_: number;
|
|
private readonly length_: number;
|
|
private readonly line1_: SVGElement;
|
|
private readonly line2_: SVGElement;
|
|
private readonly snapToGrid_: boolean;
|
|
|
|
/**
|
|
* @param pattern The grid's SVG pattern, created during injection.
|
|
* @param options A dictionary of normalized options for the grid.
|
|
* See grid documentation:
|
|
* https://developers.google.com/blockly/guides/configure/web/grid
|
|
*/
|
|
constructor(private pattern: SVGElement, options: GridOptions) {
|
|
/** The spacing of the grid lines (in px). */
|
|
this.spacing_ = options['spacing'] ?? 0;
|
|
|
|
/** How long the grid lines should be (in px). */
|
|
this.length_ = options['length'] ?? 1;
|
|
|
|
/** The horizontal grid line, if it exists. */
|
|
this.line1_ = pattern.firstChild as SVGElement;
|
|
|
|
/** The vertical grid line, if it exists. */
|
|
this.line2_ = this.line1_ && this.line1_.nextSibling as SVGElement;
|
|
|
|
/** Whether blocks should snap to the grid. */
|
|
this.snapToGrid_ = options['snap'] ?? false;
|
|
}
|
|
|
|
/**
|
|
* Whether blocks should snap to the grid, based on the initial configuration.
|
|
*
|
|
* @returns True if blocks should snap, false otherwise.
|
|
* @internal
|
|
*/
|
|
shouldSnap(): boolean {
|
|
return this.snapToGrid_;
|
|
}
|
|
|
|
/**
|
|
* Get the spacing of the grid points (in px).
|
|
*
|
|
* @returns The spacing of the grid points.
|
|
* @internal
|
|
*/
|
|
getSpacing(): number {
|
|
return this.spacing_;
|
|
}
|
|
|
|
/**
|
|
* Get the ID of the pattern element, which should be randomized to avoid
|
|
* conflicts with other Blockly instances on the page.
|
|
*
|
|
* @returns The pattern ID.
|
|
* @internal
|
|
*/
|
|
getPatternId(): string {
|
|
return this.pattern.id;
|
|
}
|
|
|
|
/**
|
|
* Update the grid with a new scale.
|
|
*
|
|
* @param scale The new workspace scale.
|
|
* @internal
|
|
*/
|
|
update(scale: number) {
|
|
this.scale_ = scale;
|
|
// MSIE freaks if it sees a 0x0 pattern, so set empty patterns to 100x100.
|
|
const safeSpacing = this.spacing_ * scale || 100;
|
|
|
|
this.pattern.setAttribute('width', safeSpacing.toString());
|
|
this.pattern.setAttribute('height', safeSpacing.toString());
|
|
|
|
let half = Math.floor(this.spacing_ / 2) + 0.5;
|
|
let start = half - this.length_ / 2;
|
|
let end = half + this.length_ / 2;
|
|
|
|
half *= scale;
|
|
start *= scale;
|
|
end *= scale;
|
|
|
|
this.setLineAttributes_(this.line1_, scale, start, end, half, half);
|
|
this.setLineAttributes_(this.line2_, scale, half, half, start, end);
|
|
}
|
|
|
|
/**
|
|
* Set the attributes on one of the lines in the grid. Use this to update the
|
|
* length and stroke width of the grid lines.
|
|
*
|
|
* @param line Which line to update.
|
|
* @param width The new stroke size (in px).
|
|
* @param x1 The new x start position of the line (in px).
|
|
* @param x2 The new x end position of the line (in px).
|
|
* @param y1 The new y start position of the line (in px).
|
|
* @param y2 The new y end position of the line (in px).
|
|
*/
|
|
private setLineAttributes_(
|
|
line: SVGElement, width: number, x1: number, x2: number, y1: number,
|
|
y2: number) {
|
|
if (line) {
|
|
line.setAttribute('stroke-width', width.toString());
|
|
line.setAttribute('x1', x1.toString());
|
|
line.setAttribute('y1', y1.toString());
|
|
line.setAttribute('x2', x2.toString());
|
|
line.setAttribute('y2', y2.toString());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Move the grid to a new x and y position, and make sure that change is
|
|
* visible.
|
|
*
|
|
* @param x The new x position of the grid (in px).
|
|
* @param y The new y position of the grid (in px).
|
|
* @internal
|
|
*/
|
|
moveTo(x: number, y: number) {
|
|
this.pattern.setAttribute('x', x.toString());
|
|
this.pattern.setAttribute('y', y.toString());
|
|
}
|
|
|
|
/**
|
|
* Create the DOM for the grid described by options.
|
|
*
|
|
* @param rnd A random ID to append to the pattern's ID.
|
|
* @param gridOptions The object containing grid configuration.
|
|
* @param defs The root SVG element for this workspace's defs.
|
|
* @returns The SVG element for the grid pattern.
|
|
* @internal
|
|
*/
|
|
static createDom(rnd: string, gridOptions: GridOptions, defs: SVGElement):
|
|
SVGElement {
|
|
/*
|
|
<pattern id="blocklyGridPattern837493" patternUnits="userSpaceOnUse">
|
|
<rect stroke="#888" />
|
|
<rect stroke="#888" />
|
|
</pattern>
|
|
*/
|
|
const gridPattern = dom.createSvgElement(
|
|
Svg.PATTERN,
|
|
{'id': 'blocklyGridPattern' + rnd, 'patternUnits': 'userSpaceOnUse'},
|
|
defs);
|
|
// x1, y1, x1, x2 properties will be set later in update.
|
|
if ((gridOptions['length'] ?? 1) > 0 && (gridOptions['spacing'] ?? 0) > 0) {
|
|
dom.createSvgElement(
|
|
Svg.LINE, {'stroke': gridOptions['colour']}, gridPattern);
|
|
if (gridOptions['length'] ?? 1 > 1) {
|
|
dom.createSvgElement(
|
|
Svg.LINE, {'stroke': gridOptions['colour']}, gridPattern);
|
|
}
|
|
} else {
|
|
// Edge 16 doesn't handle empty patterns
|
|
dom.createSvgElement(Svg.LINE, {}, gridPattern);
|
|
}
|
|
return gridPattern;
|
|
}
|
|
}
|