[fix] page to screen (#1797)
This PR fixes our page to screen conversion. ### Change Type - [x] `patch` — Bug fix ### Test Plan 1. Drop an image onto the screen while the camera is panned and zoomed. - [x] Unit Tests
This commit is contained in:
parent
8991468446
commit
16e696ed03
7 changed files with 129 additions and 198 deletions
|
@ -827,9 +827,9 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
moveShapesToPage(shapes: TLShape[], pageId: TLPageId): this;
|
||||
// (undocumented)
|
||||
moveShapesToPage(ids: TLShapeId[], pageId: TLPageId): this;
|
||||
nudgeShapes(shapes: TLShape[], offset: VecLike, historyOptions?: CommandHistoryOptions): this;
|
||||
nudgeShapes(shapes: TLShape[], offset: VecLike, historyOptions?: TLCommandHistoryOptions): this;
|
||||
// (undocumented)
|
||||
nudgeShapes(ids: TLShapeId[], offset: VecLike, historyOptions?: CommandHistoryOptions): this;
|
||||
nudgeShapes(ids: TLShapeId[], offset: VecLike, historyOptions?: TLCommandHistoryOptions): this;
|
||||
get onlySelectedShape(): null | TLShape;
|
||||
get openMenus(): string[];
|
||||
packShapes(shapes: TLShape[], gap: number): this;
|
||||
|
@ -859,9 +859,9 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
registerExternalContentHandler<T extends TLExternalContent_2['type']>(type: T, handler: ((info: T extends TLExternalContent_2['type'] ? TLExternalContent_2 & {
|
||||
type: T;
|
||||
} : TLExternalContent_2) => void) | null): this;
|
||||
renamePage(page: TLPage, name: string, historyOptions?: CommandHistoryOptions): this;
|
||||
renamePage(page: TLPage, name: string, historyOptions?: TLCommandHistoryOptions): this;
|
||||
// (undocumented)
|
||||
renamePage(id: TLPageId, name: string, historyOptions?: CommandHistoryOptions): this;
|
||||
renamePage(id: TLPageId, name: string, historyOptions?: TLCommandHistoryOptions): this;
|
||||
get renderingBounds(): Box2d;
|
||||
get renderingBoundsExpanded(): Box2d;
|
||||
renderingBoundsMargin: number;
|
||||
|
@ -910,9 +910,9 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
sendToBack(ids: TLShapeId[]): this;
|
||||
setCamera(point: VecLike, animation?: TLAnimationOptions): this;
|
||||
setCroppingShapeId(id: null | TLShapeId): this;
|
||||
setCurrentPage(page: TLPage, historyOptions?: CommandHistoryOptions): this;
|
||||
setCurrentPage(page: TLPage, historyOptions?: TLCommandHistoryOptions): this;
|
||||
// (undocumented)
|
||||
setCurrentPage(pageId: TLPageId, historyOptions?: CommandHistoryOptions): this;
|
||||
setCurrentPage(pageId: TLPageId, historyOptions?: TLCommandHistoryOptions): this;
|
||||
setCurrentTool(id: string, info?: {}): this;
|
||||
setCursor: (cursor: Partial<TLCursor>) => this;
|
||||
setEditingShapeId(id: null | TLShapeId): this;
|
||||
|
@ -920,9 +920,9 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
setFocusedGroupId(next: null | TLShapeId): this;
|
||||
setHintingIds(ids: TLShapeId[]): this;
|
||||
setHoveredShapeId(id: null | TLShapeId): this;
|
||||
setOpacity(opacity: number, historyOptions?: CommandHistoryOptions): this;
|
||||
setSelectedShapeIds(ids: TLShapeId[], historyOptions?: CommandHistoryOptions): this;
|
||||
setStyle<T>(style: StyleProp<T>, value: T, historyOptions?: CommandHistoryOptions): this;
|
||||
setOpacity(opacity: number, historyOptions?: TLCommandHistoryOptions): this;
|
||||
setSelectedShapeIds(ids: TLShapeId[], historyOptions?: TLCommandHistoryOptions): this;
|
||||
setStyle<T>(style: StyleProp<T>, value: T, historyOptions?: TLCommandHistoryOptions): this;
|
||||
shapeUtils: {
|
||||
readonly [K in string]?: ShapeUtil<TLUnknownShape>;
|
||||
};
|
||||
|
@ -959,14 +959,14 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
// (undocumented)
|
||||
ungroupShapes(ids: TLShape[]): this;
|
||||
updateAssets(assets: TLAssetPartial[]): this;
|
||||
updateCurrentPageState(partial: Partial<Omit<TLInstancePageState, 'editingShapeId' | 'focusedGroupId' | 'pageId' | 'selectedShapeIds'>>, historyOptions?: CommandHistoryOptions): this;
|
||||
updateCurrentPageState(partial: Partial<Omit<TLInstancePageState, 'editingShapeId' | 'focusedGroupId' | 'pageId' | 'selectedShapeIds'>>, historyOptions?: TLCommandHistoryOptions): this;
|
||||
updateDocumentSettings(settings: Partial<TLDocument>): this;
|
||||
updateInstanceState(partial: Partial<Omit<TLInstance, 'currentPageId'>>, historyOptions?: CommandHistoryOptions): this;
|
||||
updatePage(partial: RequiredKeys<TLPage, 'id'>, historyOptions?: CommandHistoryOptions): this;
|
||||
updateInstanceState(partial: Partial<Omit<TLInstance, 'currentPageId'>>, historyOptions?: TLCommandHistoryOptions): this;
|
||||
updatePage(partial: RequiredKeys<TLPage, 'id'>, historyOptions?: TLCommandHistoryOptions): this;
|
||||
// @internal
|
||||
updateRenderingBounds(): this;
|
||||
updateShape<T extends TLUnknownShape>(partial: null | TLShapePartial<T> | undefined, historyOptions?: CommandHistoryOptions): this;
|
||||
updateShapes<T extends TLUnknownShape>(partials: (null | TLShapePartial<T> | undefined)[], historyOptions?: CommandHistoryOptions): this;
|
||||
updateShape<T extends TLUnknownShape>(partial: null | TLShapePartial<T> | undefined, historyOptions?: TLCommandHistoryOptions): this;
|
||||
updateShapes<T extends TLUnknownShape>(partials: (null | TLShapePartial<T> | undefined)[], historyOptions?: TLCommandHistoryOptions): this;
|
||||
updateViewportScreenBounds(center?: boolean): this;
|
||||
readonly user: UserPreferencesManager;
|
||||
get viewportPageBounds(): Box2d;
|
||||
|
|
|
@ -105,7 +105,7 @@ import { parentsToChildren } from './derivations/parentsToChildren'
|
|||
import { deriveShapeIdsInCurrentPage } from './derivations/shapeIdsInCurrentPage'
|
||||
import { ClickManager } from './managers/ClickManager'
|
||||
import { EnvironmentManager } from './managers/EnvironmentManager'
|
||||
import { CommandHistoryOptions, HistoryManager } from './managers/HistoryManager'
|
||||
import { HistoryManager } from './managers/HistoryManager'
|
||||
import { SideEffectManager } from './managers/SideEffectManager'
|
||||
import { SnapManager } from './managers/SnapManager'
|
||||
import { TextManager } from './managers/TextManager'
|
||||
|
@ -122,6 +122,7 @@ import { SvgExportContext, SvgExportDef } from './types/SvgExportContext'
|
|||
import { TLContent } from './types/clipboard-types'
|
||||
import { TLEventMap } from './types/emit-types'
|
||||
import { TLEventInfo, TLPinchEventInfo, TLPointerEventInfo } from './types/event-types'
|
||||
import { TLCommandHistoryOptions } from './types/history-types'
|
||||
import { OptionalKeys, RequiredKeys } from './types/misc-types'
|
||||
import { TLResizeHandle } from './types/selection-types'
|
||||
|
||||
|
@ -1185,7 +1186,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
*/
|
||||
updateInstanceState(
|
||||
partial: Partial<Omit<TLInstance, 'currentPageId'>>,
|
||||
historyOptions?: CommandHistoryOptions
|
||||
historyOptions?: TLCommandHistoryOptions
|
||||
): this {
|
||||
this._updateInstanceState(partial, { ephemeral: true, squashing: true, ...historyOptions })
|
||||
|
||||
|
@ -1207,7 +1208,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
'updateInstanceState',
|
||||
(
|
||||
partial: Partial<Omit<TLInstance, 'currentPageId'>>,
|
||||
historyOptions?: CommandHistoryOptions
|
||||
historyOptions?: TLCommandHistoryOptions
|
||||
) => {
|
||||
const prev = this.instanceState
|
||||
const next = { ...prev, ...partial }
|
||||
|
@ -1368,7 +1369,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
partial: Partial<
|
||||
Omit<TLInstancePageState, 'selectedShapeIds' | 'editingShapeId' | 'pageId' | 'focusedGroupId'>
|
||||
>,
|
||||
historyOptions?: CommandHistoryOptions
|
||||
historyOptions?: TLCommandHistoryOptions
|
||||
): this {
|
||||
this._setInstancePageState(partial, historyOptions)
|
||||
return this
|
||||
|
@ -1379,7 +1380,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
'setInstancePageState',
|
||||
(
|
||||
partial: Partial<Omit<TLInstancePageState, 'selectedShapeIds'>>,
|
||||
historyOptions?: CommandHistoryOptions
|
||||
historyOptions?: TLCommandHistoryOptions
|
||||
) => {
|
||||
const prev = this.store.get(partial.id ?? this.currentPageState.id)!
|
||||
return { data: { prev, partial }, ...historyOptions }
|
||||
|
@ -1417,7 +1418,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
*
|
||||
* @public
|
||||
*/
|
||||
setSelectedShapeIds(ids: TLShapeId[], historyOptions?: CommandHistoryOptions): this {
|
||||
setSelectedShapeIds(ids: TLShapeId[], historyOptions?: TLCommandHistoryOptions): this {
|
||||
this._setSelectedShapeIds(ids, historyOptions)
|
||||
return this
|
||||
}
|
||||
|
@ -1425,7 +1426,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
/** @internal */
|
||||
private _setSelectedShapeIds = this.history.createCommand(
|
||||
'setSelectedShapeIds',
|
||||
(ids: TLShapeId[], historyOptions?: CommandHistoryOptions) => {
|
||||
(ids: TLShapeId[], historyOptions?: TLCommandHistoryOptions) => {
|
||||
const { selectedShapeIds: prevSelectedShapeIds } = this.currentPageState
|
||||
const prevSet = new Set(prevSelectedShapeIds)
|
||||
|
||||
|
@ -2693,8 +2694,8 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
const { screenBounds } = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!
|
||||
const { x: cx, y: cy, z: cz = 1 } = this.camera
|
||||
return {
|
||||
x: (point.x - screenBounds.x - cx) / cz,
|
||||
y: (point.y - screenBounds.y - cy) / cz,
|
||||
x: (point.x - screenBounds.x) / cz - cx,
|
||||
y: (point.y - screenBounds.y) / cz - cy,
|
||||
z: point.z ?? 0.5,
|
||||
}
|
||||
}
|
||||
|
@ -2716,8 +2717,8 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
const { x: cx, y: cy, z: cz = 1 } = this.camera
|
||||
|
||||
return {
|
||||
x: point.x * cz + cx + screenBounds.x,
|
||||
y: point.y * cz + cy + screenBounds.y,
|
||||
x: (point.x + cx) * cz + screenBounds.x,
|
||||
y: (point.y + cy) * cz + screenBounds.y,
|
||||
z: point.z ?? 0.5,
|
||||
}
|
||||
}
|
||||
|
@ -3218,9 +3219,9 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
*
|
||||
* @public
|
||||
*/
|
||||
setCurrentPage(page: TLPage, historyOptions?: CommandHistoryOptions): this
|
||||
setCurrentPage(pageId: TLPageId, historyOptions?: CommandHistoryOptions): this
|
||||
setCurrentPage(arg: TLPageId | TLPage, historyOptions?: CommandHistoryOptions): this {
|
||||
setCurrentPage(page: TLPage, historyOptions?: TLCommandHistoryOptions): this
|
||||
setCurrentPage(pageId: TLPageId, historyOptions?: TLCommandHistoryOptions): this
|
||||
setCurrentPage(arg: TLPageId | TLPage, historyOptions?: TLCommandHistoryOptions): this {
|
||||
const pageId = typeof arg === 'string' ? arg : arg.id
|
||||
this._setCurrentPageId(pageId, historyOptions)
|
||||
return this
|
||||
|
@ -3228,7 +3229,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
/** @internal */
|
||||
private _setCurrentPageId = this.history.createCommand(
|
||||
'setCurrentPage',
|
||||
(pageId: TLPageId, historyOptions?: CommandHistoryOptions) => {
|
||||
(pageId: TLPageId, historyOptions?: TLCommandHistoryOptions) => {
|
||||
if (!this.store.has(pageId)) {
|
||||
console.error("Tried to set the current page id to a page that doesn't exist.")
|
||||
return
|
||||
|
@ -3295,14 +3296,14 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
*
|
||||
* @public
|
||||
*/
|
||||
updatePage(partial: RequiredKeys<TLPage, 'id'>, historyOptions?: CommandHistoryOptions): this {
|
||||
updatePage(partial: RequiredKeys<TLPage, 'id'>, historyOptions?: TLCommandHistoryOptions): this {
|
||||
this._updatePage(partial, historyOptions)
|
||||
return this
|
||||
}
|
||||
/** @internal */
|
||||
private _updatePage = this.history.createCommand(
|
||||
'updatePage',
|
||||
(partial: RequiredKeys<TLPage, 'id'>, historyOptions?: CommandHistoryOptions) => {
|
||||
(partial: RequiredKeys<TLPage, 'id'>, historyOptions?: TLCommandHistoryOptions) => {
|
||||
if (this.instanceState.isReadonly) return null
|
||||
|
||||
const prev = this.getPage(partial.id)
|
||||
|
@ -3513,9 +3514,9 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
*
|
||||
* @public
|
||||
*/
|
||||
renamePage(page: TLPage, name: string, historyOptions?: CommandHistoryOptions): this
|
||||
renamePage(id: TLPageId, name: string, historyOptions?: CommandHistoryOptions): this
|
||||
renamePage(arg: TLPageId | TLPage, name: string, historyOptions?: CommandHistoryOptions) {
|
||||
renamePage(page: TLPage, name: string, historyOptions?: TLCommandHistoryOptions): this
|
||||
renamePage(id: TLPageId, name: string, historyOptions?: TLCommandHistoryOptions): this
|
||||
renamePage(arg: TLPageId | TLPage, name: string, historyOptions?: TLCommandHistoryOptions) {
|
||||
const id = typeof arg === 'string' ? arg : arg.id
|
||||
if (this.instanceState.isReadonly) return this
|
||||
this.updatePage({ id, name }, historyOptions)
|
||||
|
@ -4966,12 +4967,12 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
* @param direction - The direction in which to move the shapes.
|
||||
* @param historyOptions - (optional) The history options for the change.
|
||||
*/
|
||||
nudgeShapes(shapes: TLShape[], offset: VecLike, historyOptions?: CommandHistoryOptions): this
|
||||
nudgeShapes(ids: TLShapeId[], offset: VecLike, historyOptions?: CommandHistoryOptions): this
|
||||
nudgeShapes(shapes: TLShape[], offset: VecLike, historyOptions?: TLCommandHistoryOptions): this
|
||||
nudgeShapes(ids: TLShapeId[], offset: VecLike, historyOptions?: TLCommandHistoryOptions): this
|
||||
nudgeShapes(
|
||||
arg: TLShapeId[] | TLShape[],
|
||||
offset: VecLike,
|
||||
historyOptions?: CommandHistoryOptions
|
||||
historyOptions?: TLCommandHistoryOptions
|
||||
): this {
|
||||
const ids =
|
||||
typeof arg[0] === 'string' ? (arg as TLShapeId[]) : (arg as TLShape[]).map((s) => s.id)
|
||||
|
@ -6815,7 +6816,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
*/
|
||||
updateShape<T extends TLUnknownShape>(
|
||||
partial: TLShapePartial<T> | null | undefined,
|
||||
historyOptions?: CommandHistoryOptions
|
||||
historyOptions?: TLCommandHistoryOptions
|
||||
) {
|
||||
this.updateShapes([partial], historyOptions)
|
||||
return this
|
||||
|
@ -6836,7 +6837,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
*/
|
||||
updateShapes<T extends TLUnknownShape>(
|
||||
partials: (TLShapePartial<T> | null | undefined)[],
|
||||
historyOptions?: CommandHistoryOptions
|
||||
historyOptions?: TLCommandHistoryOptions
|
||||
) {
|
||||
let compactedPartials = compact(partials)
|
||||
if (this.animatingShapes.size > 0) {
|
||||
|
@ -6859,7 +6860,10 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
/** @internal */
|
||||
private _updateShapes = this.history.createCommand(
|
||||
'updateShapes',
|
||||
(_partials: (TLShapePartial | null | undefined)[], historyOptions?: CommandHistoryOptions) => {
|
||||
(
|
||||
_partials: (TLShapePartial | null | undefined)[],
|
||||
historyOptions?: TLCommandHistoryOptions
|
||||
) => {
|
||||
if (this.instanceState.isReadonly) return null
|
||||
|
||||
const partials = compact(_partials)
|
||||
|
@ -7205,7 +7209,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
* @param opacity - The opacity to set. Must be a number between 0 and 1 inclusive.
|
||||
* @param historyOptions - The history options for the change.
|
||||
*/
|
||||
setOpacity(opacity: number, historyOptions?: CommandHistoryOptions): this {
|
||||
setOpacity(opacity: number, historyOptions?: TLCommandHistoryOptions): this {
|
||||
this.history.batch(() => {
|
||||
if (this.isIn('select')) {
|
||||
const {
|
||||
|
@ -7269,7 +7273,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
*
|
||||
* @public
|
||||
*/
|
||||
setStyle<T>(style: StyleProp<T>, value: T, historyOptions?: CommandHistoryOptions): this {
|
||||
setStyle<T>(style: StyleProp<T>, value: T, historyOptions?: TLCommandHistoryOptions): this {
|
||||
this.history.batch(() => {
|
||||
if (this.isIn('select')) {
|
||||
const {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { CommandHistoryOptions, HistoryManager } from './HistoryManager'
|
||||
import { TLCommandHistoryOptions } from '../types/history-types'
|
||||
import { HistoryManager } from './HistoryManager'
|
||||
import { stack } from './Stack'
|
||||
|
||||
function createCounterHistoryManager() {
|
||||
|
@ -291,8 +292,8 @@ describe('history options', () => {
|
|||
let manager: HistoryManager<any>
|
||||
let state: { a: number; b: number }
|
||||
|
||||
let setA: (n: number, historyOptions?: CommandHistoryOptions) => any
|
||||
let setB: (n: number, historyOptions?: CommandHistoryOptions) => any
|
||||
let setA: (n: number, historyOptions?: TLCommandHistoryOptions) => any
|
||||
let setB: (n: number, historyOptions?: TLCommandHistoryOptions) => any
|
||||
|
||||
beforeEach(() => {
|
||||
manager = new HistoryManager({ emit: () => void null }, () => {
|
||||
|
@ -306,7 +307,7 @@ describe('history options', () => {
|
|||
|
||||
setA = manager.createCommand(
|
||||
'setA',
|
||||
(n: number, historyOptions?: CommandHistoryOptions) => ({
|
||||
(n: number, historyOptions?: TLCommandHistoryOptions) => ({
|
||||
data: { next: n, prev: state.a },
|
||||
...historyOptions,
|
||||
}),
|
||||
|
@ -323,7 +324,7 @@ describe('history options', () => {
|
|||
|
||||
setB = manager.createCommand(
|
||||
'setB',
|
||||
(n: number, historyOptions?: CommandHistoryOptions) => ({
|
||||
(n: number, historyOptions?: TLCommandHistoryOptions) => ({
|
||||
data: { next: n, prev: state.b },
|
||||
...historyOptions,
|
||||
}),
|
||||
|
|
|
@ -1,29 +1,13 @@
|
|||
import { atom, transact } from '@tldraw/state'
|
||||
import { devFreeze } from '@tldraw/store'
|
||||
import { uniqueId } from '../../utils/uniqueId'
|
||||
import { TLCommandHandler, TLHistoryEntry } from '../types/history-types'
|
||||
import { TLCommandHandler, TLCommandHistoryOptions, TLHistoryEntry } from '../types/history-types'
|
||||
import { Stack, stack } from './Stack'
|
||||
|
||||
/** @public */
|
||||
export type CommandHistoryOptions = Partial<{
|
||||
/**
|
||||
* When true, this command will be squashed with the previous command in the undo / redo stack.
|
||||
*/
|
||||
squashing: boolean
|
||||
/**
|
||||
* When true, this command will not add anything to the undo / redo stack. Its change will never be undone or redone.
|
||||
*/
|
||||
ephemeral: boolean
|
||||
/**
|
||||
* When true, adding this this command will not clear out the redo stack.
|
||||
*/
|
||||
preservesRedoStack: boolean
|
||||
}>
|
||||
|
||||
type CommandFn<Data> = (...args: any[]) =>
|
||||
| ({
|
||||
data: Data
|
||||
} & CommandHistoryOptions)
|
||||
} & TLCommandHistoryOptions)
|
||||
| null
|
||||
| undefined
|
||||
| void
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
/** @public */
|
||||
export type TLCommandHistoryOptions = Partial<{
|
||||
/**
|
||||
* When true, this command will be squashed with the previous command in the undo / redo stack.
|
||||
*/
|
||||
squashing: boolean
|
||||
/**
|
||||
* When true, this command will not add anything to the undo / redo stack. Its change will never be undone or redone.
|
||||
*/
|
||||
ephemeral: boolean
|
||||
/**
|
||||
* When true, adding this this command will not clear out the redo stack.
|
||||
*/
|
||||
preservesRedoStack: boolean
|
||||
}>
|
||||
|
||||
/** @public */
|
||||
export type TLHistoryMark = {
|
||||
type: 'STOP'
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { VecLike } from '@tldraw/editor'
|
||||
import { TestEditor } from '../TestEditor'
|
||||
|
||||
let editor: TestEditor
|
||||
|
@ -6,126 +7,70 @@ beforeEach(() => {
|
|||
editor = new TestEditor()
|
||||
})
|
||||
|
||||
function checkScreenPage(screen: VecLike, page: VecLike) {
|
||||
const pageResult = editor.screenToPage(screen)
|
||||
expect(pageResult).toMatchObject(page)
|
||||
const screenResult = editor.pageToScreen(pageResult)
|
||||
expect(screenResult).toMatchObject(screen)
|
||||
}
|
||||
|
||||
describe('viewport.screenToPage', () => {
|
||||
it('converts correctly', () => {
|
||||
expect(editor.screenToPage({ x: 0, y: 0 })).toMatchObject({ x: 0, y: 0 })
|
||||
expect(editor.pageToScreen({ x: 0, y: 0 })).toMatchObject({ x: 0, y: 0 })
|
||||
|
||||
expect(editor.screenToPage({ x: 100, y: 100 })).toMatchObject({ x: 100, y: 100 })
|
||||
expect(editor.pageToScreen({ x: 100, y: 100 })).toMatchObject({ x: 100, y: 100 })
|
||||
|
||||
expect(editor.screenToPage({ x: -100, y: -100 })).toMatchObject({ x: -100, y: -100 })
|
||||
expect(editor.pageToScreen({ x: -100, y: -100 })).toMatchObject({ x: -100, y: -100 })
|
||||
checkScreenPage({ x: 0, y: 0 }, { x: 0, y: 0 })
|
||||
checkScreenPage({ x: 100, y: 100 }, { x: 100, y: 100 })
|
||||
checkScreenPage({ x: -100, y: -100 }, { x: -100, y: -100 })
|
||||
})
|
||||
|
||||
it('converts correctly when zoomed', () => {
|
||||
editor.setCamera({ x: 0, y: 0, z: 0.5 })
|
||||
|
||||
expect(editor.screenToPage({ x: 0, y: 0 })).toMatchObject({ x: 0, y: 0 })
|
||||
expect(editor.pageToScreen({ x: 0, y: 0 })).toMatchObject({ x: 0, y: 0 })
|
||||
|
||||
expect(editor.screenToPage({ x: 100, y: 100 })).toMatchObject({ x: 200, y: 200 })
|
||||
expect(editor.pageToScreen({ x: 200, y: 200 })).toMatchObject({ x: 100, y: 100 })
|
||||
|
||||
expect(editor.screenToPage({ x: -100, y: -100 })).toMatchObject({ x: -200, y: -200 })
|
||||
expect(editor.pageToScreen({ x: -200, y: -200 })).toMatchObject({ x: -100, y: -100 })
|
||||
checkScreenPage({ x: 0, y: 0 }, { x: 0, y: 0 })
|
||||
checkScreenPage({ x: 100, y: 100 }, { x: 200, y: 200 })
|
||||
checkScreenPage({ x: -100, y: -100 }, { x: -200, y: -200 })
|
||||
})
|
||||
|
||||
it('converts correctly when panned', () => {
|
||||
editor.setCamera({ x: 100, y: 100 })
|
||||
|
||||
expect(editor.screenToPage({ x: 0, y: 0 })).toMatchObject({ x: -100, y: -100 })
|
||||
expect(editor.pageToScreen({ x: -100, y: -100 })).toMatchObject({ x: 0, y: 0 })
|
||||
|
||||
expect(editor.screenToPage({ x: 100, y: 100 })).toMatchObject({ x: 0, y: 0 })
|
||||
expect(editor.pageToScreen({ x: 0, y: 0 })).toMatchObject({ x: 100, y: 100 })
|
||||
|
||||
expect(editor.screenToPage({ x: -100, y: -100 })).toMatchObject({ x: -200, y: -200 })
|
||||
expect(editor.pageToScreen({ x: -200, y: -200 })).toMatchObject({ x: -100, y: -100 })
|
||||
checkScreenPage({ x: 0, y: 0 }, { x: -100, y: -100 })
|
||||
checkScreenPage({ x: 100, y: 100 }, { x: 0, y: 0 })
|
||||
checkScreenPage({ x: -100, y: -100 }, { x: -200, y: -200 })
|
||||
})
|
||||
|
||||
it('converts correctly when panned and zoomed', () => {
|
||||
editor.setCamera({ x: 100, y: 100, z: 0.5 })
|
||||
|
||||
expect(editor.screenToPage({ x: 0, y: 0 })).toMatchObject({ x: -200, y: -200 })
|
||||
expect(editor.pageToScreen({ x: -200, y: -200 })).toMatchObject({ x: 0, y: 0 })
|
||||
|
||||
expect(editor.screenToPage({ x: 100, y: 100 })).toMatchObject({ x: 0, y: 0 })
|
||||
expect(editor.pageToScreen({ x: 0, y: 0 })).toMatchObject({ x: 100, y: 100 })
|
||||
|
||||
expect(editor.screenToPage({ x: -100, y: -100 })).toMatchObject({ x: -400, y: -400 })
|
||||
expect(editor.pageToScreen({ x: -400, y: -400 })).toMatchObject({ x: -100, y: -100 })
|
||||
checkScreenPage({ x: 0, y: 0 }, { x: -100, y: -100 })
|
||||
checkScreenPage({ x: 100, y: 100 }, { x: 100, y: 100 })
|
||||
checkScreenPage({ x: -100, y: -100 }, { x: -300, y: -300 })
|
||||
checkScreenPage({ x: -150, y: -150 }, { x: -400, y: -400 })
|
||||
})
|
||||
|
||||
it('converts correctly when offset', () => {
|
||||
// move the editor's page bounds down and to the left by 100, 100
|
||||
// 0,0 s
|
||||
// +------------------------+
|
||||
// | 100,100 s |
|
||||
// | c-----------------+ |
|
||||
// | | 0,0 p | |
|
||||
// | | | |
|
||||
|
||||
editor.updateInstanceState({ screenBounds: { ...editor.viewportScreenBounds, x: 100, y: 100 } })
|
||||
|
||||
expect(editor.screenToPage({ x: 0, y: 0 })).toMatchObject({ x: -100, y: -100 })
|
||||
expect(editor.pageToScreen({ x: -100, y: -100 })).toMatchObject({ x: 0, y: 0 })
|
||||
|
||||
expect(editor.screenToPage({ x: -100, y: -100 })).toMatchObject({ x: -200, y: -200 })
|
||||
expect(editor.pageToScreen({ x: -200, y: -200 })).toMatchObject({ x: -100, y: -100 })
|
||||
|
||||
expect(editor.screenToPage({ x: 100, y: 100 })).toMatchObject({ x: 0, y: 0 })
|
||||
expect(editor.pageToScreen({ x: 0, y: 0 })).toMatchObject({ x: 100, y: 100 })
|
||||
|
||||
// 0,0 s
|
||||
// c------------------------+
|
||||
// | 100,100 s |
|
||||
// | +-----------------+ |
|
||||
// | | 100,100 p | |
|
||||
// | | | |
|
||||
|
||||
editor.setCamera({ x: -100, y: -100 }) // -100, -100
|
||||
expect(editor.screenToPage({ x: -100, y: -100 })).toMatchObject({ x: -100, y: -100 })
|
||||
expect(editor.pageToScreen({ x: -100, y: -100 })).toMatchObject({ x: -100, y: -100 })
|
||||
expect(editor.screenToPage({ x: 0, y: 0 })).toMatchObject({ x: 0, y: 0 })
|
||||
expect(editor.pageToScreen({ x: 0, y: 0 })).toMatchObject({ x: 0, y: 0 })
|
||||
expect(editor.screenToPage({ x: 100, y: 100 })).toMatchObject({ x: 100, y: 100 })
|
||||
expect(editor.pageToScreen({ x: 100, y: 100 })).toMatchObject({ x: 100, y: 100 })
|
||||
|
||||
// 0,0 s no offset, zoom at 50%
|
||||
// c------------------------+
|
||||
// | 0,0 p |
|
||||
// | |
|
||||
// | |
|
||||
// | |
|
||||
editor.setCamera({ x: 0, y: 0, z: 0.5 })
|
||||
editor.updateInstanceState({ screenBounds: { ...editor.viewportScreenBounds, x: 0, y: 0 } })
|
||||
expect(editor.screenToPage({ x: 0, y: 0 })).toMatchObject({ x: 0, y: 0 })
|
||||
expect(editor.pageToScreen({ x: 0, y: 0 })).toMatchObject({ x: 0, y: 0 })
|
||||
expect(editor.screenToPage({ x: -100, y: -100 })).toMatchObject({ x: -200, y: -200 })
|
||||
expect(editor.pageToScreen({ x: -200, y: -200 })).toMatchObject({ x: -100, y: -100 })
|
||||
expect(editor.screenToPage({ x: 100, y: 100 })).toMatchObject({ x: 200, y: 200 })
|
||||
expect(editor.pageToScreen({ x: 200, y: 200 })).toMatchObject({ x: 100, y: 100 })
|
||||
checkScreenPage({ x: 0, y: 0 }, { x: -100, y: -100 })
|
||||
checkScreenPage({ x: -100, y: -100 }, { x: -200, y: -200 })
|
||||
checkScreenPage({ x: 100, y: 100 }, { x: 0, y: 0 })
|
||||
})
|
||||
|
||||
it('converts correctly when zoomed out', () => {
|
||||
// camera at zero, screenbounds at zero, but zoom at .5
|
||||
editor.setCamera({ x: 0, y: 0, z: 0.5 })
|
||||
editor.updateInstanceState({ screenBounds: { ...editor.viewportScreenBounds, x: 0, y: 0 } })
|
||||
expect(editor.screenToPage({ x: 0, y: 0 })).toMatchObject({ x: 0, y: 0 })
|
||||
expect(editor.pageToScreen({ x: 0, y: 0 })).toMatchObject({ x: 0, y: 0 })
|
||||
expect(editor.screenToPage({ x: -100, y: -100 })).toMatchObject({ x: -200, y: -200 })
|
||||
expect(editor.pageToScreen({ x: -200, y: -200 })).toMatchObject({ x: -100, y: -100 })
|
||||
expect(editor.screenToPage({ x: 100, y: 100 })).toMatchObject({ x: 200, y: 200 })
|
||||
expect(editor.pageToScreen({ x: 200, y: 200 })).toMatchObject({ x: 100, y: 100 })
|
||||
|
||||
checkScreenPage({ x: 0, y: 0 }, { x: 0, y: 0 })
|
||||
checkScreenPage({ x: -100, y: -100 }, { x: -200, y: -200 })
|
||||
checkScreenPage({ x: 100, y: 100 }, { x: 200, y: 200 })
|
||||
})
|
||||
|
||||
it('converts correctly when zoomed in', () => {
|
||||
editor.setCamera({ x: 0, y: 0, z: 2 })
|
||||
editor.updateInstanceState({ screenBounds: { ...editor.viewportScreenBounds, x: 0, y: 0 } })
|
||||
expect(editor.screenToPage({ x: 0, y: 0 })).toMatchObject({ x: 0, y: 0 })
|
||||
expect(editor.screenToPage({ x: -100, y: -100 })).toMatchObject({ x: -50, y: -50 })
|
||||
expect(editor.screenToPage({ x: 100, y: 100 })).toMatchObject({ x: 50, y: 50 })
|
||||
|
||||
checkScreenPage({ x: 0, y: 0 }, { x: 0, y: 0 })
|
||||
checkScreenPage({ x: -100, y: -100 }, { x: -50, y: -50 })
|
||||
checkScreenPage({ x: 100, y: 100 }, { x: 50, y: 50 })
|
||||
})
|
||||
|
||||
it('converts correctly when zoomed', () => {
|
||||
|
@ -133,82 +78,63 @@ describe('viewport.screenToPage', () => {
|
|||
editor.updateInstanceState({ screenBounds: { ...editor.viewportScreenBounds, x: 0, y: 0 } })
|
||||
editor.setCamera({ x: 0, y: 0, z: 0.5 })
|
||||
|
||||
// zero point, where page and screen are the same
|
||||
expect(editor.pageToScreen({ x: 0, y: 0 })).toMatchObject({ x: 0, y: 0 })
|
||||
expect(editor.screenToPage({ x: 0, y: 0 })).toMatchObject({ x: 0, y: 0 })
|
||||
checkScreenPage({ x: 0, y: 0 }, { x: 0, y: 0 })
|
||||
checkScreenPage({ x: -100, y: -100 }, { x: -200, y: -200 })
|
||||
checkScreenPage({ x: 100, y: 100 }, { x: 200, y: 200 })
|
||||
})
|
||||
|
||||
expect(editor.pageToScreen({ x: 100, y: 100 })).toMatchObject({ x: 50, y: 50 })
|
||||
expect(editor.screenToPage({ x: 50, y: 50 })).toMatchObject({ x: 100, y: 100 })
|
||||
it('converts correctly when offset and zoomed', () => {
|
||||
editor.setCamera({ x: 0, y: 0, z: 0.5 })
|
||||
editor.updateInstanceState({ screenBounds: { ...editor.viewportScreenBounds, x: 100, y: 100 } })
|
||||
|
||||
expect(editor.pageToScreen({ x: 200, y: 200 })).toMatchObject({ x: 100, y: 100 })
|
||||
expect(editor.screenToPage({ x: 100, y: 100 })).toMatchObject({ x: 200, y: 200 })
|
||||
checkScreenPage({ x: 0, y: 0 }, { x: -200, y: -200 })
|
||||
checkScreenPage({ x: -100, y: -100 }, { x: -400, y: -400 })
|
||||
checkScreenPage({ x: 100, y: 100 }, { x: 0, y: 0 })
|
||||
})
|
||||
|
||||
it('converts correctly when zoomed and panned', () => {
|
||||
editor.updateInstanceState({ screenBounds: { ...editor.viewportScreenBounds, x: 0, y: 0 } })
|
||||
editor.setCamera({ x: 100, y: 100, z: 0.5 })
|
||||
expect(editor.pageToScreen({ x: 0, y: 0 })).toMatchObject({ x: 100, y: 100 })
|
||||
expect(editor.screenToPage({ x: 100, y: 100 })).toMatchObject({ x: 0, y: 0 })
|
||||
|
||||
expect(editor.pageToScreen({ x: 100, y: 100 })).toMatchObject({ x: 150, y: 150 })
|
||||
expect(editor.screenToPage({ x: 150, y: 150 })).toMatchObject({ x: 100, y: 100 })
|
||||
|
||||
// zero point, where page and screen are the same
|
||||
expect(editor.pageToScreen({ x: 200, y: 200 })).toMatchObject({ x: 200, y: 200 })
|
||||
expect(editor.screenToPage({ x: 200, y: 200 })).toMatchObject({ x: 200, y: 200 })
|
||||
checkScreenPage({ x: 0, y: 0 }, { x: -100, y: -100 })
|
||||
checkScreenPage({ x: -100, y: -100 }, { x: -300, y: -300 })
|
||||
checkScreenPage({ x: 100, y: 100 }, { x: 100, y: 100 })
|
||||
})
|
||||
|
||||
it('converts correctly when offset', () => {
|
||||
editor.updateInstanceState({ screenBounds: { ...editor.viewportScreenBounds, x: 100, y: 100 } })
|
||||
editor.setCamera({ x: 0, y: 0, z: 0.5 })
|
||||
|
||||
expect(editor.pageToScreen({ x: 0, y: 0 })).toMatchObject({ x: 100, y: 100 })
|
||||
expect(editor.pageToScreen({ x: 100, y: 100 })).toMatchObject({ x: 150, y: 150 })
|
||||
expect(editor.pageToScreen({ x: 200, y: 200 })).toMatchObject({ x: 200, y: 200 })
|
||||
|
||||
expect(editor.screenToPage({ x: 0, y: 0 })).toMatchObject({ x: -200, y: -200 })
|
||||
expect(editor.screenToPage({ x: 100, y: 100 })).toMatchObject({ x: 0, y: 0 })
|
||||
expect(editor.screenToPage({ x: 200, y: 200 })).toMatchObject({ x: 200, y: 200 })
|
||||
expect(editor.screenToPage({ x: 300, y: 300 })).toMatchObject({ x: 400, y: 400 })
|
||||
checkScreenPage({ x: 0, y: 0 }, { x: -200, y: -200 })
|
||||
checkScreenPage({ x: 100, y: 100 }, { x: 0, y: 0 })
|
||||
checkScreenPage({ x: 200, y: 200 }, { x: 200, y: 200 })
|
||||
})
|
||||
|
||||
it('converts correctly when panned', () => {
|
||||
editor.updateInstanceState({ screenBounds: { ...editor.viewportScreenBounds, x: 0, y: 0 } })
|
||||
editor.setCamera({ x: 100, y: 100, z: 1 })
|
||||
|
||||
expect(editor.pageToScreen({ x: 0, y: 0 })).toMatchObject({ x: 100, y: 100 })
|
||||
expect(editor.pageToScreen({ x: 100, y: 100 })).toMatchObject({ x: 200, y: 200 })
|
||||
expect(editor.pageToScreen({ x: 200, y: 200 })).toMatchObject({ x: 300, y: 300 })
|
||||
|
||||
expect(editor.screenToPage({ x: 100, y: 100 })).toMatchObject({ x: 0, y: 0 })
|
||||
expect(editor.screenToPage({ x: 200, y: 200 })).toMatchObject({ x: 100, y: 100 })
|
||||
expect(editor.screenToPage({ x: 300, y: 300 })).toMatchObject({ x: 200, y: 200 })
|
||||
checkScreenPage({ x: 0, y: 0 }, { x: -100, y: -100 })
|
||||
checkScreenPage({ x: 100, y: 100 }, { x: 0, y: 0 })
|
||||
checkScreenPage({ x: 200, y: 200 }, { x: 100, y: 100 })
|
||||
})
|
||||
|
||||
it('converts correctly when panned and zoomed', () => {
|
||||
editor.updateInstanceState({ screenBounds: { ...editor.viewportScreenBounds, x: 0, y: 0 } })
|
||||
editor.setCamera({ x: 100, y: 100, z: 0.5 })
|
||||
|
||||
expect(editor.pageToScreen({ x: 0, y: 0 })).toMatchObject({ x: 100, y: 100 })
|
||||
expect(editor.pageToScreen({ x: 100, y: 100 })).toMatchObject({ x: 150, y: 150 })
|
||||
expect(editor.pageToScreen({ x: 200, y: 200 })).toMatchObject({ x: 200, y: 200 })
|
||||
|
||||
expect(editor.screenToPage({ x: 100, y: 100 })).toMatchObject({ x: 0, y: 0 })
|
||||
expect(editor.screenToPage({ x: 150, y: 150 })).toMatchObject({ x: 100, y: 100 })
|
||||
expect(editor.screenToPage({ x: 200, y: 200 })).toMatchObject({ x: 200, y: 200 })
|
||||
checkScreenPage({ x: 0, y: 0 }, { x: -100, y: -100 })
|
||||
checkScreenPage({ x: 100, y: 100 }, { x: 100, y: 100 })
|
||||
checkScreenPage({ x: 200, y: 200 }, { x: 300, y: 300 })
|
||||
})
|
||||
|
||||
it('converts correctly when panned and zoomed and offset', () => {
|
||||
editor.updateInstanceState({ screenBounds: { ...editor.viewportScreenBounds, x: 100, y: 100 } })
|
||||
editor.setCamera({ x: 100, y: 100, z: 0.5 })
|
||||
|
||||
expect(editor.pageToScreen({ x: 0, y: 0 })).toMatchObject({ x: 200, y: 200 })
|
||||
expect(editor.pageToScreen({ x: 100, y: 100 })).toMatchObject({ x: 250, y: 250 })
|
||||
expect(editor.pageToScreen({ x: 200, y: 200 })).toMatchObject({ x: 300, y: 300 })
|
||||
|
||||
expect(editor.screenToPage({ x: 200, y: 200 })).toMatchObject({ x: 0, y: 0 })
|
||||
expect(editor.screenToPage({ x: 250, y: 250 })).toMatchObject({ x: 100, y: 100 })
|
||||
expect(editor.screenToPage({ x: 300, y: 300 })).toMatchObject({ x: 200, y: 200 })
|
||||
checkScreenPage({ x: 0, y: 0 }, { x: -300, y: -300 })
|
||||
checkScreenPage({ x: 100, y: 100 }, { x: -100, y: -100 })
|
||||
checkScreenPage({ x: 200, y: 200 }, { x: 100, y: 100 })
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
@ -84,7 +84,7 @@ describe('When center is false', () => {
|
|||
editor.setCamera({ x: -100, y: -100, z: 1 })
|
||||
expect(editor.screenToPage({ x: 0, y: 0 })).toMatchObject({ x: 100, y: 100 })
|
||||
editor.setCamera({ x: -100, y: -100, z: 2 })
|
||||
expect(editor.screenToPage({ x: 0, y: 0 })).toMatchObject({ x: 50, y: 50 })
|
||||
expect(editor.screenToPage({ x: 0, y: 0 })).toMatchObject({ x: 100, y: 100 })
|
||||
|
||||
editor.setScreenBounds({ x: 100, y: 100, w: 500, h: 600 }, false)
|
||||
expect(editor.viewportScreenBounds).toMatchObject({
|
||||
|
@ -93,7 +93,7 @@ describe('When center is false', () => {
|
|||
w: 500,
|
||||
h: 600,
|
||||
})
|
||||
expect(editor.screenToPage({ x: 0, y: 0 })).toMatchObject({ x: 0, y: 0 })
|
||||
expect(editor.screenToPage({ x: 0, y: 0 })).toMatchObject({ x: 50, y: 50 })
|
||||
})
|
||||
})
|
||||
|
||||
|
|
Loading…
Reference in a new issue