Socket
Socket
Sign inDemoInstall

js-draw

Package Overview
Dependencies
Maintainers
1
Versions
117
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

js-draw - npm Package Compare versions

Comparing version 0.18.2 to 0.19.0

dist/bundledStyles.js

7

CHANGELOG.md

@@ -0,1 +1,8 @@

# 0.19.0
* (Experimental) Sound-based image browsing.
- Pressing tab repeatedly shows an "Enable sound-based exploration" button. Clicking this button plays a sound when a user subsequently clicks on the canvas. The sound is based on the color under the cursor.
* Fixed
- Pinch-zooming on a trackpad would zoom in to a point roughly 50px below the cursor.
- Buttons accessible only by pressing "tab" repeatedly were hidden behind the editor's canvas in some browsers.
# 0.18.2

@@ -2,0 +9,0 @@ * Fix essential files missing from NPM.

@@ -0,1 +1,2 @@

import Vec3 from './math/Vec3';
export default class Color4 {

@@ -39,2 +40,9 @@ /** Red component. Should be in the range [0, 1]. */

static average(colors: Color4[]): Color4;
/**
* Converts to (hue, saturation, value).
* See also https://en.wikipedia.org/wiki/HSL_and_HSV#General_approach
*
* The resultant hue is represented in radians and is thus in [0, 2pi].
*/
asHSV(): Vec3;
private hexString;

@@ -41,0 +49,0 @@ /**

"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Color4 = void 0;
const Vec3_1 = __importDefault(require("./math/Vec3"));
class Color4 {

@@ -154,2 +158,65 @@ constructor(

/**
* Converts to (hue, saturation, value).
* See also https://en.wikipedia.org/wiki/HSL_and_HSV#General_approach
*
* The resultant hue is represented in radians and is thus in [0, 2pi].
*/
asHSV() {
// Ref: https://en.wikipedia.org/wiki/HSL_and_HSV#General_approach
//
// HUE:
// First, consider the unit cube. Rotate it such that one vertex is at the origin
// of a plane and its three neighboring vertices are equidistant from that plane:
//
// /\
// / | \
// 2 / 3 \ 1
// \ | /
// \ | /
// . \/ .
//
// .
//
// Let z be up and (x, y, 0) be in the plane.
//
// Label vectors 1,2,3 with R, G, and B, respectively. Let R's projection into the plane
// lie along the x axis.
//
// Because R is a unit vector and R, G, B are equidistant from the plane, they must
// form 30-60-90 triangles, which have side lengths proportional to (1, √3, 2)
//
// /|
// 1/ | (√3)/2
// / |
// 1/2
//
const minComponent = Math.min(this.r, this.g, this.b);
const maxComponent = Math.max(this.r, this.g, this.b);
const chroma = maxComponent - minComponent;
let hue;
// See https://en.wikipedia.org/wiki/HSL_and_HSV#General_approach
if (chroma === 0) {
hue = 0;
}
else if (this.r >= this.g && this.r >= this.b) {
hue = ((this.g - this.b) / chroma) % 6;
}
else if (this.g >= this.r && this.g >= this.b) {
hue = (this.b - this.r) / chroma + 2;
}
else {
hue = (this.r - this.g) / chroma + 4;
}
// Convert to degree representation, then to radians.
hue *= 60;
hue *= Math.PI / 180;
// Ensure positivity.
if (hue < 0) {
hue += Math.PI * 2;
}
const value = maxComponent;
const saturation = value > 0 ? chroma / value : 0;
return Vec3_1.default.of(hue, saturation, value);
}
/**
* @returns a hexadecimal color string representation of `this`, in the form `#rrggbbaa`.

@@ -156,0 +223,0 @@ *

4

dist/cjs/src/components/AbstractComponent.d.ts

@@ -29,3 +29,3 @@ import SerializableCommand from '../commands/SerializableCommand';

*
* This is intended for use by a {@link ImageLoader}.
* This is intended for use by an {@link ImageLoader}.
*/

@@ -36,3 +36,3 @@ attachLoadSaveData(key: string, data: LoadSaveData): void;

getZIndex(): number;
/** @returns the bounding box of */
/** @returns the bounding box of this. */
getBBox(): Rect2;

@@ -39,0 +39,0 @@ /** Called when this component is added to the given image. */

@@ -35,3 +35,3 @@ "use strict";

// Returns a unique ID for this element.
// @see { @link lib!EditorImage.lookupElement }
// @see { @link EditorImage.lookupElement }
getId() {

@@ -49,3 +49,3 @@ return this.id;

*
* This is intended for use by a {@link ImageLoader}.
* This is intended for use by an {@link ImageLoader}.
*/

@@ -65,3 +65,3 @@ attachLoadSaveData(key, data) {

}
/** @returns the bounding box of */
/** @returns the bounding box of this. */
getBBox() {

@@ -68,0 +68,0 @@ return this.contentBBox;

@@ -18,3 +18,3 @@ "use strict";

exports.imageBackgroundCSSClassName = 'js-draw-image-background';
// Represents the background of an image in the editor.
// Represents the background of the editor's canvas.
class ImageBackground extends AbstractComponent_1.default {

@@ -21,0 +21,0 @@ constructor(backgroundType, mainColor) {

@@ -10,4 +10,5 @@ export * from './builders/types';

import ImageComponent from './ImageComponent';
import RestyleableComponent, { createRestyleComponentCommand, isRestylableComponent } from './RestylableComponent';
import RestyleableComponent from './RestylableComponent';
import { createRestyleComponentCommand, isRestylableComponent, ComponentStyle as RestyleableComponentStyle } from './RestylableComponent';
import ImageBackground from './ImageBackground';
export { Stroke, TextComponent as Text, RestyleableComponent, createRestyleComponentCommand, isRestylableComponent, TextComponent, Stroke as StrokeComponent, ImageBackground as BackgroundComponent, ImageComponent, };
export { Stroke, TextComponent as Text, RestyleableComponent, createRestyleComponentCommand, isRestylableComponent, RestyleableComponentStyle, TextComponent, Stroke as StrokeComponent, ImageBackground as BackgroundComponent, ImageComponent, };
import Color4 from '../Color4';
import SerializableCommand from '../commands/SerializableCommand';
import Editor from '../Editor';
import TextStyle from '../rendering/TextRenderingStyle';
import TextRenderingStyle from '../rendering/TextRenderingStyle';
import AbstractComponent from './AbstractComponent';
export interface ComponentStyle {
color?: Color4;
textStyle?: TextStyle;
textStyle?: TextRenderingStyle;
}
export declare const createRestyleComponentCommand: (initialStyle: ComponentStyle, newStyle: ComponentStyle, component: RestyleableComponent) => SerializableCommand;
export declare const isRestylableComponent: (component: AbstractComponent) => component is RestyleableComponent;
/**
* An interface to be implemented by components with a changable color or {@link TextRenderingStyle}.
*
* All such classes must have a member variable, `isRestylableComponent` that is set to `true`
* to allow testing whether the class is a `RestylableComponent` (see {@link isRestylableComponent}).
*/
export interface RestyleableComponent extends AbstractComponent {
/**
* @returns a partial representation of this component's style.
*/
getStyle(): ComponentStyle;
/**
* Returns a {@link Command} that updates portions of this component's style
* to the given `style`.
*
* @example
* For some component and editor,
* ```ts
* editor.dispatch(component.updateStyle({ color: Color4.red }));
* ```
*/
updateStyle(style: ComponentStyle): SerializableCommand;

@@ -15,0 +34,0 @@ /**

@@ -11,2 +11,18 @@ import SerializableCommand from '../commands/SerializableCommand';

import RestyleableComponent, { ComponentStyle } from './RestylableComponent';
/**
* Represents an {@link AbstractComponent} made up of one or more {@link Path}s.
*
* @example
* For some {@link Editor} editor and `Stroke` stroke,
*
* **Restyling**:
* ```ts
* editor.dispatch(stroke.updateStyle({ color: Color4.red }));
* ```
*
* **Transforming**:
* ```ts
* editor.dispatch(stroke.transformBy(Mat33.translation(Vec2.of(10, 0))));
* ```
*/
export default class Stroke extends AbstractComponent implements RestyleableComponent {

@@ -17,2 +33,18 @@ private parts;

private approximateRenderingTime;
/**
* Creates a `Stroke` from the given `parts`. All parts should have the
* same color.
*
* @example
* ```ts
* // A path that starts at (1,1), moves to the right by (2, 0),
* // then moves down and right by (3, 3)
* const path = Path.fromString('m1,1 2,0 3,3');
*
* const stroke = new Stroke([
* // Fill with red
* path.toRenderable({ fill: Color4.red })
* ]);
* ```
*/
constructor(parts: RenderablePathSpec[]);

@@ -27,2 +59,5 @@ getStyle(): ComponentStyle;

protected applyTransformation(affineTransfm: Mat33): void;
/**
* @returns the {@link Path.union} of all paths that make up this stroke.
*/
getPath(): Path;

@@ -29,0 +64,0 @@ description(localization: ImageComponentLocalization): string;

@@ -11,8 +11,39 @@ "use strict";

const RestylableComponent_1 = require("./RestylableComponent");
/**
* Represents an {@link AbstractComponent} made up of one or more {@link Path}s.
*
* @example
* For some {@link Editor} editor and `Stroke` stroke,
*
* **Restyling**:
* ```ts
* editor.dispatch(stroke.updateStyle({ color: Color4.red }));
* ```
*
* **Transforming**:
* ```ts
* editor.dispatch(stroke.transformBy(Mat33.translation(Vec2.of(10, 0))));
* ```
*/
class Stroke extends AbstractComponent_1.default {
// Creates a `Stroke` from the given `parts`. All parts should have the
// same color.
/**
* Creates a `Stroke` from the given `parts`. All parts should have the
* same color.
*
* @example
* ```ts
* // A path that starts at (1,1), moves to the right by (2, 0),
* // then moves down and right by (3, 3)
* const path = Path.fromString('m1,1 2,0 3,3');
*
* const stroke = new Stroke([
* // Fill with red
* path.toRenderable({ fill: Color4.red })
* ]);
* ```
*/
constructor(parts) {
var _a;
super('stroke');
// @internal
// eslint-disable-next-line @typescript-eslint/prefer-as-const

@@ -150,2 +181,5 @@ this.isRestylableComponent = true;

}
/**
* @returns the {@link Path.union} of all paths that make up this stroke.
*/
getPath() {

@@ -152,0 +186,0 @@ let result = null;

@@ -7,6 +7,9 @@ import SerializableCommand from '../commands/SerializableCommand';

import AbstractRenderer from '../rendering/renderers/AbstractRenderer';
import { TextStyle } from '../rendering/TextRenderingStyle';
import { TextRenderingStyle } from '../rendering/TextRenderingStyle';
import AbstractComponent from './AbstractComponent';
import { ImageComponentLocalization } from './localization';
import RestyleableComponent, { ComponentStyle } from './RestylableComponent';
/**
* Displays text.
*/
export default class TextComponent extends AbstractComponent implements RestyleableComponent {

@@ -18,4 +21,9 @@ protected readonly textObjects: Array<string | TextComponent>;

readonly isRestylableComponent: true;
constructor(textObjects: Array<string | TextComponent>, transform: Mat33, style: TextStyle);
static applyTextStyles(ctx: CanvasRenderingContext2D, style: TextStyle): void;
/**
* Creates a new text object from a list of component text or child TextComponents.
*
* @see {@link fromLines}
*/
constructor(textObjects: Array<string | TextComponent>, transform: Mat33, style: TextRenderingStyle);
static applyTextStyles(ctx: CanvasRenderingContext2D, style: TextRenderingStyle): void;
private static textMeasuringCtx;

@@ -54,3 +62,17 @@ private static estimateTextDimens;

static deserializeFromString(json: any): TextComponent;
static fromLines(lines: string[], transform: Mat33, style: TextStyle): AbstractComponent;
/**
* Creates a `TextComponent` from `lines`.
*
* @example
* ```ts
* const textStyle = {
* size: 12,
* fontFamily: 'serif',
* renderingStyle: { fill: Color4.black },
* };
*
* const text = TextComponent.fromLines('foo\nbar'.split('\n'), Mat33.identity, textStyle);
* ```
*/
static fromLines(lines: string[], transform: Mat33, style: TextRenderingStyle): AbstractComponent;
}

@@ -14,3 +14,11 @@ "use strict";

const componentTypeId = 'text';
/**
* Displays text.
*/
class TextComponent extends AbstractComponent_1.default {
/**
* Creates a new text object from a list of component text or child TextComponents.
*
* @see {@link fromLines}
*/
constructor(textObjects, transform, style) {

@@ -241,2 +249,16 @@ super(componentTypeId);

}
/**
* Creates a `TextComponent` from `lines`.
*
* @example
* ```ts
* const textStyle = {
* size: 12,
* fontFamily: 'serif',
* renderingStyle: { fill: Color4.black },
* };
*
* const text = TextComponent.fromLines('foo\nbar'.split('\n'), Mat33.identity, textStyle);
* ```
*/
static fromLines(lines, transform, style) {

@@ -243,0 +265,0 @@ let lastComponent = null;

@@ -56,3 +56,3 @@ import EditorImage from './EditorImage';

private renderingRegion;
/** Manages drawing surfaces/{@link lib!AbstractRenderer}s. */
/** Manages drawing surfaces/{@link AbstractRenderer}s. */
display: Display;

@@ -99,3 +99,3 @@ /**

readonly localization: EditorLocalization;
/** {@link lib!EditorSettings.iconProvider} */
/** {@link EditorSettings.iconProvider} */
readonly icons: IconProvider;

@@ -102,0 +102,0 @@ /**

@@ -261,4 +261,4 @@ "use strict";

}
// Ensure that `pos` is relative to `this.container`
const bbox = this.container.getBoundingClientRect();
// Ensure that `pos` is relative to `this.renderingRegion`
const bbox = this.renderingRegion.getBoundingClientRect();
const pos = Vec2_1.Vec2.of(evt.clientX, evt.clientY).minus(Vec2_1.Vec2.of(bbox.left, bbox.top));

@@ -265,0 +265,0 @@ if (this.toolController.dispatchInputEvent({

@@ -8,2 +8,30 @@ /**

* import { Editor, Vec3, Mat33 } from 'js-draw';
*
* // Apply js-draw CSS
* import 'js-draw/styles';
* // If your bundler doesn't support the above, try
* // import 'js-draw/bundledStyles';
*
* (async () => {
* const editor = new Editor(document.body);
* const toolbar = editor.addToolbar();
* editor.getRootElement().style.height = '600px';
*
* await editor.loadFromSVG(`
* <svg viewBox="0 0 500 500" width="500" height="500" version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg">
* <style id="js-draw-style-sheet">path{stroke-linecap:round;stroke-linejoin:round;}text{white-space:pre;}</style>
* <path d="M500,500L500,0L0,0L0,500L500,500" fill="#423131bf" class="js-draw-image-background"></path>
* <text style="transform: matrix(1, 0, 0, 1, 57, 192); font-family: serif; font-size: 32px; fill: rgb(204, 102, 51);">Testing...</text>
* </svg>
* `);
*
* toolbar.addActionButton({
* label: 'Save',
* icon: editor.icons.makeSaveIcon(),
* }, () => {
* const saveData = editor.toSVG().outerHTML;
*
* // Do something with saveData
* });
* })();
* ```

@@ -13,2 +41,4 @@ *

* {@link Editor}
* {@link Editor.loadFromSVG}
* {@link HTMLToolbar.addActionButton }
*

@@ -15,0 +45,0 @@ * @packageDocumentation

@@ -9,2 +9,30 @@ "use strict";

* import { Editor, Vec3, Mat33 } from 'js-draw';
*
* // Apply js-draw CSS
* import 'js-draw/styles';
* // If your bundler doesn't support the above, try
* // import 'js-draw/bundledStyles';
*
* (async () => {
* const editor = new Editor(document.body);
* const toolbar = editor.addToolbar();
* editor.getRootElement().style.height = '600px';
*
* await editor.loadFromSVG(`
* <svg viewBox="0 0 500 500" width="500" height="500" version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg">
* <style id="js-draw-style-sheet">path{stroke-linecap:round;stroke-linejoin:round;}text{white-space:pre;}</style>
* <path d="M500,500L500,0L0,0L0,500L500,500" fill="#423131bf" class="js-draw-image-background"></path>
* <text style="transform: matrix(1, 0, 0, 1, 57, 192); font-family: serif; font-size: 32px; fill: rgb(204, 102, 51);">Testing...</text>
* </svg>
* `);
*
* toolbar.addActionButton({
* label: 'Save',
* icon: editor.icons.makeSaveIcon(),
* }, () => {
* const saveData = editor.toSVG().outerHTML;
*
* // Do something with saveData
* });
* })();
* ```

@@ -14,2 +42,4 @@ *

* {@link Editor}
* {@link Editor.loadFromSVG}
* {@link HTMLToolbar.addActionButton }
*

@@ -16,0 +46,0 @@ * @packageDocumentation

@@ -6,1 +6,3 @@ export { default as AbstractRenderer } from './renderers/AbstractRenderer';

export { default as Display, RenderingMode } from './Display';
export { default as TextRenderingStyle } from './TextRenderingStyle';
export { default as RenderingStyle } from './RenderingStyle';

@@ -9,3 +9,3 @@ import Color4 from '../../Color4';

import RenderingStyle from '../RenderingStyle';
import TextStyle from '../TextRenderingStyle';
import TextRenderingStyle from '../TextRenderingStyle';
export interface RenderablePathSpec {

@@ -37,3 +37,3 @@ startPoint: Point2;

protected abstract traceQuadraticBezierCurve(controlPoint: Point2, endPoint: Point2): void;
abstract drawText(text: string, transform: Mat33, style: TextStyle): void;
abstract drawText(text: string, transform: Mat33, style: TextRenderingStyle): void;
abstract drawImage(image: RenderableImage): void;

@@ -40,0 +40,0 @@ abstract isTooSmallToRender(rect: Rect2): boolean;

@@ -7,3 +7,3 @@ import Mat33 from '../../math/Mat33';

import RenderingStyle from '../RenderingStyle';
import TextStyle from '../TextRenderingStyle';
import TextRenderingStyle from '../TextRenderingStyle';
import AbstractRenderer, { RenderableImage, RenderablePathSpec } from './AbstractRenderer';

@@ -57,3 +57,3 @@ /**

drawPath(path: RenderablePathSpec): void;
drawText(text: string, transform: Mat33, style: TextStyle): void;
drawText(text: string, transform: Mat33, style: TextRenderingStyle): void;
drawImage(image: RenderableImage): void;

@@ -60,0 +60,0 @@ private clipLevels;

@@ -7,3 +7,3 @@ import Mat33 from '../../math/Mat33';

import RenderingStyle from '../RenderingStyle';
import TextStyle from '../TextRenderingStyle';
import TextRenderingStyle from '../TextRenderingStyle';
import AbstractRenderer, { RenderableImage } from './AbstractRenderer';

@@ -29,3 +29,3 @@ export default class DummyRenderer extends AbstractRenderer {

drawPoints(..._points: Vec3[]): void;
drawText(text: string, _transform: Mat33, _style: TextStyle): void;
drawText(text: string, _transform: Mat33, _style: TextRenderingStyle): void;
drawImage(image: RenderableImage): void;

@@ -32,0 +32,0 @@ startObject(boundingBox: Rect2, _clip: boolean): void;

@@ -7,3 +7,3 @@ import { LoadSaveDataTable } from '../../components/AbstractComponent';

import RenderingStyle from '../RenderingStyle';
import TextStyle from '../TextRenderingStyle';
import TextRenderingStyle from '../TextRenderingStyle';
import AbstractRenderer, { RenderableImage, RenderablePathSpec } from './AbstractRenderer';

@@ -40,3 +40,3 @@ export declare const renderedStylesheetId = "js-draw-style-sheet";

private textParentStyle;
drawText(text: string, transform: Mat33, style: TextStyle): void;
drawText(text: string, transform: Mat33, style: TextRenderingStyle): void;
drawImage(image: RenderableImage): void;

@@ -43,0 +43,0 @@ startObject(boundingBox: Rect2): void;

@@ -7,3 +7,3 @@ import Mat33 from '../../math/Mat33';

import RenderingStyle from '../RenderingStyle';
import TextStyle from '../TextRenderingStyle';
import TextRenderingStyle from '../TextRenderingStyle';
import AbstractRenderer, { RenderableImage } from './AbstractRenderer';

@@ -26,3 +26,3 @@ export default class TextOnlyRenderer extends AbstractRenderer {

protected traceQuadraticBezierCurve(_controlPoint: Vec3, _endPoint: Vec3): void;
drawText(text: string, _transform: Mat33, _style: TextStyle): void;
drawText(text: string, _transform: Mat33, _style: TextRenderingStyle): void;
drawImage(image: RenderableImage): void;

@@ -29,0 +29,0 @@ isTooSmallToRender(rect: Rect2): boolean;

import Color4 from '../Color4';
interface RenderingStyle {
fill: Color4;
stroke?: {
color: Color4;
width: number;
readonly fill: Color4;
readonly stroke?: {
readonly color: Color4;
readonly width: number;
};

@@ -8,0 +8,0 @@ }

import RenderingStyle from './RenderingStyle';
export interface TextStyle {
size: number;
fontFamily: string;
fontWeight?: string;
fontVariant?: string;
renderingStyle: RenderingStyle;
export interface TextRenderingStyle {
readonly size: number;
readonly fontFamily: string;
readonly fontWeight?: string;
readonly fontVariant?: string;
readonly renderingStyle: RenderingStyle;
}
export default TextStyle;
export declare const cloneTextStyle: (style: TextStyle) => {
export default TextRenderingStyle;
export declare const cloneTextStyle: (style: TextRenderingStyle) => {
renderingStyle: {

@@ -23,4 +23,4 @@ fill: import("../Color4").default;

};
export declare const textStyleFromJSON: (json: any) => TextStyle;
export declare const textStyleToJSON: (style: TextStyle) => {
export declare const textStyleFromJSON: (json: any) => TextRenderingStyle;
export declare const textStyleToJSON: (style: TextRenderingStyle) => {
renderingStyle: {

@@ -27,0 +27,0 @@ fill: string;

@@ -71,5 +71,4 @@ "use strict";

var _a, _b, _c, _d, _f, _g;
const style = {
fill: Color4_1.default.transparent,
};
let fill = Color4_1.default.transparent;
let stroke;
// If possible, use computedStyles (allows property inheritance).

@@ -79,3 +78,3 @@ const fillAttribute = (_b = (_a = node.getAttribute('fill')) !== null && _a !== void 0 ? _a : computedStyles === null || computedStyles === void 0 ? void 0 : computedStyles.fill) !== null && _b !== void 0 ? _b : node.style.fill;

try {
style.fill = Color4_1.default.fromString(fillAttribute);
fill = Color4_1.default.fromString(fillAttribute);
}

@@ -96,3 +95,3 @@ catch (e) {

if (strokeColor.a > 0) {
style.stroke = {
stroke = {
width,

@@ -107,2 +106,6 @@ color: strokeColor,

}
const style = {
fill,
stroke,
};
return style;

@@ -109,0 +112,0 @@ }

import Color4 from '../Color4';
import { ComponentBuilderFactory } from '../components/builders/types';
import TextStyle from '../rendering/TextRenderingStyle';
import TextRenderingStyle from '../rendering/TextRenderingStyle';
import Pen from '../tools/Pen';

@@ -50,3 +50,3 @@ export type IconType = HTMLImageElement | SVGElement;

makeInsertImageIcon(): IconType;
makeTextIcon(textStyle: TextStyle): IconType;
makeTextIcon(textStyle: TextRenderingStyle): IconType;
makePenIcon(strokeSize: number, color: string | Color4, rounded?: boolean): IconType;

@@ -53,0 +53,0 @@ makeIconFromFactory(pen: Pen, factory: ComponentBuilderFactory): IconType;

@@ -30,3 +30,3 @@ "use strict";

selectionToolKeyboardShortcuts: 'Selection tool: Use arrow keys to move selected items, lowercase/uppercase ‘i’ and ‘o’ to resize.',
documentProperties: 'Document',
documentProperties: 'Page',
backgroundColor: 'Background Color: ',

@@ -33,0 +33,0 @@ imageWidthOption: 'Width: ',

@@ -130,3 +130,3 @@ "use strict";

// Listeners will fire regardless of whether this widget is selected and require that
// {@link lib!Editor.toolController} to have an enabled {@link lib!ToolbarShortcutHandler} tool.
// {@link Editor.toolController} to have an enabled {@link ToolbarShortcutHandler} tool.
onKeyPress(_event) {

@@ -133,0 +133,0 @@ return false;

@@ -16,2 +16,3 @@ /**

export { default as PasteHandler } from './PasteHandler';
export { default as SoundUITool } from './SoundUITool';
export { default as ToolbarShortcutHandler } from './ToolbarShortcutHandler';

@@ -9,3 +9,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.ToolbarShortcutHandler = exports.PasteHandler = exports.EraserTool = exports.SelectAllShortcutHandler = exports.SelectionTool = exports.TextTool = exports.PenTool = exports.PanZoomMode = exports.PanZoomTool = exports.ToolSwitcherShortcut = exports.UndoRedoShortcut = exports.ToolEnabledGroup = exports.ToolController = exports.BaseTool = void 0;
exports.ToolbarShortcutHandler = exports.SoundUITool = exports.PasteHandler = exports.EraserTool = exports.SelectAllShortcutHandler = exports.SelectionTool = exports.TextTool = exports.PenTool = exports.PanZoomMode = exports.PanZoomTool = exports.ToolSwitcherShortcut = exports.UndoRedoShortcut = exports.ToolEnabledGroup = exports.ToolController = exports.BaseTool = void 0;
var BaseTool_1 = require("./BaseTool");

@@ -36,3 +36,5 @@ Object.defineProperty(exports, "BaseTool", { enumerable: true, get: function () { return __importDefault(BaseTool_1).default; } });

Object.defineProperty(exports, "PasteHandler", { enumerable: true, get: function () { return __importDefault(PasteHandler_1).default; } });
var SoundUITool_1 = require("./SoundUITool");
Object.defineProperty(exports, "SoundUITool", { enumerable: true, get: function () { return __importDefault(SoundUITool_1).default; } });
var ToolbarShortcutHandler_1 = require("./ToolbarShortcutHandler");
Object.defineProperty(exports, "ToolbarShortcutHandler", { enumerable: true, get: function () { return __importDefault(ToolbarShortcutHandler_1).default; } });

@@ -16,2 +16,5 @@ export interface ToolLocalization {

pasteHandler: string;
soundExplorer: string;
disableAccessibilityExploreTool: string;
enableAccessibilityExploreTool: string;
findLabel: string;

@@ -18,0 +21,0 @@ toNextMatch: string;

@@ -19,2 +19,5 @@ "use strict";

pasteHandler: 'Copy paste handler',
soundExplorer: 'Sound-based image exploration',
disableAccessibilityExploreTool: 'Disable sound-based exploration',
enableAccessibilityExploreTool: 'Enable sound-based exploration',
findLabel: 'Find',

@@ -21,0 +24,0 @@ toNextMatch: 'Next',

@@ -6,3 +6,3 @@ import Color4 from '../Color4';

import { ToolLocalization } from './localization';
import TextStyle from '../rendering/TextRenderingStyle';
import TextRenderingStyle from '../rendering/TextRenderingStyle';
export default class TextTool extends BaseTool {

@@ -32,4 +32,4 @@ private editor;

setFontSize(size: number): void;
getTextStyle(): TextStyle;
getTextStyle(): TextRenderingStyle;
private setTextStyle;
}

@@ -45,2 +45,3 @@ "use strict";

const SelectAllShortcutHandler_1 = __importDefault(require("./SelectionTool/SelectAllShortcutHandler"));
const SoundUITool_1 = __importDefault(require("./SoundUITool"));
class ToolController {

@@ -64,6 +65,10 @@ /** @internal */

new TextTool_1.default(editor, localization.textTool, localization),
new PanZoom_1.default(editor, PanZoom_1.PanZoomMode.SinglePointerGestures, localization.anyDevicePanning)
new PanZoom_1.default(editor, PanZoom_1.PanZoomMode.SinglePointerGestures, localization.anyDevicePanning),
];
// Accessibility tools
const soundExplorer = new SoundUITool_1.default(editor, localization.soundExplorer);
soundExplorer.setEnabled(false);
this.tools = [
new PipetteTool_1.default(editor, localization.pipetteTool),
soundExplorer,
panZoomTool,

@@ -70,0 +75,0 @@ ...primaryTools,

@@ -0,1 +1,2 @@

import Vec3 from './math/Vec3';
export default class Color4 {

@@ -39,2 +40,9 @@ /** Red component. Should be in the range [0, 1]. */

static average(colors: Color4[]): Color4;
/**
* Converts to (hue, saturation, value).
* See also https://en.wikipedia.org/wiki/HSL_and_HSV#General_approach
*
* The resultant hue is represented in radians and is thus in [0, 2pi].
*/
asHSV(): Vec3;
private hexString;

@@ -41,0 +49,0 @@ /**

@@ -29,3 +29,3 @@ import SerializableCommand from '../commands/SerializableCommand';

*
* This is intended for use by a {@link ImageLoader}.
* This is intended for use by an {@link ImageLoader}.
*/

@@ -36,3 +36,3 @@ attachLoadSaveData(key: string, data: LoadSaveData): void;

getZIndex(): number;
/** @returns the bounding box of */
/** @returns the bounding box of this. */
getBBox(): Rect2;

@@ -39,0 +39,0 @@ /** Called when this component is added to the given image. */

@@ -10,4 +10,5 @@ export * from './builders/types';

import ImageComponent from './ImageComponent';
import RestyleableComponent, { createRestyleComponentCommand, isRestylableComponent } from './RestylableComponent';
import RestyleableComponent from './RestylableComponent';
import { createRestyleComponentCommand, isRestylableComponent, ComponentStyle as RestyleableComponentStyle } from './RestylableComponent';
import ImageBackground from './ImageBackground';
export { Stroke, TextComponent as Text, RestyleableComponent, createRestyleComponentCommand, isRestylableComponent, TextComponent, Stroke as StrokeComponent, ImageBackground as BackgroundComponent, ImageComponent, };
export { Stroke, TextComponent as Text, RestyleableComponent, createRestyleComponentCommand, isRestylableComponent, RestyleableComponentStyle, TextComponent, Stroke as StrokeComponent, ImageBackground as BackgroundComponent, ImageComponent, };
import Color4 from '../Color4';
import SerializableCommand from '../commands/SerializableCommand';
import Editor from '../Editor';
import TextStyle from '../rendering/TextRenderingStyle';
import TextRenderingStyle from '../rendering/TextRenderingStyle';
import AbstractComponent from './AbstractComponent';
export interface ComponentStyle {
color?: Color4;
textStyle?: TextStyle;
textStyle?: TextRenderingStyle;
}
export declare const createRestyleComponentCommand: (initialStyle: ComponentStyle, newStyle: ComponentStyle, component: RestyleableComponent) => SerializableCommand;
export declare const isRestylableComponent: (component: AbstractComponent) => component is RestyleableComponent;
/**
* An interface to be implemented by components with a changable color or {@link TextRenderingStyle}.
*
* All such classes must have a member variable, `isRestylableComponent` that is set to `true`
* to allow testing whether the class is a `RestylableComponent` (see {@link isRestylableComponent}).
*/
export interface RestyleableComponent extends AbstractComponent {
/**
* @returns a partial representation of this component's style.
*/
getStyle(): ComponentStyle;
/**
* Returns a {@link Command} that updates portions of this component's style
* to the given `style`.
*
* @example
* For some component and editor,
* ```ts
* editor.dispatch(component.updateStyle({ color: Color4.red }));
* ```
*/
updateStyle(style: ComponentStyle): SerializableCommand;

@@ -15,0 +34,0 @@ /**

@@ -11,2 +11,18 @@ import SerializableCommand from '../commands/SerializableCommand';

import RestyleableComponent, { ComponentStyle } from './RestylableComponent';
/**
* Represents an {@link AbstractComponent} made up of one or more {@link Path}s.
*
* @example
* For some {@link Editor} editor and `Stroke` stroke,
*
* **Restyling**:
* ```ts
* editor.dispatch(stroke.updateStyle({ color: Color4.red }));
* ```
*
* **Transforming**:
* ```ts
* editor.dispatch(stroke.transformBy(Mat33.translation(Vec2.of(10, 0))));
* ```
*/
export default class Stroke extends AbstractComponent implements RestyleableComponent {

@@ -17,2 +33,18 @@ private parts;

private approximateRenderingTime;
/**
* Creates a `Stroke` from the given `parts`. All parts should have the
* same color.
*
* @example
* ```ts
* // A path that starts at (1,1), moves to the right by (2, 0),
* // then moves down and right by (3, 3)
* const path = Path.fromString('m1,1 2,0 3,3');
*
* const stroke = new Stroke([
* // Fill with red
* path.toRenderable({ fill: Color4.red })
* ]);
* ```
*/
constructor(parts: RenderablePathSpec[]);

@@ -27,2 +59,5 @@ getStyle(): ComponentStyle;

protected applyTransformation(affineTransfm: Mat33): void;
/**
* @returns the {@link Path.union} of all paths that make up this stroke.
*/
getPath(): Path;

@@ -29,0 +64,0 @@ description(localization: ImageComponentLocalization): string;

@@ -7,6 +7,9 @@ import SerializableCommand from '../commands/SerializableCommand';

import AbstractRenderer from '../rendering/renderers/AbstractRenderer';
import { TextStyle } from '../rendering/TextRenderingStyle';
import { TextRenderingStyle } from '../rendering/TextRenderingStyle';
import AbstractComponent from './AbstractComponent';
import { ImageComponentLocalization } from './localization';
import RestyleableComponent, { ComponentStyle } from './RestylableComponent';
/**
* Displays text.
*/
export default class TextComponent extends AbstractComponent implements RestyleableComponent {

@@ -18,4 +21,9 @@ protected readonly textObjects: Array<string | TextComponent>;

readonly isRestylableComponent: true;
constructor(textObjects: Array<string | TextComponent>, transform: Mat33, style: TextStyle);
static applyTextStyles(ctx: CanvasRenderingContext2D, style: TextStyle): void;
/**
* Creates a new text object from a list of component text or child TextComponents.
*
* @see {@link fromLines}
*/
constructor(textObjects: Array<string | TextComponent>, transform: Mat33, style: TextRenderingStyle);
static applyTextStyles(ctx: CanvasRenderingContext2D, style: TextRenderingStyle): void;
private static textMeasuringCtx;

@@ -54,3 +62,17 @@ private static estimateTextDimens;

static deserializeFromString(json: any): TextComponent;
static fromLines(lines: string[], transform: Mat33, style: TextStyle): AbstractComponent;
/**
* Creates a `TextComponent` from `lines`.
*
* @example
* ```ts
* const textStyle = {
* size: 12,
* fontFamily: 'serif',
* renderingStyle: { fill: Color4.black },
* };
*
* const text = TextComponent.fromLines('foo\nbar'.split('\n'), Mat33.identity, textStyle);
* ```
*/
static fromLines(lines: string[], transform: Mat33, style: TextRenderingStyle): AbstractComponent;
}

@@ -56,3 +56,3 @@ import EditorImage from './EditorImage';

private renderingRegion;
/** Manages drawing surfaces/{@link lib!AbstractRenderer}s. */
/** Manages drawing surfaces/{@link AbstractRenderer}s. */
display: Display;

@@ -99,3 +99,3 @@ /**

readonly localization: EditorLocalization;
/** {@link lib!EditorSettings.iconProvider} */
/** {@link EditorSettings.iconProvider} */
readonly icons: IconProvider;

@@ -102,0 +102,0 @@ /**

@@ -8,2 +8,30 @@ /**

* import { Editor, Vec3, Mat33 } from 'js-draw';
*
* // Apply js-draw CSS
* import 'js-draw/styles';
* // If your bundler doesn't support the above, try
* // import 'js-draw/bundledStyles';
*
* (async () => {
* const editor = new Editor(document.body);
* const toolbar = editor.addToolbar();
* editor.getRootElement().style.height = '600px';
*
* await editor.loadFromSVG(`
* <svg viewBox="0 0 500 500" width="500" height="500" version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg">
* <style id="js-draw-style-sheet">path{stroke-linecap:round;stroke-linejoin:round;}text{white-space:pre;}</style>
* <path d="M500,500L500,0L0,0L0,500L500,500" fill="#423131bf" class="js-draw-image-background"></path>
* <text style="transform: matrix(1, 0, 0, 1, 57, 192); font-family: serif; font-size: 32px; fill: rgb(204, 102, 51);">Testing...</text>
* </svg>
* `);
*
* toolbar.addActionButton({
* label: 'Save',
* icon: editor.icons.makeSaveIcon(),
* }, () => {
* const saveData = editor.toSVG().outerHTML;
*
* // Do something with saveData
* });
* })();
* ```

@@ -13,2 +41,4 @@ *

* {@link Editor}
* {@link Editor.loadFromSVG}
* {@link HTMLToolbar.addActionButton }
*

@@ -15,0 +45,0 @@ * @packageDocumentation

@@ -6,1 +6,3 @@ export { default as AbstractRenderer } from './renderers/AbstractRenderer';

export { default as Display, RenderingMode } from './Display';
export { default as TextRenderingStyle } from './TextRenderingStyle';
export { default as RenderingStyle } from './RenderingStyle';

@@ -9,3 +9,3 @@ import Color4 from '../../Color4';

import RenderingStyle from '../RenderingStyle';
import TextStyle from '../TextRenderingStyle';
import TextRenderingStyle from '../TextRenderingStyle';
export interface RenderablePathSpec {

@@ -37,3 +37,3 @@ startPoint: Point2;

protected abstract traceQuadraticBezierCurve(controlPoint: Point2, endPoint: Point2): void;
abstract drawText(text: string, transform: Mat33, style: TextStyle): void;
abstract drawText(text: string, transform: Mat33, style: TextRenderingStyle): void;
abstract drawImage(image: RenderableImage): void;

@@ -40,0 +40,0 @@ abstract isTooSmallToRender(rect: Rect2): boolean;

@@ -7,3 +7,3 @@ import Mat33 from '../../math/Mat33';

import RenderingStyle from '../RenderingStyle';
import TextStyle from '../TextRenderingStyle';
import TextRenderingStyle from '../TextRenderingStyle';
import AbstractRenderer, { RenderableImage, RenderablePathSpec } from './AbstractRenderer';

@@ -57,3 +57,3 @@ /**

drawPath(path: RenderablePathSpec): void;
drawText(text: string, transform: Mat33, style: TextStyle): void;
drawText(text: string, transform: Mat33, style: TextRenderingStyle): void;
drawImage(image: RenderableImage): void;

@@ -60,0 +60,0 @@ private clipLevels;

@@ -7,3 +7,3 @@ import Mat33 from '../../math/Mat33';

import RenderingStyle from '../RenderingStyle';
import TextStyle from '../TextRenderingStyle';
import TextRenderingStyle from '../TextRenderingStyle';
import AbstractRenderer, { RenderableImage } from './AbstractRenderer';

@@ -29,3 +29,3 @@ export default class DummyRenderer extends AbstractRenderer {

drawPoints(..._points: Vec3[]): void;
drawText(text: string, _transform: Mat33, _style: TextStyle): void;
drawText(text: string, _transform: Mat33, _style: TextRenderingStyle): void;
drawImage(image: RenderableImage): void;

@@ -32,0 +32,0 @@ startObject(boundingBox: Rect2, _clip: boolean): void;

@@ -7,3 +7,3 @@ import { LoadSaveDataTable } from '../../components/AbstractComponent';

import RenderingStyle from '../RenderingStyle';
import TextStyle from '../TextRenderingStyle';
import TextRenderingStyle from '../TextRenderingStyle';
import AbstractRenderer, { RenderableImage, RenderablePathSpec } from './AbstractRenderer';

@@ -40,3 +40,3 @@ export declare const renderedStylesheetId = "js-draw-style-sheet";

private textParentStyle;
drawText(text: string, transform: Mat33, style: TextStyle): void;
drawText(text: string, transform: Mat33, style: TextRenderingStyle): void;
drawImage(image: RenderableImage): void;

@@ -43,0 +43,0 @@ startObject(boundingBox: Rect2): void;

@@ -7,3 +7,3 @@ import Mat33 from '../../math/Mat33';

import RenderingStyle from '../RenderingStyle';
import TextStyle from '../TextRenderingStyle';
import TextRenderingStyle from '../TextRenderingStyle';
import AbstractRenderer, { RenderableImage } from './AbstractRenderer';

@@ -26,3 +26,3 @@ export default class TextOnlyRenderer extends AbstractRenderer {

protected traceQuadraticBezierCurve(_controlPoint: Vec3, _endPoint: Vec3): void;
drawText(text: string, _transform: Mat33, _style: TextStyle): void;
drawText(text: string, _transform: Mat33, _style: TextRenderingStyle): void;
drawImage(image: RenderableImage): void;

@@ -29,0 +29,0 @@ isTooSmallToRender(rect: Rect2): boolean;

import Color4 from '../Color4';
interface RenderingStyle {
fill: Color4;
stroke?: {
color: Color4;
width: number;
readonly fill: Color4;
readonly stroke?: {
readonly color: Color4;
readonly width: number;
};

@@ -8,0 +8,0 @@ }

import RenderingStyle from './RenderingStyle';
export interface TextStyle {
size: number;
fontFamily: string;
fontWeight?: string;
fontVariant?: string;
renderingStyle: RenderingStyle;
export interface TextRenderingStyle {
readonly size: number;
readonly fontFamily: string;
readonly fontWeight?: string;
readonly fontVariant?: string;
readonly renderingStyle: RenderingStyle;
}
export default TextStyle;
export declare const cloneTextStyle: (style: TextStyle) => {
export default TextRenderingStyle;
export declare const cloneTextStyle: (style: TextRenderingStyle) => {
renderingStyle: {

@@ -23,4 +23,4 @@ fill: import("../Color4").default;

};
export declare const textStyleFromJSON: (json: any) => TextStyle;
export declare const textStyleToJSON: (style: TextStyle) => {
export declare const textStyleFromJSON: (json: any) => TextRenderingStyle;
export declare const textStyleToJSON: (style: TextRenderingStyle) => {
renderingStyle: {

@@ -27,0 +27,0 @@ fill: string;

import Color4 from '../Color4';
import { ComponentBuilderFactory } from '../components/builders/types';
import TextStyle from '../rendering/TextRenderingStyle';
import TextRenderingStyle from '../rendering/TextRenderingStyle';
import Pen from '../tools/Pen';

@@ -50,3 +50,3 @@ export type IconType = HTMLImageElement | SVGElement;

makeInsertImageIcon(): IconType;
makeTextIcon(textStyle: TextStyle): IconType;
makeTextIcon(textStyle: TextRenderingStyle): IconType;
makePenIcon(strokeSize: number, color: string | Color4, rounded?: boolean): IconType;

@@ -53,0 +53,0 @@ makeIconFromFactory(pen: Pen, factory: ComponentBuilderFactory): IconType;

@@ -16,2 +16,3 @@ /**

export { default as PasteHandler } from './PasteHandler';
export { default as SoundUITool } from './SoundUITool';
export { default as ToolbarShortcutHandler } from './ToolbarShortcutHandler';

@@ -16,2 +16,5 @@ export interface ToolLocalization {

pasteHandler: string;
soundExplorer: string;
disableAccessibilityExploreTool: string;
enableAccessibilityExploreTool: string;
findLabel: string;

@@ -18,0 +21,0 @@ toNextMatch: string;

@@ -6,3 +6,3 @@ import Color4 from '../Color4';

import { ToolLocalization } from './localization';
import TextStyle from '../rendering/TextRenderingStyle';
import TextRenderingStyle from '../rendering/TextRenderingStyle';
export default class TextTool extends BaseTool {

@@ -32,4 +32,4 @@ private editor;

setFontSize(size: number): void;
getTextStyle(): TextStyle;
getTextStyle(): TextRenderingStyle;
private setTextStyle;
}
{
"name": "js-draw",
"version": "0.18.2",
"version": "0.19.0",
"description": "Draw pictures using a pen, touchscreen, or mouse! JS-draw is a drawing library for JavaScript and TypeScript. ",
"types": "./dist/cjs/src/lib.d.ts",
"types": "./dist/mjs/src/lib.d.ts",
"main": "./dist/cjs/src/lib.js",
"exports": {
".": {
"types": "./dist/cjs/src/lib.d.ts",
"types": "./dist/mjs/src/lib.d.ts",
"import": "./dist/mjs/src/lib.mjs",

@@ -23,2 +23,5 @@ "require": "./dist/cjs/src/lib.js"

},
"./bundledStyles": {
"default": "./dist/bundledStyles.js"
},
"./Editor": {

@@ -83,3 +86,2 @@ "types": "./dist/mjs/src/Editor.d.ts",

"dependencies": {
"@babel/runtime": "^7.21.0",
"@melloware/coloris": "^0.18.0",

@@ -86,0 +88,0 @@ "bezier-js": "^6.1.3"

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc