aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/views/MainView.tsx5
-rw-r--r--src/client/views/collections/CollectionCarouselView.tsx5
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx4
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx118
-rw-r--r--src/client/views/nodes/CollectionFreeFormDocumentView.tsx60
-rw-r--r--src/fields/ScriptField.ts8
6 files changed, 128 insertions, 72 deletions
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 978cf7868..f58313f06 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -1,6 +1,6 @@
import { library } from '@fortawesome/fontawesome-svg-core';
import {
- faTrashAlt, faAngleRight, faBell, faTrash, faCamera, faExpand, faCaretDown, faCaretRight, faCaretSquareDown, faCaretSquareRight, faArrowsAltH, faPlus, faMinus,
+ faTrashAlt, faAngleRight, faBell, faTrash, faCamera, faExpand, faCaretDown, faCaretLeft, faCaretRight, faCaretSquareDown, faCaretSquareRight, faArrowsAltH, faPlus, faMinus,
faTerminal, faToggleOn, faFile as fileSolid, faExternalLinkAlt, faLocationArrow, faSearch, faFileDownload, faStop, faCalculator, faWindowMaximize, faAddressCard,
faQuestionCircle, faArrowLeft, faArrowRight, faArrowDown, faArrowUp, faBolt, faBullseye, faCaretUp, faCat, faCheck, faChevronRight, faClipboard, faClone, faCloudUploadAlt,
faCommentAlt, faCompressArrowsAlt, faCut, faEllipsisV, faEraser, faExclamation, faFileAlt, faFileAudio, faFilePdf, faFilm, faFilter, faFont, faGlobeAsia, faHighlighter,
@@ -121,6 +121,8 @@ export class MainView extends React.Component {
library.add(faCamera);
library.add(faExpand);
library.add(faCaretDown);
+ library.add(faCaretUp);
+ library.add(faCaretLeft);
library.add(faCaretRight);
library.add(faCaretSquareDown);
library.add(faCaretSquareRight);
@@ -168,7 +170,6 @@ export class MainView extends React.Component {
library.add(faThumbtack);
library.add(faLongArrowAltRight);
library.add(faCheck);
- library.add(faCaretUp);
library.add(faFilter);
library.add(faBullseye);
library.add(faArrowLeft);
diff --git a/src/client/views/collections/CollectionCarouselView.tsx b/src/client/views/collections/CollectionCarouselView.tsx
index 39bb9bc23..f65a89422 100644
--- a/src/client/views/collections/CollectionCarouselView.tsx
+++ b/src/client/views/collections/CollectionCarouselView.tsx
@@ -9,7 +9,6 @@ import { DragManager } from '../../util/DragManager';
import { ContentFittingDocumentView } from '../nodes/ContentFittingDocumentView';
import "./CollectionCarouselView.scss";
import { CollectionSubView } from './CollectionSubView';
-import { faCaretLeft, faCaretRight } from '@fortawesome/free-solid-svg-icons';
import { Doc } from '../../../fields/Doc';
import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox';
import { ContextMenu } from '../ContextMenu';
@@ -76,10 +75,10 @@ export class CollectionCarouselView extends CollectionSubView(CarouselDocument)
@computed get buttons() {
return <>
<div key="back" className="carouselView-back" style={{ background: `${StrCast(this.props.Document.backgroundColor)}` }} onClick={this.goback}>
- <FontAwesomeIcon icon={faCaretLeft} size={"2x"} />
+ <FontAwesomeIcon icon={"caret-left"} size={"2x"} />
</div>
<div key="fwd" className="carouselView-fwd" style={{ background: `${StrCast(this.props.Document.backgroundColor)}` }} onClick={this.advance}>
- <FontAwesomeIcon icon={faCaretRight} size={"2x"} />
+ <FontAwesomeIcon icon={"caret-right"} size={"2x"} />
</div>
</>;
}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
index 3860ce2d7..a4fd5384f 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
@@ -25,6 +25,7 @@ export interface ViewDefBounds {
fontSize?: number;
highlight?: boolean;
color?: string;
+ opacity?: number;
replica?: string;
pair?: { layout: Doc, data?: Doc };
}
@@ -37,6 +38,7 @@ export interface PoolData {
width?: number;
height?: number;
color?: string;
+ opacity?: number;
transition?: string;
highlight?: boolean;
replica: string;
@@ -416,7 +418,7 @@ function normalizeResults(
height: newPosRaw.height! * scale,
pair: ele[1].pair
};
- poolData.set(newPos.pair.layout[Id] + (newPos.replica || ""), { transition: "transform 1s", ...newPos });
+ poolData.set(newPos.pair.layout[Id] + (newPos.replica || ""), { transition: "all 1s", ...newPos });
}
});
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index bf679309c..751ee03d2 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -46,6 +46,7 @@ import React = require("react");
import { CollectionViewType } from "../CollectionView";
import { Timeline } from "../../animationtimeline/Timeline";
import { SnappingManager } from "../../../util/SnappingManager";
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
library.add(faEye as any, faTable, faPaintBrush, faExpandArrowsAlt, faCompressArrowsAlt, faCompass, faUpload, faBraille, faChalkboard, faFileUpload);
@@ -53,6 +54,7 @@ export const panZoomSchema = createSchema({
_panX: "number",
_panY: "number",
scale: "number",
+ timecode: "number",
arrangeScript: ScriptField,
arrangeInit: ScriptField,
useClusters: "boolean",
@@ -124,15 +126,8 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
this.addDocument(newBox);
}
addDocument = (newBox: Doc | Doc[]) => {
- const timecode = Cast(this.props.Document.timecode, "number", null);
- if (timecode !== undefined) {
- ((newBox instanceof Doc) ? [newBox] : newBox).map(doc => {
- doc["x-indexed"] = new List<number>(numberRange(timecode + 1).map(i => NumCast(doc.x)));
- doc["y-indexed"] = new List<number>(numberRange(timecode + 1).map(i => NumCast(doc.y)));
- doc.timecode = ComputedField.MakeFunction("collection.timecode", {}, { collection: this.props.Document });
- doc.x = ComputedField.MakeInterpolated("x", "timecode");
- doc.y = ComputedField.MakeInterpolated("y", "timecode");
- });
+ if (this.Document.timecode !== undefined) {
+ CollectionFreeFormDocumentView.setupKeyframes((newBox instanceof Doc) ? [newBox] : newBox, this.Document.timecode, this.props.Document);
}
if (newBox instanceof Doc) {
@@ -145,6 +140,25 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
// bcz: deal with clusters
}
}
+
+ @undoBatch
+ @action
+ nextKeyframe = (): void => {
+ if (this.props.Document.timecode === undefined) {
+ this.props.Document.timecode = 0;
+ CollectionFreeFormDocumentView.setupKeyframes(this.childDocs, 0, this.props.Document);
+ }
+ const timecode = NumCast(this.props.Document.timecode);
+ CollectionFreeFormDocumentView.updateKeyframe(this.childDocs, timecode);
+ this.props.Document.timecode = Math.max(0, timecode + 1);
+ }
+ @undoBatch
+ @action
+ prevKeyframe = (): void => {
+ CollectionFreeFormDocumentView.gotoKeyframe(this.childDocs.slice());
+ this.props.Document.timecode = Math.max(0, NumCast(this.props.Document.timecode) - 1);
+ }
+
private selectDocuments = (docs: Doc[]) => {
SelectionManager.DeselectAll();
docs.map(doc => DocumentManager.Instance.getDocumentView(doc)).map(dv => dv && SelectionManager.SelectDoc(dv, true));
@@ -185,8 +199,12 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
for (let i = 0; i < droppedDocs.length; i++) {
const d = droppedDocs[i];
const layoutDoc = Doc.Layout(d);
- d.x = x + NumCast(d.x) - dropX;
- d.y = y + NumCast(d.y) - dropY;
+ if (this.Document.timecode !== undefined) {
+ CollectionFreeFormDocumentView.setValues(this.Document.timecode, d, x + NumCast(d.x) - dropX, y + NumCast(d.y) - dropY, Cast(d.opacity, "number", null));
+ } else {
+ d.x = x + NumCast(d.x) - dropX;
+ d.y = y + NumCast(d.y) - dropY;
+ }
if (!NumCast(layoutDoc._width)) {
layoutDoc._width = 300;
}
@@ -953,10 +971,15 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
return { x: 0, y: 0, transition: "transform 1s", ...result, pair: params.pair, replica: "" };
}
const layoutDoc = Doc.Layout(params.pair.layout);
- const { x, y, z, color, zIndex } = params.pair.layout;
+ const { x, y, opacity } = this.Document.timecode === undefined ? params.pair.layout :
+ CollectionFreeFormDocumentView.getValues(params.pair.layout, this.Document.timecode);
+ if (this.Document.timecode !== undefined) {
+ const time = this.Document.timecode || 0;
+ }
+ const { z, color, zIndex } = params.pair.layout;
return {
x: NumCast(x), y: NumCast(y), z: Cast(z, "number"), color: StrCast(color), zIndex: Cast(zIndex, "number"),
- transition: StrCast(layoutDoc.transition),
+ transition: StrCast(layoutDoc.transition), opacity: Cast(opacity, "number", null),
width: Cast(layoutDoc._width, "number"), height: Cast(layoutDoc._height, "number"), pair: params.pair, replica: ""
};
}
@@ -1142,39 +1165,6 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
Doc.toggleNativeDimensions(this.layoutDoc, this.props.ContentScaling(), this.props.NativeWidth(), this.props.NativeHeight());
}
- @undoBatch
- @action
- snaphsotInterpolated = (): void => {
- if (this.props.Document.timecode === undefined) {
- this.childDocs.map(doc => {
- this.props.Document.timecode = 0;
- doc["x-indexed"] = new List<number>([NumCast(doc.x)]);
- doc["y-indexed"] = new List<number>([NumCast(doc.y)]);
- doc.timecode = ComputedField.MakeFunction("collection.timecode", {}, { collection: this.props.Document });
- doc.x = ComputedField.MakeInterpolated("x", "timecode");
- doc.y = ComputedField.MakeInterpolated("y", "timecode");
- });
- }
- const timecode = NumCast(this.props.Document.timecode);
- this.childDocs.map(doc => {
- const xindexed = Cast(doc['x-indexed'], listSpec("number"), null);
- const yindexed = Cast(doc['y-indexed'], listSpec("number"), null);
- xindexed.length <= timecode + 1 && xindexed.push(NumCast(doc.x));
- yindexed.length <= timecode + 1 && yindexed.push(NumCast(doc.y));
- });
- this.childDocs.map(doc => doc.transition = "transform 1s");
- this.props.Document.timecode = Math.max(0, timecode + 1);
- setTimeout(() => this.childDocs.map(doc => doc.transition = undefined), 1010);
- }
- @undoBatch
- @action
- backupInterpolated = (): void => {
- this.childDocs.map(doc => doc.transition = "transform 1s");
- this.props.Document.timecode = Math.max(0, NumCast(this.props.Document.timecode) - 1);
- setTimeout(() => this.childDocs.map(doc => doc.transition = undefined), 1010);
- }
-
-
private thumbIdentifier?: number;
onContextMenu = (e: React.MouseEvent) => {
@@ -1185,8 +1175,8 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
this._timelineVisible = !this._timelineVisible;
}), icon: this._timelineVisible ? faEyeSlash : faEye
});
- ContextMenu.Instance.addItem({ description: "Advance", event: this.snaphsotInterpolated, icon: BoolCast(this.Document.lockedTransform) ? "unlock" : "lock" });
- ContextMenu.Instance.addItem({ description: "Backup ", event: this.backupInterpolated, icon: BoolCast(this.Document.lockedTransform) ? "unlock" : "lock" });
+ ContextMenu.Instance.addItem({ description: "Advance", event: this.nextKeyframe, icon: BoolCast(this.Document.lockedTransform) ? "unlock" : "lock" });
+ ContextMenu.Instance.addItem({ description: "Backup ", event: this.prevKeyframe, icon: BoolCast(this.Document.lockedTransform) ? "unlock" : "lock" });
const options = ContextMenu.Instance.findByDescription("Options...");
const optionItems: ContextMenuProps[] = options && "subitems" in options ? options.subitems : [];
@@ -1342,18 +1332,14 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
render() {
TraceMobx();
const clientRect = this._mainCont?.getBoundingClientRect();
- // update the actual dimensions of the collection so that they can inquired (e.g., by a minimap)
- // this.Document.fitX = this.contentBounds && this.contentBounds.x;
- // this.Document.fitY = this.contentBounds && this.contentBounds.y;
- // this.Document.fitW = this.contentBounds && (this.contentBounds.r - this.contentBounds.x);
- // this.Document.fitH = this.contentBounds && (this.contentBounds.b - this.contentBounds.y);
- // if isAnnotationOverlay is set, then children will be stored in the extension document for the fieldKey.
- // otherwise, they are stored in fieldKey. All annotations to this document are stored in the extension document
- return <div className={"collectionfreeformview-container"}
- ref={this.createDashEventsTarget}
+ return <div className={"collectionfreeformview-container"} ref={this.createDashEventsTarget}
onPointerOver={this.onPointerOver}
- onWheel={this.onPointerWheel} onClick={this.onClick} //pointerEvents: DraggingManager.GetIsDragging() ? "all" : undefined,
- onPointerDown={this.onPointerDown} onPointerMove={this.onCursorMove} onDrop={this.onExternalDrop.bind(this)} onContextMenu={this.onContextMenu}
+ onWheel={this.onPointerWheel}
+ onClick={this.onClick}
+ onPointerDown={this.onPointerDown}
+ onPointerMove={this.onCursorMove}
+ onDrop={this.onExternalDrop.bind(this)}
+ onContextMenu={this.onContextMenu}
style={{
pointerEvents: this.backgroundEvents ? "all" : undefined,
transform: this.contentScaling ? `scale(${this.contentScaling})` : "",
@@ -1364,12 +1350,22 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
{!this.Document._LODdisable && !this.props.active() && !this.props.isAnnotationOverlay && !this.props.annotationsKey && this.props.renderDepth > 0 ?
this.placeholder : this.marqueeView}
<CollectionFreeFormOverlayView elements={this.elementFunc} />
-
+ {this.isAnnotationOverlay ? (null) :
+ <>
+ <div key="back" style={{ position: "absolute", width: 20, height: 20, right: 0, bottom: 0, }} onClick={this.nextKeyframe}>
+ <FontAwesomeIcon icon={"caret-right"} size={"lg"} />
+ </div>
+ <div key="fwd" style={{ position: "absolute", width: 20, height: 20, right: 20, bottom: 0, }}>
+ {NumCast(this.props.Document.timecode)}
+ </div>
+ <div key="fwd" style={{ position: "absolute", width: 20, height: 20, right: 40, bottom: 0, }} onClick={this.prevKeyframe}>
+ <FontAwesomeIcon icon={"caret-left"} size={"lg"} />
+ </div>
+ </>}
<div className={"pullpane-indicator"}
style={{
display: this._pullDirection ? "block" : "none",
top: clientRect ? this._pullDirection === "bottom" ? this._pullCoords[1] - clientRect.y : 0 : "auto",
- // left: clientRect ? this._pullDirection === "right" ? this._pullCoords[0] - clientRect.x - MainView.Instance.flyoutWidth : 0 : "auto",
left: clientRect ? this._pullDirection === "right" ? this._pullCoords[0] - clientRect.x : 0 : "auto",
width: clientRect ? this._pullDirection === "left" ? this._pullCoords[0] - clientRect.left : this._pullDirection === "right" ? clientRect.right - this._pullCoords[0] : clientRect.width : 0,
height: clientRect ? this._pullDirection === "top" ? this._pullCoords[1] - clientRect.top : this._pullDirection === "bottom" ? clientRect.bottom - this._pullCoords[1] : clientRect.height : 0,
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 5d6e587d9..5d109a5f2 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -10,9 +10,14 @@ import React = require("react");
import { Document } from "../../../fields/documentSchemas";
import { TraceMobx } from "../../../fields/util";
import { ContentFittingDocumentView } from "./ContentFittingDocumentView";
+import { List } from "../../../fields/List";
+import { numberRange } from "../../../Utils";
+import { ComputedField } from "../../../fields/ScriptField";
+import { listSpec } from "../../../fields/Schema";
+import { docs } from "googleapis/build/src/apis/docs";
export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps {
- dataProvider?: (doc: Doc, replica: string) => { x: number, y: number, zIndex?: number, highlight?: boolean, z: number, transition?: string } | undefined;
+ dataProvider?: (doc: Doc, replica: string) => { x: number, y: number, zIndex?: number, opacity?: number, highlight?: boolean, z: number, transition?: string } | undefined;
sizeProvider?: (doc: Doc, replica: string) => { width: number, height: number } | undefined;
zIndex?: number;
highlight?: boolean;
@@ -35,6 +40,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
get transform() { return `scale(${this.props.ContentScaling()}) translate(${this.X}px, ${this.Y}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 Opacity() { return this.dataProvider ? this.dataProvider.opacity : (this.Document.opacity || 0); }
get ZInd() { return this.dataProvider ? this.dataProvider.zIndex : (this.Document.zIndex || 0); }
get Highlight() { return this.dataProvider?.highlight; }
get width() { return this.props.sizeProvider && this.sizeProvider ? this.sizeProvider.width : this.layoutDoc[WidthSym](); }
@@ -62,6 +68,53 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
}
return undefined;
}
+
+ public static getValues(doc: Doc, time: number) {
+ return ({
+ x: Cast(doc["x-indexed"], listSpec("number"), []).reduce((p, x, i) => (i <= time && x !== undefined) || p === undefined ? x : p, undefined as any as number),
+ y: Cast(doc["y-indexed"], listSpec("number"), []).reduce((p, y, i) => (i <= time && y !== undefined) || p === undefined ? y : p, undefined as any as number),
+ opacity: Cast(doc["opacity-indexed"], listSpec("number"), []).reduce((p, o, i) => i <= time || p === undefined ? o : p, undefined as any as number),
+ });
+ }
+
+ public static setValues(timecode: number, d: Doc, x?: number, y?: number, opacity?: number) {
+ Cast(d["x-indexed"], listSpec("number"), [])[timecode] = x as any as number;
+ Cast(d["y-indexed"], listSpec("number"), null)[timecode] = y as any as number;
+ Cast(d["opacity-indexed"], listSpec("number"), null)[timecode] = opacity as any as number;
+ }
+ public static updateKeyframe(docs: Doc[], timecode: number) {
+ docs.forEach(doc => {
+ const xindexed = Cast(doc['x-indexed'], listSpec("number"), null);
+ const yindexed = Cast(doc['y-indexed'], listSpec("number"), null);
+ const opacityindexed = Cast(doc['opacity-indexed'], listSpec("number"), null);
+ xindexed.length <= timecode + 1 && xindexed.push(undefined as any as number);
+ yindexed.length <= timecode + 1 && yindexed.push(undefined as any as number);
+ opacityindexed.length <= timecode + 1 && opacityindexed.push(undefined as any as number);
+ doc.transition = "all 1s";
+ });
+ setTimeout(() => docs.forEach(doc => doc.transition = undefined), 1010);
+ }
+
+ public static gotoKeyframe(docs: Doc[]) {
+ docs.forEach(doc => doc.transition = "all 1s");
+ setTimeout(() => docs.forEach(doc => doc.transition = undefined), 1010);
+ }
+
+ public static setupKeyframes(docs: Doc[], timecode: number, collection: Doc) {
+ docs.forEach(doc => {
+ doc["x-indexed"] = new List<number>(numberRange(timecode).map(i => undefined) as any as number[]);
+ doc["y-indexed"] = new List<number>(numberRange(timecode).map(i => undefined) as any as number[]);
+ doc["opacity-indexed"] = new List<number>(numberRange(timecode).map(i => 0));
+ (doc["x-indexed"] as any).push(NumCast(doc.x));
+ (doc["y-indexed"] as any).push(NumCast(doc.y));
+ (doc["opacity-indexed"] as any).push(NumCast(doc.opacity, 1));
+ doc.timecode = ComputedField.MakeFunction("collection.timecode", {}, { collection });
+ doc.x = ComputedField.MakeInterpolated("x", "timecode");
+ doc.y = ComputedField.MakeInterpolated("y", "timecode");
+ doc.opacity = ComputedField.MakeInterpolated("opacity", "timecode");
+ });
+ }
+
nudge = (x: number, y: number) => {
this.props.Document.x = NumCast(this.props.Document.x) + x;
this.props.Document.y = NumCast(this.props.Document.y) + y;
@@ -79,7 +132,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
return <div className="collectionFreeFormDocumentView-container"
style={{
boxShadow:
- this.layoutDoc.opacity === 0 ? undefined : // if it's not visible, then no shadow
+ this.Opacity === 0 ? undefined : // if it's not visible, then no shadow
this.layoutDoc.z ? `#9c9396 ${StrCast(this.layoutDoc.boxShadow, "10px 10px 0.9vw")}` : // if it's a floating doc, give it a big shadow
this.props.backgroundHalo?.() ? (`${this.props.backgroundColor?.(this.props.Document)} ${StrCast(this.layoutDoc.boxShadow, `0vw 0vw ${(this.layoutDoc.isBackground ? 100 : 50) / this.props.ContentScaling()}px`)}`) : // if it's just in a cluster, make the shadown roughly match the cluster border extent
this.layoutDoc.isBackground ? undefined : // if it's a background & has a cluster color, make the shadow spread really big
@@ -90,9 +143,10 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
transition: this.props.transition ? this.props.transition : this.dataProvider ? this.dataProvider.transition : StrCast(this.layoutDoc.transition),
width: this.width,
height: this.height,
+ opacity: this.Opacity,
zIndex: this.ZInd,
display: this.ZInd === -99 ? "none" : undefined,
- pointerEvents: this.props.Document.isBackground ? "none" : this.props.pointerEvents ? "all" : undefined
+ pointerEvents: this.props.Document.isBackground || this.Opacity === 0 ? "none" : this.props.pointerEvents ? "all" : undefined
}} >
{!this.props.fitToBox ?
diff --git a/src/fields/ScriptField.ts b/src/fields/ScriptField.ts
index f05f431ac..0ac1ac360 100644
--- a/src/fields/ScriptField.ts
+++ b/src/fields/ScriptField.ts
@@ -1,5 +1,5 @@
import { ObjectField } from "./ObjectField";
-import { CompiledScript, CompileScript, scriptingGlobal, ScriptOptions, CompileError, CompileResult } from "../client/util/Scripting";
+import { CompiledScript, CompileScript, scriptingGlobal, ScriptOptions, CompileError, CompileResult, Scripting } from "../client/util/Scripting";
import { Copy, ToScriptString, ToString, Parent, SelfProxy } from "./FieldSymbols";
import { serializable, createSimpleSchema, map, primitive, object, deserialize, PropSchema, custom, SKIP } from "serializr";
import { Deserializable, autoObject } from "../client/util/SerializationHelper";
@@ -156,12 +156,16 @@ export class ComputedField extends ScriptField {
return compiled.compiled ? new ComputedField(compiled, setCompiled?.compiled ? setCompiled : undefined) : undefined;
}
public static MakeInterpolated(fieldKey: string, interpolatorKey: string) {
- const getField = ScriptField.CompileScript(`(self['${fieldKey}-indexed'])[self.${interpolatorKey}]`, {}, true, {});
+ const getField = ScriptField.CompileScript(`getIndexVal(self['${fieldKey}-indexed'], self.${interpolatorKey})`, {}, true, {});
const setField = ScriptField.CompileScript(`(self['${fieldKey}-indexed'])[self.${interpolatorKey}] = value`, { value: "any" }, true, {});
return getField.compiled ? new ComputedField(getField, setField?.compiled ? setField : undefined) : undefined;
}
}
+Scripting.addGlobal(function getIndexVal(list: any[], index: number) {
+ return list.reduce((p, x, i) => (i <= index && x !== undefined) || p === undefined ? x : p, undefined as any)
+});
+
export namespace ComputedField {
let useComputed = true;
export function DisableComputedFields() {