aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2025-08-08 12:54:45 -0400
committerbobzel <zzzman@gmail.com>2025-08-08 12:54:45 -0400
commitb3aa4a5b0bbbb87d041b9515bddedbcbf8ae9fc5 (patch)
tree8622701837c9085d0e7f911e94b745e45b6025db
parent8ec4e4fbd42be8ba6606d78da25c33f69d30ed63 (diff)
fixed sizing of arrows and dashes to relate to stroke width. Made link's use fill to set color and default to backgorundColor
-rw-r--r--src/client/util/InteractionUtils.tsx8
-rw-r--r--src/client/views/PropertiesView.tsx70
-rw-r--r--src/client/views/StyleProvider.tsx17
-rw-r--r--src/client/views/nodes/DocumentView.tsx2
-rw-r--r--src/client/views/nodes/LinkBox.tsx7
5 files changed, 37 insertions, 67 deletions
diff --git a/src/client/util/InteractionUtils.tsx b/src/client/util/InteractionUtils.tsx
index ca1cb8014..f469f2ef8 100644
--- a/src/client/util/InteractionUtils.tsx
+++ b/src/client/util/InteractionUtils.tsx
@@ -132,9 +132,9 @@ export namespace InteractionUtils {
const Tag = (bezier ? 'path' : 'polyline') as keyof JSX.IntrinsicElements;
const markerStrokeWidth = strokeWidth / 2;
- const arrowWidthFactor = 3 * (markerScale || 0.5); // used to be 1.5
- const arrowLengthFactor = 5 * (markerScale || 0.5);
- const arrowNotchFactor = 2 * (markerScale || 0.5);
+ const arrowWidthFactor = markerScale || 0.5; // used to be 1.5
+ const arrowLengthFactor = (5 / 3) * (markerScale || 0.5);
+ const arrowNotchFactor = (2 / 3) * (markerScale || 0.5);
return (
<svg fill={color || 'transparent'} style={{ transition: 'inherit' }} onPointerDown={downHdlr}>
{' '}
@@ -148,7 +148,7 @@ export namespace InteractionUtils {
)}
{arrowStart !== 'dot' && arrowEnd !== 'dot' ? null : (
<marker id={`dot${defGuid}`} orient="auto" markerUnits="userSpaceOnUse" refX={0} refY="0" overflow="visible">
- <circle r={strokeWidth * arrowWidthFactor} fill="context-stroke" />
+ <circle r={(strokeWidth * arrowWidthFactor) / 2} fill="context-stroke" />
</marker>
)}
{arrowStart !== 'arrow' ? null : (
diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx
index f7c4b464c..b4ea1f07b 100644
--- a/src/client/views/PropertiesView.tsx
+++ b/src/client/views/PropertiesView.tsx
@@ -880,18 +880,14 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
set colorFil(value) {
this.selectedStrokes.forEach(doc => {
const inkStroke = DocumentView.getDocumentView(doc)?.ComponentView as InkingStroke;
- const { inkData } = inkStroke.inkScaledData();
- if (InkingStroke.IsClosed(inkData)) {
+ const inkData = inkStroke?.inkScaledData?.().inkData;
+ if (!inkData || InkingStroke.IsClosed(inkData)) {
doc.$fillColor = value || undefined;
}
});
}
@computed get colorStk() { return StrCast(this.selectedStrokes.lastElement()?.$color); } // prettier-ignore
- set colorStk(value) {
- this.selectedStrokes.forEach(doc => {
- doc.$color = value || undefined;
- });
- }
+ set colorStk(value) { this.selectedStrokes.forEach(doc => (doc.$color = value || undefined)); } // prettier-ignore
@computed get borderColor() {
return StrCast(this.selectedDoc._color);
}
@@ -1023,47 +1019,21 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
);
}
- @computed get dashdStk() { return this.selectedStrokes[0]?.stroke_dash || ''; } // prettier-ignore
- set dashdStk(value) {
- value && (this._lastDash = value as string);
- this.selectedStrokes.forEach(doc => {
- doc.$stroke_dash = value ? this._lastDash : undefined;
- });
- }
- @computed get widthStk() { return this.getField('stroke_width') || '1'; } // prettier-ignore
- set widthStk(value) {
- this.selectedStrokes.forEach(doc => {
- doc.$stroke_width = Number(value);
- });
- }
- @computed get markScal() { return Number(this.getField('stroke_markerScale') || '1'); } // prettier-ignore
- set markScal(value) {
- this.selectedStrokes.forEach(doc => {
- doc.$stroke_markerScale = Number(value);
- });
- }
+ @computed get dashdStk() { return this.selectedStrokes[0]?.stroke_dash || ''; } // prettier-ignore
+ set dashdStk(value) { value && (this._lastDash = value as string);
+ this.selectedStrokes.forEach(doc => (doc.$stroke_dash = value ? this._lastDash : undefined)); } // prettier-ignore
+ @computed get widthStk() { return this.getField('stroke_width') || '1'; } // prettier-ignore
+ set widthStk(value) { this.selectedStrokes.forEach(doc => (doc.$stroke_width = Number(value))); } // prettier-ignore
+ @computed get markScal() { return Number(this.getField('stroke_markerScale') || '1'); } // prettier-ignore
+ set markScal(value) { this.selectedStrokes.forEach(doc => (doc.$stroke_markerScale = Number(value))); } // prettier-ignore
@computed get refStrength() { return Number(this.getField('drawing_refStrength') || '50'); } // prettier-ignore
- set refStrength(value) {
- this.selectedDoc.$drawing_refStrength = Number(value);
- }
- @computed get smoothAmt() { return Number(this.getField('stroke_smoothAmount') || '5'); } // prettier-ignore
- set smoothAmt(value) {
- this.selectedStrokes.forEach(doc => {
- doc.$stroke_smoothAmount = Number(value);
- });
- }
- @computed get markHead() { return this.getField('stroke_startMarker') || ''; } // prettier-ignore
- set markHead(value) {
- this.selectedStrokes.forEach(doc => {
- doc.$stroke_startMarker = value;
- });
- }
- @computed get markTail() { return this.getField('stroke_endMarker') || ''; } // prettier-ignore
- set markTail(value) {
- this.selectedStrokes.forEach(doc => {
- doc.$stroke_endMarker = value;
- });
- }
+ set refStrength(value) { this.selectedDoc.$drawing_refStrength = Number(value); } // prettier-ignore
+ @computed get smoothAmt() { return Number(this.getField('stroke_smoothAmount') || '5'); } // prettier-ignore
+ set smoothAmt(value) { this.selectedStrokes.forEach(doc => (doc.$stroke_smoothAmount = Number(value))) } // prettier-ignore
+ @computed get markHead() { return this.getField('stroke_startMarker') || ''; } // prettier-ignore
+ set markHead(value) { this.selectedStrokes.forEach(doc => (doc.$stroke_startMarker = value)); } // prettier-ignore
+ @computed get markTail() { return this.getField('stroke_endMarker') || ''; } // prettier-ignore
+ set markTail(value) { this.selectedStrokes.forEach(doc => (doc.$stroke_endMarker = value)); } // prettier-ignore
regInput = (key: string, value: string | number | undefined, setter: (val: string) => void) => (
<div className="inputBox">
@@ -1160,16 +1130,14 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
</div>
<div className="dashed">
<div className="dashed-title">Dashed Line:</div>
- <input key="markHead" className="dashed-input" type="checkbox" checked={this.dashdStk === '2'} onChange={this.changeDash} />
+ <input key="markHead" className="dashed-input" type="checkbox" checked={!!this.dashdStk} onChange={this.changeDash} />
</div>
</div>
);
}
@undoBatch
- changeDash = () => {
- this.dashdStk = this.dashdStk === '2' ? '0' : '2';
- };
+ changeDash = () => (this.dashdStk = this.dashdStk ? '' : '2');
@computed get inkEditor() {
return (
diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx
index b52f17102..ca089a2fc 100644
--- a/src/client/views/StyleProvider.tsx
+++ b/src/client/views/StyleProvider.tsx
@@ -83,7 +83,6 @@ export function SetFilterOpener(func: () => void) {
export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps & DocumentViewProps>, property: string) {
const remoteDocHeader = 'author;author_date;noMargin';
const isCaption = property.includes(':caption');
- const isAnchor = property.includes(':anchor');
const isNonTransparent = property.includes(':nonTransparent');
const isNonTransparentLevel = isNonTransparent ? Number(property.replace(/.*:nonTransparent([0-9]+).*/, '$1')) : 0; // property.includes(':nonTransparent');
const isAnnotated = property.includes(':annotated');
@@ -251,14 +250,16 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps &
const dataKey = doc ? Doc.LayoutDataKey(doc) : '';
const usePath = StrCast(doc?.[dataKey + '_usePath']);
const alternate = usePath.includes(':hover') ? ( isHovering?.() ? '_' + usePath.replace(':hover','') : '') : usePath ? "_" +usePath:usePath;
- let docColor:Opt<string> = layoutDoc &&
- StrCast(alternate ? layoutDoc['backgroundColor' + alternate]:undefined,
+ const colorKey = doc?.layout_isSvg ? "fillColor" : "backgroundColor";
+ const docColorFn = (key: string) => layoutDoc &&
+ StrCast(alternate ? layoutDoc[key + alternate]:undefined,
DocCast(doc.rootDocument)
- ? StrCast(layoutDoc.backgroundColor, StrCast(DocCast(doc.rootDocument)!.backgroundColor)) // for nested templates: use template's color, then root doc's color
+ ? StrCast(layoutDoc[key], StrCast(DocCast(doc.rootDocument)![key])) // for nested templates: use template's color, then root doc's color
: layoutDoc === doc
- ? StrCast(doc.backgroundColor)
- : StrCast(StrCast(Doc.GetT(layoutDoc, 'backgroundColor', 'string', true), StrCast(doc.backgroundColor, StrCast(layoutDoc.backgroundColor)) // otherwise, use expanded template coloor, then root doc's color, then template's inherited color
- )));
+ ? StrCast(doc[key])
+ : StrCast(StrCast(Doc.GetT(layoutDoc, key, 'string', true), StrCast(doc[key], StrCast(layoutDoc[key])) // otherwise, use expanded template coloor, then root doc's color, then template's inherited color
+ )))
+ let docColor = docColorFn(colorKey);
// prettier-ignore
switch (layoutDoc?.type) {
@@ -266,11 +267,11 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps &
case DocumentType.PRES: docColor = docColor || 'transparent'; break;
case DocumentType.FONTICON: docColor = boxBackground ? undefined : docColor || SnappingManager.userBackgroundColor; break;
case DocumentType.RTF: docColor = docColor || StrCast(Doc.UserDoc().textBackgroundColor, Colors.LIGHT_GRAY); break;
- case DocumentType.LINK: docColor = (isAnchor ? docColor : undefined); break;
case DocumentType.INK: docColor = doc?.stroke_isInkMask ? 'rgba(0,0,0,0.7)' : undefined; break;
case DocumentType.EQUATION: docColor = docColor || StrCast(Doc.UserDoc().textBackgroundColor, 'transparent'); break;
case DocumentType.LABEL: docColor = docColor || Colors.LIGHT_GRAY; break;
case DocumentType.BUTTON: docColor = docColor || Colors.LIGHT_GRAY; break;
+ case DocumentType.LINK: docColor = docColor || docColorFn('backgroundColor'); break;
case DocumentType.IMG:
case DocumentType.WEB:
case DocumentType.PDF:
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 90edab3a7..d32f55e64 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -1651,7 +1651,7 @@ export function ActiveInkColor(): string { return StrCast(Doc.UserDoc()?.[`activ
export function ActiveInkArrowStart(): string { return StrCast(Doc.UserDoc()?.[`active${Doc.ActiveInk}ArrowStart`], ''); } // prettier-ignore
export function ActiveInkArrowEnd(): string { return StrCast(Doc.UserDoc()?.[`active${Doc.ActiveInk}ArrowEnd`], ''); } // prettier-ignore
export function ActiveInkArrowScale(): number { return NumCast(Doc.UserDoc()?.[`active${Doc.ActiveInk}ArrowScale`], 1); } // prettier-ignore
-export function ActiveInkDash(): string { return StrCast(Doc.UserDoc()?.[`active${Doc.ActiveInk}Dash`], '0'); } // prettier-ignore
+export function ActiveInkDash(): string { return StrCast(Doc.UserDoc()?.[`active${Doc.ActiveInk}Dash`], ''); } // prettier-ignore
export function ActiveInkWidth(): number { return Number(Doc.UserDoc()?.[`active${Doc.ActiveInk}Width`]); } // prettier-ignore
export function ActiveInkBezierApprox(): string { return StrCast(Doc.UserDoc()[`active${Doc.ActiveInk}Bezier`]); } // prettier-ignore
diff --git a/src/client/views/nodes/LinkBox.tsx b/src/client/views/nodes/LinkBox.tsx
index d31fadf77..88e327a09 100644
--- a/src/client/views/nodes/LinkBox.tsx
+++ b/src/client/views/nodes/LinkBox.tsx
@@ -164,13 +164,14 @@ export class LinkBox extends ViewBoxBaseComponent<FieldViewProps>() {
}
const highlight = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Highlighting) as { highlightStyle: string; highlightColor: string; highlightIndex: number; highlightStroke: boolean };
const highlightColor = highlight?.highlightIndex ? highlight?.highlightColor : undefined;
- const color = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color) as string;
+ const color = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor) as string;
const fontFamily = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.FontFamily) as string;
const fontSize = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.FontSize) as number;
const fontColor = (c => (c !== 'transparent' ? c : undefined))(StrCast(this.layoutDoc.link_fontColor));
const { stroke_markerScale: strokeMarkerScale, stroke_width: strokeRawWidth, stroke_startMarker: strokeStartMarker, stroke_endMarker: strokeEndMarker, stroke_dash: strokeDash } = this.Document;
const strokeWidth = NumCast(strokeRawWidth, 1);
+ const strokeDashLen = strokeDash ? Number(strokeDash) * strokeWidth : undefined;
const linkDesc = StrCast(this.dataDoc.link_description) || ' ';
const labelText = linkDesc.substring(0, 50) + (linkDesc.length > 50 ? '...' : '');
return (
@@ -195,7 +196,7 @@ export class LinkBox extends ViewBoxBaseComponent<FieldViewProps>() {
start={aid}
end={bid} //
strokeWidth={strokeWidth}
- dashness={!!Number(strokeDash)}
+ dashness={!strokeDashLen ? undefined : { strokeLen: strokeDashLen, nonStrokeLen: strokeDashLen }}
showHead={!!strokeStartMarker}
showTail={!!strokeEndMarker}
headSize={NumCast(strokeMarkerScale, 3)}
@@ -299,7 +300,7 @@ Docs.Prototypes.TemplateMap.set(DocumentType.LINK, {
_width: 1,
link: '',
link_description: '',
- color: 'lightBlue', // lightblue is default color for linking dot and link documents text comment area
+ backgroundColor: 'lightBlue', // lightblue is default color for linking dot and link documents text comment area
_dropPropertiesToRemove: new List(['onClick']),
},
});