mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-22 09:28:11 +08:00
Add a movable canvas with matricies (#175)
* Convert polygon and rectangle tool to kurbo::BezPath * Add glam * Add affine transform to elipse and remove circle * Format * Add svg group and add matrix for group * Convert all operations to use matricies * Work uses same transform as root * Format * Frontend fixed to render changes to working colors when changed from backend (#180) * Backend and Frontend modification to show working color mods * Remove comments & change precedence for tool and doc actions * Add keybind for resetting work colors * Minor Frontend changes * Remove early sample "greet" code * Add a contributing section to the project README * Add moving document around * Add document transform for tools * Update to GraphiteEditor's fork * Use write in foreach for rendering group / folder * Add missing TranslateDown action * Use points for line operation * Format * Add todo to change to shape's aspect ratio * Remove empty if * Initial pass at refactor * Fix polyline test * Use document message to modify document transform * Messages -> Operations * Transform layer * Format * Use DAffine2::IDENTITY * Clean up kurbo generation for line and rect * Use .into for rectangle points * Rename cols to transform * Rename other cols to transform * Add todo for into_iter * Remove unnecessary clone Co-authored-by: akshay1992kalbhor <akshay1992kalbhor@gmail.com> Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
committed by
Keavon Chambers
co-authored by
akshay1992kalbhor
Keavon Chambers
parent
923e63c045
commit
bb3293af43
@@ -1,38 +1,68 @@
|
||||
use crate::shape_points;
|
||||
use kurbo::BezPath;
|
||||
use kurbo::Vec2;
|
||||
|
||||
use super::style;
|
||||
use super::LayerData;
|
||||
|
||||
use std::fmt::Write;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct Shape {
|
||||
bounding_rect: kurbo::Rect,
|
||||
shape: shape_points::ShapePoints,
|
||||
style: style::PathStyle,
|
||||
equal_sides: bool,
|
||||
sides: u8,
|
||||
}
|
||||
|
||||
impl Shape {
|
||||
pub fn new(p0: impl Into<kurbo::Point>, p1: impl Into<kurbo::Point>, sides: u8, style: style::PathStyle) -> Shape {
|
||||
Shape {
|
||||
bounding_rect: kurbo::Rect::from_points(p0, p1),
|
||||
shape: shape_points::ShapePoints::new(kurbo::Point::new(0.5, 0.5), kurbo::Vec2::new(0.5, 0.0), sides),
|
||||
style,
|
||||
}
|
||||
pub fn new(equal_sides: bool, sides: u8) -> Shape {
|
||||
Shape { equal_sides, sides }
|
||||
}
|
||||
}
|
||||
|
||||
impl LayerData for Shape {
|
||||
fn render(&mut self, svg: &mut String) {
|
||||
let _ = write!(
|
||||
svg,
|
||||
r#"<polygon points="{}" transform="translate({} {}) scale({} {})"{} />"#,
|
||||
self.shape,
|
||||
self.bounding_rect.origin().x,
|
||||
self.bounding_rect.origin().y,
|
||||
self.bounding_rect.width(),
|
||||
self.bounding_rect.height(),
|
||||
self.style.render(),
|
||||
);
|
||||
fn to_kurbo_path(&mut self, transform: glam::DAffine2, _style: style::PathStyle) -> BezPath {
|
||||
fn unit_rotation(theta: f64) -> Vec2 {
|
||||
Vec2::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);
|
||||
|
||||
let relative_points = (0..self.sides)
|
||||
.map(|i| apothem_offset_angle * ((i * 2 + ((self.sides + 1) % 2)) as f64))
|
||||
.map(|radians| unit_rotation(radians));
|
||||
|
||||
let (mut min_x, mut min_y, mut max_x, mut max_y) = (f64::MAX, f64::MAX, f64::MIN, f64::MIN);
|
||||
relative_points.clone().for_each(|p| {
|
||||
min_x = min_x.min(p.x);
|
||||
min_y = min_y.min(p.y);
|
||||
max_x = max_x.max(p.x);
|
||||
max_y = max_y.max(p.y);
|
||||
});
|
||||
|
||||
relative_points
|
||||
.map(|p| {
|
||||
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.)
|
||||
}
|
||||
})
|
||||
.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())
|
||||
.enumerate()
|
||||
.for_each(|(i, p)| {
|
||||
if i == 0 {
|
||||
path.move_to(p);
|
||||
} else {
|
||||
path.line_to(p);
|
||||
}
|
||||
});
|
||||
|
||||
path.close_path();
|
||||
path
|
||||
}
|
||||
fn render(&mut self, svg: &mut String, transform: glam::DAffine2, style: style::PathStyle) {
|
||||
let _ = write!(svg, r#"<path d="{}" {} />"#, self.to_kurbo_path(transform, style).to_svg(), style.render());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user