From 440f5c296a599d5c3f9ed781b58c5b00da6edb5a Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Mon, 22 Aug 2022 17:18:10 -0400
Subject: added animation of background color, and streamlined/extended a
 variety of props-related things.

---
 .../views/nodes/CollectionFreeFormDocumentView.tsx | 30 +++++++++++++++++-----
 1 file changed, 24 insertions(+), 6 deletions(-)

(limited to 'src/client/views/nodes/CollectionFreeFormDocumentView.tsx')

diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index e19e2d525..7dc8a7fbb 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -18,7 +18,7 @@ import { DocumentView, DocumentViewProps } from './DocumentView';
 import React = require('react');
 
 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;
+    dataProvider?: (doc: Doc, replica: string) => { x: number; y: number; zIndex?: number; backgroundColor?: string; opacity?: number; highlight?: boolean; z: number; transition?: string } | undefined;
     sizeProvider?: (doc: Doc, replica: string) => { width: number; height: number } | undefined;
     renderCutoffProvider: (doc: Doc) => boolean;
     zIndex?: number;
@@ -32,6 +32,7 @@ export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps {
 @observer
 export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeFormDocumentViewProps>() {
     public static animFields = ['_height', '_width', 'x', 'y', '_scrollTop', 'opacity']; // fields that are configured to be animatable using animation frames
+    public static animStringFields = ['backgroundColor']; // fields that are configured to be animatable using animation frames
     @observable _animPos: number[] | undefined = undefined;
     @observable _contentView: DocumentView | undefined | null;
     get displayName() {
@@ -41,16 +42,19 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
         return `translate(${this.X}px, ${this.Y}px) rotate(${NumCast(this.Document.jitterRotation, this.props.jitterRotation)}deg)`;
     }
     get X() {
-        return this.dataProvider ? this.dataProvider.x : NumCast(this.Document.x);
+        return this.dataProvider?.x ?? NumCast(this.Document.x);
     }
     get Y() {
-        return this.dataProvider ? this.dataProvider.y : NumCast(this.Document.y);
+        return this.dataProvider?.y ?? NumCast(this.Document.y);
     }
     get ZInd() {
-        return this.dataProvider ? this.dataProvider.zIndex : NumCast(this.Document.zIndex);
+        return this.dataProvider?.zIndex ?? NumCast(this.Document.zIndex);
     }
     get Opacity() {
-        return this.dataProvider ? this.dataProvider.opacity : undefined;
+        return this.dataProvider?.opacity;
+    }
+    get BackgroundColor() {
+        return this.dataProvider?.backgroundColor;
     }
     get Highlight() {
         return this.dataProvider?.highlight;
@@ -67,6 +71,9 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
 
     styleProvider = (doc: Doc | undefined, props: Opt<DocumentViewProps>, property: string) => {
         if (property === StyleProp.Opacity && doc === this.layoutDoc) return this.Opacity; // only change the opacity for this specific document, not its children
+        if (property === StyleProp.BackgroundColor) {
+            return this.BackgroundColor; // only change the opacity for this specific document, not its children
+        }
         return this.props.styleProvider?.(doc, props, property);
     };
 
@@ -77,6 +84,13 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
         }, {} as { [val: string]: Opt<number> });
     }
 
+    public static getStringValues(doc: Doc, time: number) {
+        return CollectionFreeFormDocumentView.animStringFields.reduce((p, val) => {
+            p[val] = Cast(`${val}-indexed`, listSpec('string'), [StrCast(doc[val])]).reduce((p, v, i) => ((i <= Math.round(time) && v !== undefined) || p === undefined ? v : p), undefined as any as string);
+            return p;
+        }, {} as { [val: string]: Opt<string> });
+    }
+
     public static setValues(time: number, d: Doc, vals: { [val: string]: Opt<number> }) {
         const timecode = Math.round(time);
         Object.keys(vals).forEach(val => {
@@ -95,6 +109,10 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
                     const findexed = Cast(doc[`${val}-indexed`], listSpec('number'), null);
                     findexed?.length <= timecode + 1 && findexed.push(undefined as any as number);
                 });
+                CollectionFreeFormDocumentView.animStringFields.forEach(val => {
+                    const findexed = Cast(doc[`${val}-indexed`], listSpec('string'), null);
+                    findexed?.length <= timecode + 1 && findexed.push(undefined as any as string);
+                });
             })
         );
         setTimeout(
@@ -142,6 +160,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
                 doc['opacity-indexed'] = new List<number>(numberRange(currTimecode + 1).map(t => (!doc.z && makeAppear && t < NumCast(doc.appearFrame) ? 0 : 1)));
             }
             CollectionFreeFormDocumentView.animFields.forEach(val => (doc[val] = ComputedField.MakeInterpolated(val, 'activeFrame', doc, currTimecode)));
+            CollectionFreeFormDocumentView.animStringFields.forEach(val => (doc[val] = ComputedField.MakeInterpolatedString(val, 'activeFrame', doc, currTimecode)));
             doc.activeFrame = ComputedField.MakeFunction('self.context?._currentFrame||0');
             doc.dataTransition = 'inherit';
         });
@@ -189,7 +208,6 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
             PanelWidth: this.panelWidth,
             PanelHeight: this.panelHeight,
         };
-        const background = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);
         const mixBlendMode = undefined; // (StrCast(this.layoutDoc.mixBlendMode) as any) || (typeof background === 'string' && background && !background.startsWith('linear') && DashColor(background).alpha() !== 1 ? 'multiply' : undefined);
         return (
             <div
-- 
cgit v1.2.3-70-g09d2

