Comparing version 0.1.4 to 0.1.5
@@ -0,1 +1,5 @@ | ||
# 0.1.5 | ||
* Add a text-only renderer (only renders text objects at present) that can be activated with a screen reader. | ||
* Make new text objects parallel to screen's horizontal axis. | ||
# 0.1.4 | ||
@@ -2,0 +6,0 @@ * Option to enable pan gestures only if the editor has focus |
import { CommandLocalization } from './commands/localization'; | ||
import { ImageComponentLocalization } from './components/localization'; | ||
import { TextRendererLocalization } from './rendering/localization'; | ||
import { ToolbarLocalization } from './toolbar/localization'; | ||
import { ToolLocalization } from './tools/localization'; | ||
export interface EditorLocalization extends ToolbarLocalization, ToolLocalization, CommandLocalization, ImageComponentLocalization { | ||
export interface EditorLocalization extends ToolbarLocalization, ToolLocalization, CommandLocalization, ImageComponentLocalization, TextRendererLocalization { | ||
undoAnnouncement: (actionDescription: string) => string; | ||
@@ -7,0 +8,0 @@ redoAnnouncement: (actionDescription: string) => string; |
import { defaultCommandLocalization } from './commands/localization'; | ||
import { defaultComponentLocalization } from './components/localization'; | ||
import { defaultTextRendererLocalization } from './rendering/localization'; | ||
import { defaultToolbarLocalization } from './toolbar/localization'; | ||
import { defaultToolLocalization } from './tools/localization'; | ||
export const defaultEditorLocalization = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, defaultToolbarLocalization), defaultToolLocalization), defaultCommandLocalization), defaultComponentLocalization), { loading: (percentage) => `Loading ${percentage}%...`, imageEditor: 'Image Editor', doneLoading: 'Done loading', undoAnnouncement: (commandDescription) => `Undid ${commandDescription}`, redoAnnouncement: (commandDescription) => `Redid ${commandDescription}` }); | ||
export const defaultEditorLocalization = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, defaultToolbarLocalization), defaultToolLocalization), defaultCommandLocalization), defaultComponentLocalization), defaultTextRendererLocalization), { loading: (percentage) => `Loading ${percentage}%...`, imageEditor: 'Image Editor', doneLoading: 'Done loading', undoAnnouncement: (commandDescription) => `Undid ${commandDescription}`, redoAnnouncement: (commandDescription) => `Redid ${commandDescription}` }); |
@@ -13,2 +13,3 @@ import AbstractRenderer from './renderers/AbstractRenderer'; | ||
private wetInkRenderer; | ||
private textRenderer; | ||
private cache; | ||
@@ -22,2 +23,3 @@ private resizeSurfacesCallback?; | ||
private initializeCanvasRendering; | ||
private initializeTextRendering; | ||
startRerender(): AbstractRenderer; | ||
@@ -24,0 +26,0 @@ setDraftMode(draftMode: boolean): void; |
@@ -6,2 +6,3 @@ import CanvasRenderer from './renderers/CanvasRenderer'; | ||
import RenderingCache from './caching/RenderingCache'; | ||
import TextOnlyRenderer from './renderers/TextOnlyRenderer'; | ||
export var RenderingMode; | ||
@@ -27,2 +28,4 @@ (function (RenderingMode) { | ||
} | ||
this.textRenderer = new TextOnlyRenderer(editor.viewport, editor.localization); | ||
this.initializeTextRendering(); | ||
const cacheBlockResolution = Vec2.of(600, 600); | ||
@@ -109,2 +112,18 @@ this.cache = new RenderingCache({ | ||
} | ||
initializeTextRendering() { | ||
const textRendererOutputContainer = document.createElement('div'); | ||
textRendererOutputContainer.classList.add('textRendererOutputContainer'); | ||
const rerenderButton = document.createElement('button'); | ||
rerenderButton.classList.add('rerenderButton'); | ||
rerenderButton.innerText = this.editor.localization.rerenderAsText; | ||
const rerenderOutput = document.createElement('div'); | ||
rerenderOutput.ariaLive = 'polite'; | ||
rerenderButton.onclick = () => { | ||
this.textRenderer.clear(); | ||
this.editor.image.render(this.textRenderer, this.editor.viewport); | ||
rerenderOutput.innerText = this.textRenderer.getDescription(); | ||
}; | ||
textRendererOutputContainer.replaceChildren(rerenderButton, rerenderOutput); | ||
this.editor.createHTMLOverlay(textRendererOutputContainer); | ||
} | ||
// Clears the drawing surfaces and otherwise prepares for a rerender. | ||
@@ -111,0 +130,0 @@ startRerender() { |
@@ -17,2 +17,3 @@ import Color4 from '../Color4'; | ||
private textMeasuringCtx; | ||
private textRotation; | ||
constructor(editor: Editor, description: string, localizationTable: ToolLocalization); | ||
@@ -19,0 +20,0 @@ private getTextAscent; |
@@ -61,3 +61,3 @@ import Color4 from '../Color4'; | ||
} | ||
const textTransform = Mat33.translation(this.textTargetPosition).rightMul(Mat33.scaling2D(this.editor.viewport.getSizeOfPixelOnCanvas())); | ||
const textTransform = Mat33.translation(this.textTargetPosition).rightMul(Mat33.scaling2D(this.editor.viewport.getSizeOfPixelOnCanvas())).rightMul(Mat33.zRotation(this.textRotation)); | ||
const textComponent = new Text([content], textTransform, this.textStyle); | ||
@@ -75,3 +75,3 @@ const action = new EditorImage.AddElementCommand(textComponent); | ||
const viewport = this.editor.viewport; | ||
const textScreenPos = this.editor.viewport.canvasToScreen(this.textTargetPosition); | ||
const textScreenPos = viewport.canvasToScreen(this.textTargetPosition); | ||
this.textInputElem.type = 'text'; | ||
@@ -88,3 +88,3 @@ this.textInputElem.placeholder = this.localizationTable.enterTextToInsert; | ||
this.textInputElem.style.margin = '0'; | ||
const rotation = viewport.getRotationAngle(); | ||
const rotation = this.textRotation + viewport.getRotationAngle(); | ||
const ascent = this.getTextAscent(this.textInputElem.value || 'W', this.textStyle); | ||
@@ -99,2 +99,3 @@ this.textInputElem.style.transform = `rotate(${rotation * 180 / Math.PI}deg) translate(0, ${-ascent}px)`; | ||
this.textTargetPosition = textCanvasPos; | ||
this.textRotation = -this.editor.viewport.getRotationAngle(); | ||
this.updateTextInput(); | ||
@@ -101,0 +102,0 @@ this.textInputElem.oninput = () => { |
@@ -96,3 +96,3 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { | ||
} | ||
// Try to move the selection within the center 2/3rds of the viewport. | ||
// Try to move the selection within the center 3/4ths of the viewport. | ||
const recomputeTargetRect = () => { | ||
@@ -102,3 +102,3 @@ // transform transforms objects on the canvas. As such, we need to invert it | ||
const visibleRect = this.visibleRect.transformedBoundingBox(transform.inverse()); | ||
return visibleRect.transformedBoundingBox(Mat33.scaling2D(2 / 3, visibleRect.center)); | ||
return visibleRect.transformedBoundingBox(Mat33.scaling2D(3 / 4, visibleRect.center)); | ||
}; | ||
@@ -108,3 +108,3 @@ let targetRect = recomputeTargetRect(); | ||
// Ensure that toMakeVisible is at least 1/8th of the visible region. | ||
const muchSmallerThanTarget = toMakeVisible.maxDimension / targetRect.maxDimension < 0.125; | ||
const muchSmallerThanTarget = toMakeVisible.maxDimension / targetRect.maxDimension < 0.25; | ||
if ((largerThanTarget && allowZoomOut) || (muchSmallerThanTarget && allowZoomIn)) { | ||
@@ -111,0 +111,0 @@ // If larger than the target, ensure that the longest axis is visible. |
{ | ||
"name": "js-draw", | ||
"version": "0.1.4", | ||
"version": "0.1.5", | ||
"description": "Draw pictures using a pen, touchscreen, or mouse! JS-draw is a drawing library for JavaScript and TypeScript. ", | ||
@@ -5,0 +5,0 @@ "main": "dist/src/Editor.js", |
@@ -39,4 +39,4 @@ # js-draw | ||
```html | ||
<!-- Replace 0.1.2 with the latest version of js-draw --> | ||
<script src="https://cdn.jsdelivr.net/npm/js-draw@0.1.2/dist/bundle.js"></script> | ||
<!-- Replace 0.1.5 with the latest version of js-draw --> | ||
<script src="https://cdn.jsdelivr.net/npm/js-draw@0.1.5/dist/bundle.js"></script> | ||
<script> | ||
@@ -43,0 +43,0 @@ const editor = new jsdraw.Editor(document.body); |
import { CommandLocalization, defaultCommandLocalization } from './commands/localization'; | ||
import { defaultComponentLocalization, ImageComponentLocalization } from './components/localization'; | ||
import { defaultTextRendererLocalization, TextRendererLocalization } from './rendering/localization'; | ||
import { defaultToolbarLocalization, ToolbarLocalization } from './toolbar/localization'; | ||
@@ -7,3 +8,3 @@ import { defaultToolLocalization, ToolLocalization } from './tools/localization'; | ||
export interface EditorLocalization extends ToolbarLocalization, ToolLocalization, CommandLocalization, ImageComponentLocalization { | ||
export interface EditorLocalization extends ToolbarLocalization, ToolLocalization, CommandLocalization, ImageComponentLocalization, TextRendererLocalization { | ||
undoAnnouncement: (actionDescription: string)=> string; | ||
@@ -21,2 +22,3 @@ redoAnnouncement: (actionDescription: string)=> string; | ||
...defaultComponentLocalization, | ||
...defaultTextRendererLocalization, | ||
loading: (percentage: number) => `Loading ${percentage}%...`, | ||
@@ -23,0 +25,0 @@ imageEditor: 'Image Editor', |
@@ -8,2 +8,3 @@ import AbstractRenderer from './renderers/AbstractRenderer'; | ||
import RenderingCache from './caching/RenderingCache'; | ||
import TextOnlyRenderer from './renderers/TextOnlyRenderer'; | ||
@@ -19,2 +20,3 @@ export enum RenderingMode { | ||
private wetInkRenderer: AbstractRenderer; | ||
private textRenderer: TextOnlyRenderer; | ||
private cache: RenderingCache; | ||
@@ -36,2 +38,5 @@ private resizeSurfacesCallback?: ()=> void; | ||
this.textRenderer = new TextOnlyRenderer(editor.viewport, editor.localization); | ||
this.initializeTextRendering(); | ||
const cacheBlockResolution = Vec2.of(600, 600); | ||
@@ -135,2 +140,23 @@ this.cache = new RenderingCache({ | ||
private initializeTextRendering() { | ||
const textRendererOutputContainer = document.createElement('div'); | ||
textRendererOutputContainer.classList.add('textRendererOutputContainer'); | ||
const rerenderButton = document.createElement('button'); | ||
rerenderButton.classList.add('rerenderButton'); | ||
rerenderButton.innerText = this.editor.localization.rerenderAsText; | ||
const rerenderOutput = document.createElement('div'); | ||
rerenderOutput.ariaLive = 'polite'; | ||
rerenderButton.onclick = () => { | ||
this.textRenderer.clear(); | ||
this.editor.image.render(this.textRenderer, this.editor.viewport); | ||
rerenderOutput.innerText = this.textRenderer.getDescription(); | ||
}; | ||
textRendererOutputContainer.replaceChildren(rerenderButton, rerenderOutput); | ||
this.editor.createHTMLOverlay(textRendererOutputContainer); | ||
} | ||
// Clears the drawing surfaces and otherwise prepares for a rerender. | ||
@@ -137,0 +163,0 @@ public startRerender(): AbstractRenderer { |
@@ -22,2 +22,3 @@ import Color4 from '../Color4'; | ||
private textMeasuringCtx: CanvasRenderingContext2D|null = null; | ||
private textRotation: number; | ||
@@ -77,2 +78,4 @@ public constructor(private editor: Editor, description: string, private localizationTable: ToolLocalization) { | ||
Mat33.scaling2D(this.editor.viewport.getSizeOfPixelOnCanvas()) | ||
).rightMul( | ||
Mat33.zRotation(this.textRotation) | ||
); | ||
@@ -98,3 +101,3 @@ | ||
const viewport = this.editor.viewport; | ||
const textScreenPos = this.editor.viewport.canvasToScreen(this.textTargetPosition); | ||
const textScreenPos = viewport.canvasToScreen(this.textTargetPosition); | ||
this.textInputElem.type = 'text'; | ||
@@ -113,3 +116,3 @@ this.textInputElem.placeholder = this.localizationTable.enterTextToInsert; | ||
const rotation = viewport.getRotationAngle(); | ||
const rotation = this.textRotation + viewport.getRotationAngle(); | ||
const ascent = this.getTextAscent(this.textInputElem.value || 'W', this.textStyle); | ||
@@ -126,2 +129,3 @@ this.textInputElem.style.transform = `rotate(${rotation * 180 / Math.PI}deg) translate(0, ${-ascent}px)`; | ||
this.textTargetPosition = textCanvasPos; | ||
this.textRotation = -this.editor.viewport.getRotationAngle(); | ||
this.updateTextInput(); | ||
@@ -128,0 +132,0 @@ |
@@ -184,3 +184,3 @@ import Command from './commands/Command'; | ||
// Try to move the selection within the center 2/3rds of the viewport. | ||
// Try to move the selection within the center 3/4ths of the viewport. | ||
const recomputeTargetRect = () => { | ||
@@ -190,3 +190,3 @@ // transform transforms objects on the canvas. As such, we need to invert it | ||
const visibleRect = this.visibleRect.transformedBoundingBox(transform.inverse()); | ||
return visibleRect.transformedBoundingBox(Mat33.scaling2D(2 / 3, visibleRect.center)); | ||
return visibleRect.transformedBoundingBox(Mat33.scaling2D(3 / 4, visibleRect.center)); | ||
}; | ||
@@ -198,3 +198,3 @@ | ||
// Ensure that toMakeVisible is at least 1/8th of the visible region. | ||
const muchSmallerThanTarget = toMakeVisible.maxDimension / targetRect.maxDimension < 0.125; | ||
const muchSmallerThanTarget = toMakeVisible.maxDimension / targetRect.maxDimension < 0.25; | ||
@@ -201,0 +201,0 @@ if ((largerThanTarget && allowZoomOut) || (muchSmallerThanTarget && allowZoomIn)) { |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
842350
219
17613