This guide demonstrates changing which part of an image is visible in an Editor.
Related APIs:
Command that moves/zooms/rotates the canvas.Command.Viewport.transformBy how to move/scale/rotate.
Mat33.scaling2D(2) zooms in by a factor of 2.For example, to zoom out by a factor of 4,
import { Editor, Viewport, Mat33 } from 'js-draw';
const editor = new Editor(document.body); // 1
editor.addToolbar();
const command = Viewport.transformBy(Mat33.scaling2D(1/4)); // 2
editor.dispatch(command); // 3
Above:
document.body.transformBy command is created. In this case, the command scales the viewport by a factor of 4.
1/4 with 1/2. This should zoom out by a factor of 2.1/4 with 4. This should zoom in by a factor of 4.command to the editor.
transformBy command is unapplied.In the example above, pressing "undo" unapplies the zoom command. There are at least two ways to prevent this:
editor.dispatch(command) with command.apply(editor).
command was done for accessibility tools.editor.dispatch(command) with editor.dispatch(command, false).
import { Editor, Viewport, Mat33 } from 'js-draw';
const editor = new Editor(document.body); // 1
editor.addToolbar();
---visible---
const command = Viewport.transformBy(Mat33.scaling2D(1/4)); // 2
editor.dispatch(command, false); // false: Don't add to history
// Alternatively,
// command.apply(editor);
See also Editor.dispatchNoAnnounce.
Let's start by creating an editor and adding it to the document:
import { Editor } from 'js-draw';
// Create an editor with a toolbar:
const editor = new Editor(document.body);
editor.addToolbar();
Next, to make it clear that the editor is moving, let's give the editor a repeating background:
---use-previous---
---visible---
import { Color4, BackgroundComponentBackgroundType } from 'js-draw';
editor.dispatch(
editor.setBackgroundStyle({
color: Color4.orange,
type: BackgroundComponentBackgroundType.Grid,
// Make the background autoresize so that it's always
// visible:
autoresize: true,
}),
);
Next, let's change the position of the canvas in a loop:
---use-previous---
---visible---
import { Viewport } from 'js-draw';
import { Mat33, Vec2 } from '@js-draw/math';
// When moveLeftUpdate is applied to the viewport, it moves the
// canvas to the left by 1 unit. This is the same as moving the viewport
// to the right by one unit.
const moveLeftUpdate = Mat33.translation(Vec2.of(-1, 0));
function update() {
const moveLeftCommand = Viewport.transformBy(moveLeftUpdate);
moveLeftCommand.apply(editor);
requestAnimationFrame(update);
}
update();
Above, the Vec2.of(-1, 0) gives the direction to move the canvas.
Things to try:
Vec2.of(-1, 0) with Vec2.of(0, 1). How is the viewport updated?.apply twice or use Mat33.rightMul to combine the two transformations.The above update loop has a problem — on some devices, the viewport moves faster than on others.
To fix this, we determine the time elapsed between each animation frame and use this to scale the position change:
import { Editor } from 'js-draw';
import { Color4, BackgroundComponentBackgroundType } from 'js-draw';
const editor = new Editor(document.body);
editor.addToolbar();
editor.dispatch(
editor.setBackgroundStyle({
color: Color4.orange,
type: BackgroundComponentBackgroundType.Grid,
autoresize: true,
}),
);
---visible---
import { Viewport } from 'js-draw';
import { Mat33, Vec2 } from '@js-draw/math';
let lastTime = performance.now();
function update() {
// Get how long many milliseconds have elapsed since the last update.
const nowTime = performance.now();
const millisecondsElapsed = nowTime - lastTime;
const seconds = millisecondsElapsed / 1000;
lastTime = nowTime;
const moveLeftRate = -10; // units/second
const moveLeftAmount = Vec2.of(moveLeftRate * seconds, 0);
const moveLeftUpdate = Mat33.translation(moveLeftAmount);
const moveLeftCommand = Viewport.transformBy(
moveLeftUpdate
);
moveLeftCommand.apply(editor);
requestAnimationFrame(update);
}
update();