Viewport canvas navigation with modifier keys and zoom widget (#229)

* Add rotation around the center

* Document transform centred

* Fix drawing hexagon on rotated document

* Format

* Fix translation on rotated document

* Remove logging

* Rotate around centre of viewport

* Rotate with shift + MMB drag

* Zoom with +/- keys

* Rotation input field

* Implement frontend zoom buttons

* Zoom with ctrl + MMB

* Format

* Update number inputs

* Require Ctrl + Plus / Minus key

* Ctrl scroll

* Update zoom -> Multiply Zoom

* Fix typo

* More fixing typo

* Remove :v-on

* Add mouse scroll X

* Scrolling on document

* Refactor

* Format

* Fix ctrl + plus/minus to zoom

* Reduce zoom sensitivity

* Ctrl + shift + mmb drag = snap rotate

* Further reduce zoom speed

* Add ctrl + number key to change zoom

* Switch Ctrl and Shift for zoom and rotate

* Fix compile errors

* Format JS

* Add increment to snap angle

* Edit getting layerdata functions

* Pass viewport size directily into create_document_transform_from_layerdata

* Add to_dvec2()

* Refactor get_transform

* Get -> Calculate

* Add consts

* Use to_radians

* Remove get from function names

* Use .entry when getting layerdata that does not exist

* Fix distance scroll calculations

* Fix zooming.

* Remove 'Violation' in chrome

* Fix compile errors
This commit is contained in:
0HyperCube
2021-07-13 07:50:10 +01:00
committed by GitHub
parent 8ff545f01c
commit 39e6893630
22 changed files with 442 additions and 73 deletions

View File

@@ -316,6 +316,13 @@ impl Document {
self.root.cache_dirty = true;
Some(vec![DocumentResponse::DocumentChanged])
}
Operation::SetLayerTransform { path, transform } => {
let transform = DAffine2::from_cols_array(&transform);
let layer = self.document_layer_mut(path).unwrap();
layer.transform = transform;
layer.cache_dirty = true;
Some(vec![DocumentResponse::DocumentChanged])
}
Operation::DiscardWorkingFolder => {
self.work_operations.clear();
self.work_mount_path = vec![];

View File

@@ -4,7 +4,6 @@ use glam::DVec2;
use crate::intersection::intersect_quad_bez_path;
use crate::LayerId;
use kurbo::BezPath;
use kurbo::Vec2;
use super::style;
use super::LayerData;
@@ -26,11 +25,9 @@ impl Shape {
impl LayerData for Shape {
fn to_kurbo_path(&self, transform: glam::DAffine2, _style: style::PathStyle) -> BezPath {
fn unit_rotation(theta: f64) -> Vec2 {
Vec2::new(-theta.sin(), theta.cos())
fn unit_rotation(theta: f64) -> DVec2 {
DVec2::new(-theta.sin(), theta.cos())
}
let extent = Vec2::new((transform.x_axis.x + transform.x_axis.y) / 2., (transform.y_axis.x + transform.y_axis.y) / 2.);
let translation = transform.translation;
let mut path = kurbo::BezPath::new();
let apothem_offset_angle = std::f64::consts::PI / (self.sides as f64);
@@ -51,11 +48,12 @@ impl LayerData for Shape {
if self.equal_sides {
p
} else {
Vec2::new((p.x - min_x) / (max_x - min_x) * 2. - 1., (p.y - min_y) / (max_y - min_y) * 2. - 1.)
DVec2::new((p.x - min_x) / (max_x - min_x) * 2. - 1., (p.y - min_y) / (max_y - min_y) * 2. - 1.)
}
})
.map(|unit| Vec2::new(-unit.x * extent.x + translation.x + extent.x, -unit.y * extent.y + translation.y + extent.y))
.map(|pos| (pos).to_point())
.map(|p| DVec2::new(p.x / 2. + 0.5, p.y / 2. + 0.5))
.map(|unit| transform.transform_point2(unit.into()))
.map(|pos| kurbo::Point::new(pos.x, pos.y))
.enumerate()
.for_each(|(i, p)| {
if i == 0 {

View File

@@ -61,6 +61,10 @@ pub enum Operation {
path: Vec<LayerId>,
transform: [f64; 6],
},
SetLayerTransform {
path: Vec<LayerId>,
transform: [f64; 6],
},
DiscardWorkingFolder,
ClearWorkingFolder,
CommitTransaction,