aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/nodes/CollectionFreeFormDocumentView.tsx')
-rw-r--r--src/client/views/nodes/CollectionFreeFormDocumentView.tsx62
1 files changed, 18 insertions, 44 deletions
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 1b47f4551..727b25d1b 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -1,22 +1,22 @@
import { action, computed, observable } from "mobx";
import { observer } from "mobx-react";
-import { Doc, HeightSym, Opt, WidthSym } from "../../../fields/Doc";
+import { Doc, Opt } from "../../../fields/Doc";
import { Document } from "../../../fields/documentSchemas";
import { List } from "../../../fields/List";
import { listSpec } from "../../../fields/Schema";
import { ComputedField } from "../../../fields/ScriptField";
import { Cast, NumCast, StrCast } from "../../../fields/Types";
import { TraceMobx } from "../../../fields/util";
-import { numberRange, returnVal } from "../../../Utils";
-import { DocumentType } from "../../documents/DocumentTypes";
+import { numberRange, returnOne } from "../../../Utils";
import { Transform } from "../../util/Transform";
import { DocComponent } from "../DocComponent";
import { InkingStroke } from "../InkingStroke";
+import { StyleProp } from "../StyleProvider";
import "./CollectionFreeFormDocumentView.scss";
-import { ContentFittingDocumentView } from "./ContentFittingDocumentView";
import { DocumentView, DocumentViewProps } from "./DocumentView";
+import { FieldViewProps } from "./FieldView";
import React = require("react");
-import { StyleProp } from "../StyleProvider";
+import { CollectionFreeFormView } from "../collections/collectionFreeForm/CollectionFreeFormView";
export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps {
dataProvider?: (doc: Doc, replica: string) => { x: number, y: number, zIndex?: number, opacity?: number, highlight?: boolean, z: number, transition?: string } | undefined;
@@ -26,14 +26,15 @@ export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps {
highlight?: boolean;
jitterRotation: number;
dataTransition?: string;
- fitToBox?: boolean;
replica: string;
+ CollectionFreeFormView: CollectionFreeFormView;
}
@observer
export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeFormDocumentViewProps, Document>(Document) {
+ static animFields = ["_height", "_width", "x", "y", "_scrollTop", "opacity"]; // fields that are configured to be animatable using animation frames
@observable _animPos: number[] | undefined = undefined;
- @observable _contentView: ContentFittingDocumentView | undefined | null;
+ @observable _contentView: DocumentView | undefined | null;
random(min: number, max: number) { // min should not be equal to max
const mseed = Math.abs(this.X * this.Y);
const seed = (mseed * 9301 + 49297) % 233280;
@@ -42,29 +43,20 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
}
get displayName() { return "CollectionFreeFormDocumentView(" + this.rootDoc.title + ")"; } // this makes mobx trace() statements more descriptive
get maskCentering() { return this.props.Document.isInkMask ? InkingStroke.MaskDim / 2 : 0; }
- get transform() { return `scale(${this.props.ContentScaling()}) translate(${this.X - this.maskCentering}px, ${this.Y - this.maskCentering}px) rotate(${this.random(-1, 1) * this.props.jitterRotation}deg)`; }
+ get transform() { return `translate(${this.X - this.maskCentering}px, ${this.Y - this.maskCentering}px) rotate(${this.random(-1, 1) * this.props.jitterRotation}deg)`; }
get X() { return this.dataProvider ? this.dataProvider.x : (this.Document.x || 0); }
get Y() { return this.dataProvider ? this.dataProvider.y : (this.Document.y || 0); }
get ZInd() { return this.dataProvider ? this.dataProvider.zIndex : (this.Document.zIndex || 0); }
get Opacity() { return this.dataProvider ? this.dataProvider.opacity : undefined; }
get Highlight() { return this.dataProvider?.highlight; }
- get width() { return this.props.sizeProvider && this.sizeProvider ? this.sizeProvider.width : this.layoutDoc[WidthSym](); }
- get height() {
- const hgt = this.props.sizeProvider && this.sizeProvider ? this.sizeProvider.height : this.layoutDoc[HeightSym]();
- return (hgt === undefined && this.nativeWidth && this.nativeHeight) ? this.width * this.nativeHeight / this.nativeWidth : hgt;
- }
- @computed get freezeDimensions() { return this.props.freezeDimensions; }
@computed get dataProvider() { return this.props.dataProvider?.(this.props.Document, this.props.replica); }
@computed get sizeProvider() { return this.props.sizeProvider?.(this.props.Document, this.props.replica); }
- @computed get nativeWidth() { return returnVal(this.props.NativeWidth?.(), Doc.NativeWidth(this.layoutDoc, undefined, this.freezeDimensions)); }
- @computed get nativeHeight() { return returnVal(this.props.NativeHeight?.(), Doc.NativeHeight(this.layoutDoc, undefined, this.freezeDimensions)); }
- styleProvider = (doc: Doc | undefined, props: Opt<DocumentViewProps>, property: string) => {
+ styleProvider = (doc: Doc | undefined, props: Opt<DocumentViewProps | FieldViewProps>, property: string) => {
if (property === StyleProp.Opacity && doc === this.layoutDoc) return this.Opacity; // only change the opacity for this specific document, not its children
return this.props.styleProvider?.(doc, props, property);
}
- static animFields = ["_height", "_width", "x", "y", "_scrollTop", "opacity"];
public static getValues(doc: Doc, time: number) {
return CollectionFreeFormDocumentView.animFields.reduce((p, val) => {
p[val] = Cast(`${val}-indexed`, listSpec("number"), [NumCast(doc[val])]).reduce((p, v, i) => (i <= Math.round(time) && v !== undefined) || p === undefined ? v : p, undefined as any as number);
@@ -138,60 +130,42 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
this.props.Document.x = NumCast(this.props.Document.x) + x;
this.props.Document.y = NumCast(this.props.Document.y) + y;
}
- contentScaling = () => this.nativeWidth > 0 && !this.props.fitToBox && !this.freezeDimensions ? this.width / this.nativeWidth : 1;
panelWidth = () => (this.sizeProvider?.width || this.props.PanelWidth?.());
panelHeight = () => (this.sizeProvider?.height || this.props.PanelHeight?.());
- getTransform = (): Transform => this.props.ScreenToLocalTransform().translate(-this.X, -this.Y).scale(1 / this.contentScaling());
+ screenToLocalTransform = (): Transform => this.props.ScreenToLocalTransform().translate(-this.X, -this.Y);
focusDoc = (doc: Doc) => this.props.focus(doc, false);
- NativeWidth = () => this.nativeWidth;
- NativeHeight = () => this.nativeHeight;
returnThis = () => this;
- @computed get pointerEvents() {
- if (this.props.pointerEvents === "none") return "none";
- return this.props.styleProvider?.(this.Document, this.props, StyleProp.PointerEvents + (!this._contentView?.docView?.isSelected() ? ":selected" : ""));
- }
render() {
TraceMobx();
- const backgroundColor = this.props.styleProvider?.(this.Document, this.props, StyleProp.BackgroundColor);
- const borderRadius = this.props.styleProvider?.(this.Document, this.props, StyleProp.BorderRounding);
- const boxShadow = this.props.styleProvider?.(this.Document, this.props, StyleProp.BoxShadow);
+ const backgroundColor = () => this.props.styleProvider?.(this.Document, this.props, StyleProp.BackgroundColor);
const divProps: DocumentViewProps = {
...this.props,
CollectionFreeFormDocumentView: this.returnThis,
- dragDivName: "collectionFreeFormDocumentView-container",
styleProvider: this.styleProvider,
- ScreenToLocalTransform: this.getTransform,
- NativeHeight: this.NativeHeight,
- NativeWidth: this.NativeWidth,
+ ScreenToLocalTransform: this.screenToLocalTransform,
PanelWidth: this.panelWidth,
- PanelHeight: this.panelHeight
+ PanelHeight: this.panelHeight,
};
- return <div className="collectionFreeFormDocumentView-container"
+ return <div className={"collectionFreeFormDocumentView-container"}
style={{
- boxShadow,
- borderRadius,
outline: this.Highlight ? "orange solid 2px" : "",
transform: this.transform,
transition: this.props.dataTransition ? this.props.dataTransition : this.dataProvider ? this.dataProvider.transition : StrCast(this.layoutDoc.dataTransition),
- width: this.props.Document.isInkMask ? InkingStroke.MaskDim : this.width,
- height: this.props.Document.isInkMask ? InkingStroke.MaskDim : this.height,
zIndex: this.ZInd,
mixBlendMode: StrCast(this.layoutDoc.mixBlendMode) as any,
display: this.ZInd === -99 ? "none" : undefined,
- pointerEvents: this.pointerEvents
+ pointerEvents: "none"
}} >
{Doc.UserDoc().renderStyle !== "comic" ? (null) :
<div style={{ width: "100%", height: "100%", position: "absolute" }}>
<svg style={{ transform: `scale(1,${this.props.PanelHeight() / this.props.PanelWidth()})`, transformOrigin: "top left", overflow: "visible" }} viewBox="0 0 12 14">
<path d="M 7 0 C 9 -1 13 1 12 4 C 11 10 13 12 10 12 C 6 12 7 13 2 12 Q -1 11 0 8 C 1 4 0 4 0 2 C 0 0 1 0 1 0 C 3 0 3 1 7 0"
- style={{ stroke: "black", fill: backgroundColor, strokeWidth: 0.2 }} />
+ style={{ stroke: "black", fill: backgroundColor(), strokeWidth: 0.2 }} />
</svg>
</div>}
- {this.props.fitToBox ?
- <ContentFittingDocumentView {...divProps} ref={action((r: ContentFittingDocumentView | null) => this._contentView = r)} /> :
- <DocumentView {...divProps} ContentScaling={this.contentScaling} />}
+ <DocumentView {...divProps} ref={action((r: DocumentView | null) => this._contentView = r)} />
</div>;
}
}