Comparing version 0.1.10 to 0.1.11
@@ -0,1 +1,6 @@ | ||
# 0.1.11 | ||
* Fix 'Enter' key not toggling toolbar buttons. | ||
* Add zoom limits. | ||
* Add a reset zoom button. | ||
# 0.1.10 | ||
@@ -2,0 +7,0 @@ * Keyboard shortcuts for the selection tool. |
@@ -18,2 +18,4 @@ import EditorImage from './EditorImage'; | ||
wheelEventsEnabled: boolean | 'only-if-focused'; | ||
minZoom: number; | ||
maxZoom: number; | ||
} | ||
@@ -20,0 +22,0 @@ export declare class Editor { |
@@ -29,3 +29,3 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
constructor(parent, settings = {}) { | ||
var _a, _b; | ||
var _a, _b, _c, _d; | ||
this.announceUndoCallback = (command) => { | ||
@@ -44,2 +44,4 @@ this.announceForAccessibility(this.localization.undoAnnouncement(command.description(this.localization))); | ||
localization: this.localization, | ||
minZoom: (_c = settings.minZoom) !== null && _c !== void 0 ? _c : 2e-10, | ||
maxZoom: (_d = settings.maxZoom) !== null && _d !== void 0 ? _d : 1e12, | ||
}; | ||
@@ -76,2 +78,16 @@ this.container = document.createElement('div'); | ||
this.hideLoadingWarning(); | ||
// Enforce zoom limits. | ||
this.notifier.on(EditorEventType.ViewportChanged, evt => { | ||
if (evt.kind === EditorEventType.ViewportChanged) { | ||
const zoom = evt.newTransform.transformVec3(Vec2.unitX).length(); | ||
if (zoom > this.settings.maxZoom || zoom < this.settings.minZoom) { | ||
const oldZoom = evt.oldTransform.transformVec3(Vec2.unitX).length(); | ||
let resetTransform = Mat33.identity; | ||
if (oldZoom <= this.settings.maxZoom && oldZoom >= this.settings.minZoom) { | ||
resetTransform = evt.oldTransform; | ||
} | ||
this.viewport.resetTransform(resetTransform); | ||
} | ||
} | ||
}); | ||
} | ||
@@ -78,0 +94,0 @@ // Returns a reference to this' container. |
@@ -9,3 +9,3 @@ import { defaultEditorLocalization } from '../localization'; | ||
// (see src/toolbar/localization.ts) | ||
pen: 'Lapiz', eraser: 'Borrador', select: 'Selecciona', thicknessLabel: 'Tamaño: ', colorLabel: 'Color: ', doneLoading: 'El cargado terminó', fontLabel: 'Fuente: ', anyDevicePanning: 'Mover la pantalla con todo dispotivo', touchPanning: 'Mover la pantalla con un dedo', touchPanTool: 'Instrumento de mover la pantalla con un dedo', outlinedRectanglePen: 'Rectángulo con nada más que un borde', filledRectanglePen: 'Rectángulo sin borde', linePen: 'Línea', arrowPen: 'Flecha', freehandPen: 'Dibuja sin restricción de forma', selectObjectType: 'Forma de dibuja:', handTool: 'Mover', resizeImageToSelection: 'Redimensionar la imagen a lo que está seleccionado', deleteSelection: 'Borra la selección', duplicateSelection: 'Duplica la selección', pickColorFronScreen: 'Selecciona un color de la pantalla', dropdownShown(toolName) { | ||
pen: 'Lapiz', eraser: 'Borrador', select: 'Selecciona', thicknessLabel: 'Tamaño: ', colorLabel: 'Color: ', doneLoading: 'El cargado terminó', fontLabel: 'Fuente: ', anyDevicePanning: 'Mover la pantalla con todo dispotivo', touchPanning: 'Mover la pantalla con un dedo', touchPanTool: 'Instrumento de mover la pantalla con un dedo', outlinedRectanglePen: 'Rectángulo con nada más que un borde', filledRectanglePen: 'Rectángulo sin borde', linePen: 'Línea', arrowPen: 'Flecha', freehandPen: 'Dibuja sin restricción de forma', selectObjectType: 'Forma de dibuja:', handTool: 'Mover', zoom: 'Zoom', resetView: 'Reiniciar vista', resizeImageToSelection: 'Redimensionar la imagen a lo que está seleccionado', deleteSelection: 'Borra la selección', duplicateSelection: 'Duplica la selección', pickColorFronScreen: 'Selecciona un color de la pantalla', dropdownShown(toolName) { | ||
return `Menú por ${toolName} es visible`; | ||
@@ -12,0 +12,0 @@ }, dropdownHidden: function (toolName) { |
@@ -24,2 +24,3 @@ export interface ToolbarLocalization { | ||
zoom: string; | ||
resetView: string; | ||
selectionToolKeyboardShortcuts: string; | ||
@@ -26,0 +27,0 @@ dropdownShown: (toolName: string) => string; |
@@ -7,2 +7,3 @@ export const defaultToolbarLocalization = { | ||
zoom: 'Zoom', | ||
resetView: 'Reset view', | ||
thicknessLabel: 'Thickness: ', | ||
@@ -9,0 +10,0 @@ colorLabel: 'Color: ', |
@@ -48,3 +48,3 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { | ||
setupActionBtnClickListener(button) { | ||
const clickTriggers = { enter: true, ' ': true, }; | ||
const clickTriggers = { Enter: true, ' ': true, }; | ||
button.onkeydown = (evt) => { | ||
@@ -51,0 +51,0 @@ let handled = false; |
@@ -13,6 +13,8 @@ import Mat33 from '../../geometry/Mat33'; | ||
const decreaseButton = document.createElement('button'); | ||
const resetViewButton = document.createElement('button'); | ||
const zoomLevelDisplay = document.createElement('span'); | ||
increaseButton.innerText = '+'; | ||
decreaseButton.innerText = '-'; | ||
zoomLevelRow.replaceChildren(zoomLevelDisplay, increaseButton, decreaseButton); | ||
resetViewButton.innerText = localizationTable.resetView; | ||
zoomLevelRow.replaceChildren(zoomLevelDisplay, increaseButton, decreaseButton, resetViewButton); | ||
zoomLevelRow.classList.add(`${toolbarCSSPrefix}zoomLevelEditor`); | ||
@@ -38,2 +40,4 @@ zoomLevelDisplay.classList.add('zoomDisplay'); | ||
updateZoomDisplay(); | ||
// Can't reset if already reset. | ||
resetViewButton.disabled = event.newTransform.eq(Mat33.identity); | ||
} | ||
@@ -52,2 +56,5 @@ }); | ||
}; | ||
resetViewButton.onclick = () => { | ||
editor.dispatch(new Viewport.ViewportTransform(editor.viewport.canvasToScreenTransform.inverse()), true); | ||
}; | ||
return zoomLevelRow; | ||
@@ -54,0 +61,0 @@ }; |
@@ -124,5 +124,5 @@ import Mat33 from '../geometry/Mat33'; | ||
onWheel({ delta, screenPos }) { | ||
if (this.transform === null) { | ||
this.transform = new Viewport.ViewportTransform(Mat33.identity); | ||
} | ||
// Reset the transformation -- wheel events are individual events, so we don't | ||
// need to unapply/reapply. | ||
this.transform = new Viewport.ViewportTransform(Mat33.identity); | ||
const canvasPos = this.editor.viewport.screenToCanvas(screenPos); | ||
@@ -133,3 +133,3 @@ const toCanvas = this.editor.viewport.screenToCanvasTransform; | ||
const pinchZoomScaleFactor = 1.04; | ||
const transformUpdate = Mat33.scaling2D(Math.pow(pinchZoomScaleFactor, -delta.z), canvasPos).rightMul(Mat33.translation(translation)); | ||
const transformUpdate = Mat33.scaling2D(Math.max(0.25, Math.min(Math.pow(pinchZoomScaleFactor, -delta.z), 4)), canvasPos).rightMul(Mat33.translation(translation)); | ||
this.updateTransform(transformUpdate); | ||
@@ -142,2 +142,4 @@ return true; | ||
} | ||
// No need to keep the same the transform for keyboard events. | ||
this.transform = new Viewport.ViewportTransform(Mat33.identity); | ||
let translation = Vec2.zero; | ||
@@ -144,0 +146,0 @@ let scale = 1; |
@@ -82,2 +82,3 @@ import EventDispatcher from './EventDispatcher'; | ||
readonly newTransform: Mat33; | ||
readonly oldTransform: Mat33; | ||
} | ||
@@ -84,0 +85,0 @@ export interface DisplayResizedEvent { |
@@ -41,2 +41,3 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { | ||
resetTransform(newTransform = Mat33.identity) { | ||
const oldTransform = this.transform; | ||
this.transform = newTransform; | ||
@@ -47,2 +48,3 @@ this.inverseTransform = newTransform.inverse(); | ||
newTransform, | ||
oldTransform, | ||
}); | ||
@@ -49,0 +51,0 @@ } |
{ | ||
"name": "js-draw", | ||
"version": "0.1.10", | ||
"version": "0.1.11", | ||
"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", |
@@ -34,2 +34,5 @@ | ||
wheelEventsEnabled: boolean|'only-if-focused'; | ||
minZoom: number, | ||
maxZoom: number, | ||
} | ||
@@ -73,2 +76,4 @@ | ||
localization: this.localization, | ||
minZoom: settings.minZoom ?? 2e-10, | ||
maxZoom: settings.maxZoom ?? 1e12, | ||
}; | ||
@@ -116,2 +121,20 @@ | ||
this.hideLoadingWarning(); | ||
// Enforce zoom limits. | ||
this.notifier.on(EditorEventType.ViewportChanged, evt => { | ||
if (evt.kind === EditorEventType.ViewportChanged) { | ||
const zoom = evt.newTransform.transformVec3(Vec2.unitX).length(); | ||
if (zoom > this.settings.maxZoom || zoom < this.settings.minZoom) { | ||
const oldZoom = evt.oldTransform.transformVec3(Vec2.unitX).length(); | ||
let resetTransform = Mat33.identity; | ||
if (oldZoom <= this.settings.maxZoom && oldZoom >= this.settings.minZoom) { | ||
resetTransform = evt.oldTransform; | ||
} | ||
this.viewport.resetTransform(resetTransform); | ||
} | ||
} | ||
}); | ||
} | ||
@@ -118,0 +141,0 @@ |
@@ -36,2 +36,4 @@ import { defaultEditorLocalization, EditorLocalization } from '../localization'; | ||
handTool: 'Mover', | ||
zoom: 'Zoom', | ||
resetView: 'Reiniciar vista', | ||
resizeImageToSelection: 'Redimensionar la imagen a lo que está seleccionado', | ||
@@ -38,0 +40,0 @@ deleteSelection: 'Borra la selección', |
@@ -26,2 +26,3 @@ | ||
zoom: string; | ||
resetView: string; | ||
selectionToolKeyboardShortcuts: string; | ||
@@ -41,2 +42,3 @@ | ||
zoom: 'Zoom', | ||
resetView: 'Reset view', | ||
thicknessLabel: 'Thickness: ', | ||
@@ -43,0 +45,0 @@ colorLabel: 'Color: ', |
@@ -54,3 +54,3 @@ import Editor from '../../Editor'; | ||
protected setupActionBtnClickListener(button: HTMLElement) { | ||
const clickTriggers = { enter: true, ' ': true, }; | ||
const clickTriggers = { Enter: true, ' ': true, }; | ||
button.onkeydown = (evt) => { | ||
@@ -57,0 +57,0 @@ let handled = false; |
@@ -17,6 +17,8 @@ import Editor from '../../Editor'; | ||
const decreaseButton = document.createElement('button'); | ||
const resetViewButton = document.createElement('button'); | ||
const zoomLevelDisplay = document.createElement('span'); | ||
increaseButton.innerText = '+'; | ||
decreaseButton.innerText = '-'; | ||
zoomLevelRow.replaceChildren(zoomLevelDisplay, increaseButton, decreaseButton); | ||
resetViewButton.innerText = localizationTable.resetView; | ||
zoomLevelRow.replaceChildren(zoomLevelDisplay, increaseButton, decreaseButton, resetViewButton); | ||
@@ -46,2 +48,5 @@ zoomLevelRow.classList.add(`${toolbarCSSPrefix}zoomLevelEditor`); | ||
updateZoomDisplay(); | ||
// Can't reset if already reset. | ||
resetViewButton.disabled = event.newTransform.eq(Mat33.identity); | ||
} | ||
@@ -64,2 +69,8 @@ }); | ||
resetViewButton.onclick = () => { | ||
editor.dispatch(new Viewport.ViewportTransform( | ||
editor.viewport.canvasToScreenTransform.inverse() | ||
), true); | ||
}; | ||
return zoomLevelRow; | ||
@@ -66,0 +77,0 @@ }; |
@@ -161,5 +161,5 @@ | ||
public onWheel({ delta, screenPos }: WheelEvt): boolean { | ||
if (this.transform === null) { | ||
this.transform = new Viewport.ViewportTransform(Mat33.identity); | ||
} | ||
// Reset the transformation -- wheel events are individual events, so we don't | ||
// need to unapply/reapply. | ||
this.transform = new Viewport.ViewportTransform(Mat33.identity); | ||
@@ -176,3 +176,3 @@ const canvasPos = this.editor.viewport.screenToCanvas(screenPos); | ||
const transformUpdate = Mat33.scaling2D( | ||
Math.pow(pinchZoomScaleFactor, -delta.z), canvasPos | ||
Math.max(0.25, Math.min(Math.pow(pinchZoomScaleFactor, -delta.z), 4)), canvasPos | ||
).rightMul( | ||
@@ -191,2 +191,5 @@ Mat33.translation(translation) | ||
// No need to keep the same the transform for keyboard events. | ||
this.transform = new Viewport.ViewportTransform(Mat33.identity); | ||
let translation = Vec2.zero; | ||
@@ -193,0 +196,0 @@ let scale = 1; |
@@ -120,2 +120,3 @@ // Types related to the image editor | ||
readonly newTransform: Mat33; | ||
readonly oldTransform: Mat33; | ||
} | ||
@@ -122,0 +123,0 @@ |
@@ -106,2 +106,3 @@ import Command from './commands/Command'; | ||
public resetTransform(newTransform: Mat33 = Mat33.identity) { | ||
const oldTransform = this.transform; | ||
this.transform = newTransform; | ||
@@ -112,2 +113,3 @@ this.inverseTransform = newTransform.inverse(); | ||
newTransform, | ||
oldTransform, | ||
}); | ||
@@ -114,0 +116,0 @@ } |
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
974707
20616