mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-10-02 02:58:13 +08:00
Set integer ruler intervals when zoomed in (#1966)
* modify interval calculation * modify progression and add powers of 10 * Some small tweaks * Prevent the graph view from subdividing below 1 --------- Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
co-authored by
Keavon Chambers
parent
a93dcb2776
commit
f17f8ddf61
@@ -796,7 +796,22 @@ impl MessageHandler<DocumentMessage, DocumentMessageData<'_>> for DocumentMessag
|
|||||||
|
|
||||||
let ruler_origin = document_to_viewport.transform_point2(DVec2::ZERO);
|
let ruler_origin = document_to_viewport.transform_point2(DVec2::ZERO);
|
||||||
let log = ruler_scale.log2();
|
let log = ruler_scale.log2();
|
||||||
let ruler_interval: f64 = if log < 0. { 100. * 2_f64.powf(-log.ceil()) } else { 100. / 2_f64.powf(log.ceil()) };
|
let mut ruler_interval: f64 = if log < 0. { 100. * 2_f64.powf(-log.ceil()) } else { 100. / 2_f64.powf(log.ceil()) };
|
||||||
|
|
||||||
|
// When the interval becomes too small, force it to be a whole number, then to powers of 10.
|
||||||
|
// The progression of intervals is:
|
||||||
|
// ..., 100, 50, 25, 12.5, 6 (6.25), 4 (3.125), 2 (1.5625), 1, 0.1, 0.01, ...
|
||||||
|
if ruler_interval < 1. {
|
||||||
|
ruler_interval = 10_f64.powf(ruler_interval.log10().ceil());
|
||||||
|
} else if ruler_interval < 12.5 {
|
||||||
|
// Round to nearest even number
|
||||||
|
ruler_interval = 2. * (ruler_interval / 2.).round();
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.graph_view_overlay_open {
|
||||||
|
ruler_interval = ruler_interval.max(1.);
|
||||||
|
}
|
||||||
|
|
||||||
let ruler_spacing = ruler_interval * ruler_scale;
|
let ruler_spacing = ruler_interval * ruler_scale;
|
||||||
|
|
||||||
responses.add(FrontendMessage::UpdateDocumentRulers {
|
responses.add(FrontendMessage::UpdateDocumentRulers {
|
||||||
|
|||||||
@@ -7,40 +7,40 @@
|
|||||||
|
|
||||||
const RULER_THICKNESS = 16;
|
const RULER_THICKNESS = 16;
|
||||||
const MAJOR_MARK_THICKNESS = 16;
|
const MAJOR_MARK_THICKNESS = 16;
|
||||||
const MEDIUM_MARK_THICKNESS = 6;
|
const MINOR_MARK_THICKNESS = 6;
|
||||||
const MINOR_MARK_THICKNESS = 3;
|
const MICRO_MARK_THICKNESS = 3;
|
||||||
|
|
||||||
export let direction: RulerDirection = "Vertical";
|
export let direction: RulerDirection = "Vertical";
|
||||||
export let origin: number;
|
export let origin: number;
|
||||||
export let numberInterval: number;
|
export let numberInterval: number;
|
||||||
export let majorMarkSpacing: number;
|
export let majorMarkSpacing: number;
|
||||||
export let mediumDivisions = 5;
|
export let minorDivisions = 5;
|
||||||
export let minorDivisions = 2;
|
export let microDivisions = 2;
|
||||||
|
|
||||||
let rulerInput: HTMLDivElement | undefined;
|
let rulerInput: HTMLDivElement | undefined;
|
||||||
let rulerLength = 0;
|
let rulerLength = 0;
|
||||||
let svgBounds = { width: "0px", height: "0px" };
|
let svgBounds = { width: "0px", height: "0px" };
|
||||||
|
|
||||||
$: svgPath = computeSvgPath(direction, origin, majorMarkSpacing, mediumDivisions, minorDivisions, rulerLength);
|
$: svgPath = computeSvgPath(direction, origin, majorMarkSpacing, minorDivisions, microDivisions, rulerLength);
|
||||||
$: svgTexts = computeSvgTexts(direction, origin, majorMarkSpacing, numberInterval, rulerLength);
|
$: svgTexts = computeSvgTexts(direction, origin, majorMarkSpacing, numberInterval, rulerLength);
|
||||||
|
|
||||||
function computeSvgPath(direction: RulerDirection, origin: number, majorMarkSpacing: number, mediumDivisions: number, minorDivisions: number, rulerLength: number): string {
|
function computeSvgPath(direction: RulerDirection, origin: number, majorMarkSpacing: number, minorDivisions: number, microDivisions: number, rulerLength: number): string {
|
||||||
const isVertical = direction === "Vertical";
|
const isVertical = direction === "Vertical";
|
||||||
const lineDirection = isVertical ? "H" : "V";
|
const lineDirection = isVertical ? "H" : "V";
|
||||||
|
|
||||||
const offsetStart = mod(origin, majorMarkSpacing);
|
const offsetStart = mod(origin, majorMarkSpacing);
|
||||||
const shiftedOffsetStart = offsetStart - majorMarkSpacing;
|
const shiftedOffsetStart = offsetStart - majorMarkSpacing;
|
||||||
|
|
||||||
const divisions = majorMarkSpacing / mediumDivisions / minorDivisions;
|
const divisions = majorMarkSpacing / minorDivisions / microDivisions;
|
||||||
const majorMarksFrequency = mediumDivisions * minorDivisions;
|
const majorMarksFrequency = minorDivisions * microDivisions;
|
||||||
|
|
||||||
let dPathAttribute = "";
|
let dPathAttribute = "";
|
||||||
let i = 0;
|
let i = 0;
|
||||||
for (let location = shiftedOffsetStart; location < rulerLength; location += divisions) {
|
for (let location = shiftedOffsetStart; location < rulerLength; location += divisions) {
|
||||||
let length;
|
let length;
|
||||||
if (i % majorMarksFrequency === 0) length = MAJOR_MARK_THICKNESS;
|
if (i % majorMarksFrequency === 0) length = MAJOR_MARK_THICKNESS;
|
||||||
else if (i % minorDivisions === 0) length = MEDIUM_MARK_THICKNESS;
|
else if (i % microDivisions === 0) length = MINOR_MARK_THICKNESS;
|
||||||
else length = MINOR_MARK_THICKNESS;
|
else length = MICRO_MARK_THICKNESS;
|
||||||
i += 1;
|
i += 1;
|
||||||
|
|
||||||
const destination = Math.round(location) + 0.5;
|
const destination = Math.round(location) + 0.5;
|
||||||
@@ -51,7 +51,7 @@
|
|||||||
return dPathAttribute;
|
return dPathAttribute;
|
||||||
}
|
}
|
||||||
|
|
||||||
function computeSvgTexts(direction: RulerDirection, origin: number, majorMarkSpacing: number, numberInterval: number, rulerLength: number): { transform: string; text: number }[] {
|
function computeSvgTexts(direction: RulerDirection, origin: number, majorMarkSpacing: number, numberInterval: number, rulerLength: number): { transform: string; text: string }[] {
|
||||||
const isVertical = direction === "Vertical";
|
const isVertical = direction === "Vertical";
|
||||||
|
|
||||||
const offsetStart = mod(origin, majorMarkSpacing);
|
const offsetStart = mod(origin, majorMarkSpacing);
|
||||||
@@ -59,7 +59,7 @@
|
|||||||
|
|
||||||
const svgTextCoordinates = [];
|
const svgTextCoordinates = [];
|
||||||
|
|
||||||
let text = (Math.ceil(-origin / majorMarkSpacing) - 1) * numberInterval;
|
let labelNumber = (Math.ceil(-origin / majorMarkSpacing) - 1) * numberInterval;
|
||||||
|
|
||||||
for (let location = shiftedOffsetStart; location < rulerLength; location += majorMarkSpacing) {
|
for (let location = shiftedOffsetStart; location < rulerLength; location += majorMarkSpacing) {
|
||||||
const destination = Math.round(location);
|
const destination = Math.round(location);
|
||||||
@@ -69,9 +69,11 @@
|
|||||||
let transform = `translate(${x} ${y})`;
|
let transform = `translate(${x} ${y})`;
|
||||||
if (isVertical) transform += " rotate(270)";
|
if (isVertical) transform += " rotate(270)";
|
||||||
|
|
||||||
|
const text = numberInterval >= 1 ? `${labelNumber}` : labelNumber.toFixed(Math.abs(Math.log10(numberInterval))).replace(/\.0+$/, "");
|
||||||
|
|
||||||
svgTextCoordinates.push({ transform, text });
|
svgTextCoordinates.push({ transform, text });
|
||||||
|
|
||||||
text += numberInterval;
|
labelNumber += numberInterval;
|
||||||
}
|
}
|
||||||
|
|
||||||
return svgTextCoordinates;
|
return svgTextCoordinates;
|
||||||
|
|||||||
Reference in New Issue
Block a user