Improve document zooming to work based on nice steps (#336)
* Improve document zooming to work based on nice steps * Code review improvements
This commit is contained in:
parent
74d0e6dbc0
commit
22947933b0
|
|
@ -1,16 +1,20 @@
|
||||||
pub const PLUS_KEY_ZOOM_RATE: f64 = 1.25;
|
// VIEWPORT
|
||||||
pub const MINUS_KEY_ZOOM_RATE: f64 = 0.8;
|
pub const VIEWPORT_ZOOM_WHEEL_RATE: f64 = 1. / 600.;
|
||||||
|
pub const VIEWPORT_ZOOM_MOUSE_RATE: f64 = 1. / 400.;
|
||||||
pub const VIEWPORT_ZOOM_SCALE_MIN: f64 = 0.000_001;
|
pub const VIEWPORT_ZOOM_SCALE_MIN: f64 = 0.000_000_1;
|
||||||
pub const VIEWPORT_ZOOM_SCALE_MAX: f64 = 1_000_000.;
|
pub const VIEWPORT_ZOOM_SCALE_MAX: f64 = 10_000.;
|
||||||
|
pub const VIEWPORT_ZOOM_LEVELS: [f64; 74] = [
|
||||||
|
0.0001, 0.000125, 0.00016, 0.0002, 0.00025, 0.00032, 0.0004, 0.0005, 0.00064, 0.0008, 0.001, 0.0016, 0.002, 0.0025, 0.0032, 0.004, 0.005, 0.0064, 0.008, 0.01, 0.01125, 0.015, 0.02, 0.025, 0.03,
|
||||||
|
0.04, 0.05, 0.06, 0.08, 0.1, 0.125, 0.15, 0.2, 0.25, 0.33333333, 0.4, 0.5, 0.66666666, 0.8, 1., 1.25, 1.6, 2., 2.5, 3.2, 4., 5., 6.4, 8., 10., 12.5, 16., 20., 25., 32., 40., 50., 64., 80., 100.,
|
||||||
|
128., 160., 200., 256., 320., 400., 512., 640., 800., 1024., 1280., 1600., 2048., 2560.,
|
||||||
|
];
|
||||||
|
|
||||||
pub const VIEWPORT_SCROLL_RATE: f64 = 0.6;
|
pub const VIEWPORT_SCROLL_RATE: f64 = 0.6;
|
||||||
|
|
||||||
pub const WHEEL_ZOOM_RATE: f64 = 1. / 600.;
|
pub const VIEWPORT_ROTATE_SNAP_INTERVAL: f64 = 15.;
|
||||||
pub const MOUSE_ZOOM_RATE: f64 = 1. / 400.;
|
|
||||||
|
|
||||||
pub const ROTATE_SNAP_INTERVAL: f64 = 15.;
|
|
||||||
|
|
||||||
|
// LINE TOOL
|
||||||
pub const LINE_ROTATE_SNAP_ANGLE: f64 = 15.;
|
pub const LINE_ROTATE_SNAP_ANGLE: f64 = 15.;
|
||||||
|
|
||||||
|
// SELECT TOOL
|
||||||
pub const SELECTION_TOLERANCE: f64 = 1.0;
|
pub const SELECTION_TOLERANCE: f64 = 1.0;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::{consts::ROTATE_SNAP_INTERVAL, frontend::layer_panel::*};
|
use crate::{consts::VIEWPORT_ROTATE_SNAP_INTERVAL, frontend::layer_panel::*};
|
||||||
use glam::{DAffine2, DVec2};
|
use glam::{DAffine2, DVec2};
|
||||||
use graphene::{
|
use graphene::{
|
||||||
layers::{Layer, LayerData as DocumentLayerData},
|
layers::{Layer, LayerData as DocumentLayerData},
|
||||||
|
|
@ -30,7 +30,7 @@ impl LayerData {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn snapped_angle(&self) -> f64 {
|
pub fn snapped_angle(&self) -> f64 {
|
||||||
let increment_radians: f64 = ROTATE_SNAP_INTERVAL.to_radians();
|
let increment_radians: f64 = VIEWPORT_ROTATE_SNAP_INTERVAL.to_radians();
|
||||||
if self.snap_rotate {
|
if self.snap_rotate {
|
||||||
(self.rotation / increment_radians).round() * increment_radians
|
(self.rotation / increment_radians).round() * increment_radians
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ use super::LayerData;
|
||||||
|
|
||||||
use crate::message_prelude::*;
|
use crate::message_prelude::*;
|
||||||
use crate::{
|
use crate::{
|
||||||
consts::{MOUSE_ZOOM_RATE, VIEWPORT_SCROLL_RATE, VIEWPORT_ZOOM_SCALE_MAX, VIEWPORT_ZOOM_SCALE_MIN, WHEEL_ZOOM_RATE},
|
consts::{VIEWPORT_SCROLL_RATE, VIEWPORT_ZOOM_LEVELS, VIEWPORT_ZOOM_MOUSE_RATE, VIEWPORT_ZOOM_SCALE_MAX, VIEWPORT_ZOOM_SCALE_MIN, VIEWPORT_ZOOM_WHEEL_RATE},
|
||||||
input::{mouse::ViewportPosition, InputPreprocessor},
|
input::{mouse::ViewportPosition, InputPreprocessor},
|
||||||
};
|
};
|
||||||
use glam::DVec2;
|
use glam::DVec2;
|
||||||
|
|
@ -24,10 +24,11 @@ pub enum MovementMessage {
|
||||||
DisableSnapping,
|
DisableSnapping,
|
||||||
ZoomCanvasBegin,
|
ZoomCanvasBegin,
|
||||||
TranslateCanvasEnd,
|
TranslateCanvasEnd,
|
||||||
SetCanvasZoom(f64),
|
|
||||||
MultiplyCanvasZoom(f64),
|
|
||||||
WheelCanvasZoom,
|
|
||||||
SetCanvasRotation(f64),
|
SetCanvasRotation(f64),
|
||||||
|
SetCanvasZoom(f64),
|
||||||
|
IncreaseCanvasZoom,
|
||||||
|
DecreaseCanvasZoom,
|
||||||
|
WheelCanvasZoom,
|
||||||
ZoomCanvasToFitAll,
|
ZoomCanvasToFitAll,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -113,7 +114,7 @@ impl MessageHandler<MovementMessage, (&mut LayerData, &Document, &InputPreproces
|
||||||
}
|
}
|
||||||
if self.zooming {
|
if self.zooming {
|
||||||
let difference = self.mouse_pos.y as f64 - ipp.mouse.position.y as f64;
|
let difference = self.mouse_pos.y as f64 - ipp.mouse.position.y as f64;
|
||||||
let amount = 1. + difference * MOUSE_ZOOM_RATE;
|
let amount = 1. + difference * VIEWPORT_ZOOM_MOUSE_RATE;
|
||||||
|
|
||||||
let new = (layerdata.scale * amount).clamp(VIEWPORT_ZOOM_SCALE_MIN, VIEWPORT_ZOOM_SCALE_MAX);
|
let new = (layerdata.scale * amount).clamp(VIEWPORT_ZOOM_SCALE_MIN, VIEWPORT_ZOOM_SCALE_MAX);
|
||||||
layerdata.scale = new;
|
layerdata.scale = new;
|
||||||
|
|
@ -127,9 +128,13 @@ impl MessageHandler<MovementMessage, (&mut LayerData, &Document, &InputPreproces
|
||||||
responses.push_back(FrontendMessage::SetCanvasZoom { new_zoom: layerdata.scale }.into());
|
responses.push_back(FrontendMessage::SetCanvasZoom { new_zoom: layerdata.scale }.into());
|
||||||
self.create_document_transform_from_layerdata(layerdata, &ipp.viewport_size, responses);
|
self.create_document_transform_from_layerdata(layerdata, &ipp.viewport_size, responses);
|
||||||
}
|
}
|
||||||
MultiplyCanvasZoom(multiplier) => {
|
IncreaseCanvasZoom => {
|
||||||
let new = (layerdata.scale * multiplier).clamp(VIEWPORT_ZOOM_SCALE_MIN, VIEWPORT_ZOOM_SCALE_MAX);
|
layerdata.scale = *VIEWPORT_ZOOM_LEVELS.iter().find(|scale| **scale > layerdata.scale).unwrap_or(&layerdata.scale);
|
||||||
layerdata.scale = new;
|
responses.push_back(FrontendMessage::SetCanvasZoom { new_zoom: layerdata.scale }.into());
|
||||||
|
self.create_document_transform_from_layerdata(layerdata, &ipp.viewport_size, responses);
|
||||||
|
}
|
||||||
|
DecreaseCanvasZoom => {
|
||||||
|
layerdata.scale = *VIEWPORT_ZOOM_LEVELS.iter().rev().find(|scale| **scale < layerdata.scale).unwrap_or(&layerdata.scale);
|
||||||
responses.push_back(FrontendMessage::SetCanvasZoom { new_zoom: layerdata.scale }.into());
|
responses.push_back(FrontendMessage::SetCanvasZoom { new_zoom: layerdata.scale }.into());
|
||||||
self.create_document_transform_from_layerdata(layerdata, &ipp.viewport_size, responses);
|
self.create_document_transform_from_layerdata(layerdata, &ipp.viewport_size, responses);
|
||||||
}
|
}
|
||||||
|
|
@ -137,7 +142,7 @@ impl MessageHandler<MovementMessage, (&mut LayerData, &Document, &InputPreproces
|
||||||
let scroll = ipp.mouse.scroll_delta.scroll_delta();
|
let scroll = ipp.mouse.scroll_delta.scroll_delta();
|
||||||
let mouse = ipp.mouse.position.as_f64();
|
let mouse = ipp.mouse.position.as_f64();
|
||||||
let viewport_size = ipp.viewport_size.as_f64();
|
let viewport_size = ipp.viewport_size.as_f64();
|
||||||
let mut zoom_factor = 1. + scroll.abs() * WHEEL_ZOOM_RATE;
|
let mut zoom_factor = 1. + scroll.abs() * VIEWPORT_ZOOM_WHEEL_RATE;
|
||||||
if ipp.mouse.scroll_delta.y > 0 {
|
if ipp.mouse.scroll_delta.y > 0 {
|
||||||
zoom_factor = 1. / zoom_factor
|
zoom_factor = 1. / zoom_factor
|
||||||
};
|
};
|
||||||
|
|
@ -195,9 +200,10 @@ impl MessageHandler<MovementMessage, (&mut LayerData, &Document, &InputPreproces
|
||||||
RotateCanvasBegin,
|
RotateCanvasBegin,
|
||||||
ZoomCanvasBegin,
|
ZoomCanvasBegin,
|
||||||
SetCanvasZoom,
|
SetCanvasZoom,
|
||||||
MultiplyCanvasZoom,
|
|
||||||
SetCanvasRotation,
|
SetCanvasRotation,
|
||||||
WheelCanvasZoom,
|
WheelCanvasZoom,
|
||||||
|
IncreaseCanvasZoom,
|
||||||
|
DecreaseCanvasZoom,
|
||||||
WheelCanvasTranslate,
|
WheelCanvasTranslate,
|
||||||
ZoomCanvasToFitAll,
|
ZoomCanvasToFitAll,
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ use super::{
|
||||||
keyboard::{Key, KeyStates, NUMBER_OF_KEYS},
|
keyboard::{Key, KeyStates, NUMBER_OF_KEYS},
|
||||||
InputPreprocessor,
|
InputPreprocessor,
|
||||||
};
|
};
|
||||||
use crate::consts::{MINUS_KEY_ZOOM_RATE, PLUS_KEY_ZOOM_RATE};
|
|
||||||
use crate::message_prelude::*;
|
use crate::message_prelude::*;
|
||||||
use crate::tool::ToolType;
|
use crate::tool::ToolType;
|
||||||
|
|
||||||
|
|
@ -196,9 +195,9 @@ impl Default for Mapping {
|
||||||
entry! {action=MovementMessage::ZoomCanvasToFitAll, key_down=Key0, modifiers=[KeyControl]},
|
entry! {action=MovementMessage::ZoomCanvasToFitAll, key_down=Key0, modifiers=[KeyControl]},
|
||||||
entry! {action=MovementMessage::TranslateCanvasBegin, key_down=Mmb},
|
entry! {action=MovementMessage::TranslateCanvasBegin, key_down=Mmb},
|
||||||
entry! {action=MovementMessage::TranslateCanvasEnd, key_up=Mmb},
|
entry! {action=MovementMessage::TranslateCanvasEnd, key_up=Mmb},
|
||||||
entry! {action=MovementMessage::MultiplyCanvasZoom(PLUS_KEY_ZOOM_RATE), key_down=KeyPlus, modifiers=[KeyControl]},
|
entry! {action=MovementMessage::IncreaseCanvasZoom, key_down=KeyPlus, modifiers=[KeyControl]},
|
||||||
entry! {action=MovementMessage::MultiplyCanvasZoom(PLUS_KEY_ZOOM_RATE), key_down=KeyEquals, modifiers=[KeyControl]},
|
entry! {action=MovementMessage::IncreaseCanvasZoom, key_down=KeyEquals, modifiers=[KeyControl]},
|
||||||
entry! {action=MovementMessage::MultiplyCanvasZoom(MINUS_KEY_ZOOM_RATE), key_down=KeyMinus, modifiers=[KeyControl]},
|
entry! {action=MovementMessage::DecreaseCanvasZoom, key_down=KeyMinus, modifiers=[KeyControl]},
|
||||||
entry! {action=MovementMessage::SetCanvasZoom(1.), key_down=Key1, modifiers=[KeyControl]},
|
entry! {action=MovementMessage::SetCanvasZoom(1.), key_down=Key1, modifiers=[KeyControl]},
|
||||||
entry! {action=MovementMessage::SetCanvasZoom(2.), key_down=Key2, modifiers=[KeyControl]},
|
entry! {action=MovementMessage::SetCanvasZoom(2.), key_down=Key2, modifiers=[KeyControl]},
|
||||||
entry! {action=MovementMessage::WheelCanvasZoom, message=InputMapperMessage::MouseScroll, modifiers=[KeyControl]},
|
entry! {action=MovementMessage::WheelCanvasZoom, message=InputMapperMessage::MouseScroll, modifiers=[KeyControl]},
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@
|
||||||
|
|
||||||
<Separator :type="SeparatorType.Section" />
|
<Separator :type="SeparatorType.Section" />
|
||||||
|
|
||||||
<NumberInput @update:value="setRotation" v-model:value="documentRotation" :step="15" :unit="`°`" ref="rotation" />
|
<NumberInput @update:value="setRotation" v-model:value="documentRotation" :incrementFactor="15" :unit="`°`" ref="rotation" />
|
||||||
|
|
||||||
<Separator :type="SeparatorType.Section" />
|
<Separator :type="SeparatorType.Section" />
|
||||||
|
|
||||||
|
|
@ -54,11 +54,12 @@
|
||||||
|
|
||||||
<NumberInput
|
<NumberInput
|
||||||
v-model:value="documentZoom"
|
v-model:value="documentZoom"
|
||||||
@update:value="setZoom"
|
@update:value="setCanvasZoom"
|
||||||
:min="0.000001"
|
:min="0.000001"
|
||||||
:max="1000000"
|
:max="1000000"
|
||||||
:step="1.25"
|
:incrementBehavior="IncrementBehavior.Callback"
|
||||||
:stepIsMultiplier="true"
|
:incrementCallbackIncrease="increaseCanvasZoom"
|
||||||
|
:incrementCallbackDecrease="decreaseCanvasZoom"
|
||||||
:unit="`%`"
|
:unit="`%`"
|
||||||
:displayDecimalPlaces="4"
|
:displayDecimalPlaces="4"
|
||||||
ref="zoom"
|
ref="zoom"
|
||||||
|
|
@ -225,7 +226,7 @@ import CanvasRuler, { RulerDirection } from "@/components/widgets/rulers/CanvasR
|
||||||
import IconButton from "@/components/widgets/buttons/IconButton.vue";
|
import IconButton from "@/components/widgets/buttons/IconButton.vue";
|
||||||
import PopoverButton from "@/components/widgets/buttons/PopoverButton.vue";
|
import PopoverButton from "@/components/widgets/buttons/PopoverButton.vue";
|
||||||
import RadioInput, { RadioEntries } from "@/components/widgets/inputs/RadioInput.vue";
|
import RadioInput, { RadioEntries } from "@/components/widgets/inputs/RadioInput.vue";
|
||||||
import NumberInput, { IncrementDirection } from "@/components/widgets/inputs/NumberInput.vue";
|
import NumberInput, { IncrementDirection, IncrementBehavior } from "@/components/widgets/inputs/NumberInput.vue";
|
||||||
import DropdownInput from "@/components/widgets/inputs/DropdownInput.vue";
|
import DropdownInput from "@/components/widgets/inputs/DropdownInput.vue";
|
||||||
import OptionalInput from "@/components/widgets/inputs/OptionalInput.vue";
|
import OptionalInput from "@/components/widgets/inputs/OptionalInput.vue";
|
||||||
import ToolOptions from "@/components/widgets/options/ToolOptions.vue";
|
import ToolOptions from "@/components/widgets/options/ToolOptions.vue";
|
||||||
|
|
@ -283,9 +284,14 @@ export default defineComponent({
|
||||||
const modifiers = makeModifiersBitfield(e.ctrlKey, e.shiftKey, e.altKey);
|
const modifiers = makeModifiersBitfield(e.ctrlKey, e.shiftKey, e.altKey);
|
||||||
on_mouse_scroll(e.deltaX, e.deltaY, e.deltaZ, modifiers);
|
on_mouse_scroll(e.deltaX, e.deltaY, e.deltaZ, modifiers);
|
||||||
},
|
},
|
||||||
async setZoom(newZoom: number) {
|
async setCanvasZoom(newZoom: number) {
|
||||||
const { set_zoom } = await wasm;
|
(await wasm).set_canvas_zoom(newZoom / 100);
|
||||||
set_zoom(newZoom / 100);
|
},
|
||||||
|
async increaseCanvasZoom() {
|
||||||
|
(await wasm).increase_canvas_zoom();
|
||||||
|
},
|
||||||
|
async decreaseCanvasZoom() {
|
||||||
|
(await wasm).decrease_canvas_zoom();
|
||||||
},
|
},
|
||||||
async setRotation(newRotation: number) {
|
async setRotation(newRotation: number) {
|
||||||
const { set_rotation } = await wasm;
|
const { set_rotation } = await wasm;
|
||||||
|
|
@ -364,6 +370,7 @@ export default defineComponent({
|
||||||
overlaysEnabled: true,
|
overlaysEnabled: true,
|
||||||
documentRotation: 0,
|
documentRotation: 0,
|
||||||
documentZoom: 100,
|
documentZoom: 100,
|
||||||
|
IncrementBehavior,
|
||||||
IncrementDirection,
|
IncrementDirection,
|
||||||
MenuDirection,
|
MenuDirection,
|
||||||
SeparatorDirection,
|
SeparatorDirection,
|
||||||
|
|
|
||||||
|
|
@ -145,7 +145,14 @@
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from "vue";
|
import { defineComponent, PropType } from "vue";
|
||||||
|
|
||||||
|
export enum IncrementBehavior {
|
||||||
|
Add = "Add",
|
||||||
|
Multiply = "Multiply",
|
||||||
|
Callback = "Callback",
|
||||||
|
None = "None",
|
||||||
|
}
|
||||||
|
|
||||||
export enum IncrementDirection {
|
export enum IncrementDirection {
|
||||||
Decrease = "Decrease",
|
Decrease = "Decrease",
|
||||||
|
|
@ -158,8 +165,10 @@ export default defineComponent({
|
||||||
value: { type: Number, required: true },
|
value: { type: Number, required: true },
|
||||||
min: { type: Number, required: false },
|
min: { type: Number, required: false },
|
||||||
max: { type: Number, required: false },
|
max: { type: Number, required: false },
|
||||||
step: { type: Number, default: 1 },
|
incrementBehavior: { type: String as PropType<IncrementBehavior>, default: IncrementBehavior.Add },
|
||||||
stepIsMultiplier: { type: Boolean, default: false },
|
incrementFactor: { type: Number, default: 1 },
|
||||||
|
incrementCallbackIncrease: { type: Function, required: false },
|
||||||
|
incrementCallbackDecrease: { type: Function, required: false },
|
||||||
isInteger: { type: Boolean, default: false },
|
isInteger: { type: Boolean, default: false },
|
||||||
unit: { type: String, default: "" },
|
unit: { type: String, default: "" },
|
||||||
unitIsHiddenWhenEditing: { type: Boolean, default: true },
|
unitIsHiddenWhenEditing: { type: Boolean, default: true },
|
||||||
|
|
@ -210,12 +219,24 @@ export default defineComponent({
|
||||||
onIncrement(direction: IncrementDirection) {
|
onIncrement(direction: IncrementDirection) {
|
||||||
if (Number.isNaN(this.value)) return;
|
if (Number.isNaN(this.value)) return;
|
||||||
|
|
||||||
if (this.stepIsMultiplier) {
|
switch (this.incrementBehavior) {
|
||||||
const directionMultiplier = direction === IncrementDirection.Increase ? this.step : 1 / this.step;
|
case IncrementBehavior.Add: {
|
||||||
this.updateValue(this.value * directionMultiplier);
|
const directionAddend = direction === IncrementDirection.Increase ? this.incrementFactor : -this.incrementFactor;
|
||||||
} else {
|
this.updateValue(this.value + directionAddend);
|
||||||
const directionAddend = direction === IncrementDirection.Increase ? this.step : -this.step;
|
break;
|
||||||
this.updateValue(this.value + directionAddend);
|
}
|
||||||
|
case IncrementBehavior.Multiply: {
|
||||||
|
const directionMultiplier = direction === IncrementDirection.Increase ? this.incrementFactor : 1 / this.incrementFactor;
|
||||||
|
this.updateValue(this.value * directionMultiplier);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case IncrementBehavior.Callback: {
|
||||||
|
if (direction === IncrementDirection.Increase && this.incrementCallbackIncrease) this.incrementCallbackIncrease();
|
||||||
|
if (direction === IncrementDirection.Decrease && this.incrementCallbackDecrease) this.incrementCallbackDecrease();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
updateValue(newValue: number) {
|
updateValue(newValue: number) {
|
||||||
|
|
|
||||||
|
|
@ -63,8 +63,8 @@ export interface NumberInputProps {
|
||||||
value: number;
|
value: number;
|
||||||
min?: number;
|
min?: number;
|
||||||
max?: number;
|
max?: number;
|
||||||
step?: number;
|
incrementBehavior?: boolean;
|
||||||
stepIsMultiplier?: boolean;
|
incrementFactor?: number;
|
||||||
isInteger?: boolean;
|
isInteger?: boolean;
|
||||||
unit?: string;
|
unit?: string;
|
||||||
unitIsHiddenWhenEditing?: boolean;
|
unitIsHiddenWhenEditing?: boolean;
|
||||||
|
|
|
||||||
|
|
@ -253,11 +253,25 @@ pub fn export_document() -> Result<(), JsValue> {
|
||||||
|
|
||||||
/// Sets the zoom to the value
|
/// Sets the zoom to the value
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub fn set_zoom(new_zoom: f64) -> Result<(), JsValue> {
|
pub fn set_canvas_zoom(new_zoom: f64) -> Result<(), JsValue> {
|
||||||
let ev = MovementMessage::SetCanvasZoom(new_zoom);
|
let ev = MovementMessage::SetCanvasZoom(new_zoom);
|
||||||
EDITOR_STATE.with(|editor| editor.borrow_mut().handle_message(ev)).map_err(convert_error)
|
EDITOR_STATE.with(|editor| editor.borrow_mut().handle_message(ev)).map_err(convert_error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Zoom in to the next step
|
||||||
|
#[wasm_bindgen]
|
||||||
|
pub fn increase_canvas_zoom() -> Result<(), JsValue> {
|
||||||
|
let ev = MovementMessage::IncreaseCanvasZoom;
|
||||||
|
EDITOR_STATE.with(|editor| editor.borrow_mut().handle_message(ev)).map_err(convert_error)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Zoom out to the next step
|
||||||
|
#[wasm_bindgen]
|
||||||
|
pub fn decrease_canvas_zoom() -> Result<(), JsValue> {
|
||||||
|
let ev = MovementMessage::DecreaseCanvasZoom;
|
||||||
|
EDITOR_STATE.with(|editor| editor.borrow_mut().handle_message(ev)).map_err(convert_error)
|
||||||
|
}
|
||||||
|
|
||||||
/// Sets the rotation to the new value (in radians)
|
/// Sets the rotation to the new value (in radians)
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub fn set_rotation(new_radians: f64) -> Result<(), JsValue> {
|
pub fn set_rotation(new_radians: f64) -> Result<(), JsValue> {
|
||||||
|
|
|
||||||
|
|
@ -11,3 +11,4 @@ use_try_shorthand = true
|
||||||
# where_single_line = true
|
# where_single_line = true
|
||||||
# match_block_trailing_comma = true # https://github.com/rust-lang/rustfmt/issues/3380
|
# match_block_trailing_comma = true # https://github.com/rust-lang/rustfmt/issues/3380
|
||||||
# control_brace_style = "ClosingNextLine" # https://github.com/rust-lang/rustfmt/issues/3377
|
# control_brace_style = "ClosingNextLine" # https://github.com/rust-lang/rustfmt/issues/3377
|
||||||
|
# blank_lines_lower_bound = 1 # https://github.com/rust-lang/rustfmt/issues/3382
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue