diff options
author | Sophie Zhang <sophie_zhang@brown.edu> | 2024-05-14 14:17:44 -0400 |
---|---|---|
committer | Sophie Zhang <sophie_zhang@brown.edu> | 2024-05-14 14:17:44 -0400 |
commit | 1e6d483091131db07b30e96d0910c858eb4f37c4 (patch) | |
tree | 9975ddef5dd273df19507adca53718066c888dcc /src | |
parent | 0201c8b4d52932760d87686424cdc0a4d39e60bd (diff) |
add fields to customization
Diffstat (limited to 'src')
-rw-r--r-- | src/client/apis/gpt/customization.ts | 40 | ||||
-rw-r--r-- | src/client/views/nodes/trails/CubicBezierEditor.tsx | 25 | ||||
-rw-r--r-- | src/client/views/nodes/trails/PresBox.tsx | 77 | ||||
-rw-r--r-- | src/client/views/nodes/trails/SpringUtils.ts | 3 |
4 files changed, 45 insertions, 100 deletions
diff --git a/src/client/apis/gpt/customization.ts b/src/client/apis/gpt/customization.ts index 9c751f8bd..13129b23c 100644 --- a/src/client/apis/gpt/customization.ts +++ b/src/client/apis/gpt/customization.ts @@ -1,6 +1,4 @@ -import { ChatCompletionMessageParam } from 'openai/resources'; import { openai } from './setup'; -import { ClientOptions, OpenAI } from 'openai'; export enum CustomizationType { PRES_TRAIL_SLIDE = 'trails', @@ -18,15 +16,35 @@ const prompts: { [key: string]: PromptInfo } = { }, }; +// Allows you to register properties that are customizable export const addCustomizationProperty = (type: CustomizationType, name: string, description: string, values?: string[]) => { values ? prompts[type].features.push({ name, description, values }) : prompts[type].features.push({ name, description }); }; -export const gptSlideProperties = ['title', 'presentation_transition', 'presentation_effect', 'presentation_effectDirection', 'presEffectTiming', 'config_zoom']; +// All the registered fields, make sure to update during registration, this +// includes most fields but is not yet fully comprehensive +export const gptSlideProperties = [ + 'title', + 'presentation_transition', + 'presEaseFunc', + 'presentation_effect', + 'presentation_effectDirection', + 'presEffectTiming', + 'config_zoom', + 'presPlayAudio', + 'presentation_zoomText', + 'presentation_hideBefore', + 'presentation_hide', + 'presentation_hideAfter', + 'presentation_openInLightbox', +]; +// Registers slide properties const setupPresSlideCustomization = () => { addCustomizationProperty(CustomizationType.PRES_TRAIL_SLIDE, 'title', 'is the title/name of the slide.'); addCustomizationProperty(CustomizationType.PRES_TRAIL_SLIDE, 'presentation_transition', 'is a number in milliseconds for how long it should take to transition/move to a slide.'); + addCustomizationProperty(CustomizationType.PRES_TRAIL_SLIDE, 'presEaseFunc', 'is the easing function for the movement to the slide.', ['Ease', 'Ease In', 'Ease Out', 'Ease Out', 'Ease In Out', 'Linear']); + addCustomizationProperty(CustomizationType.PRES_TRAIL_SLIDE, 'presentation_effect', 'is an effect applied to the slide when we transition to it.', ['None', 'Zoom', 'Fade in', 'Bounce', 'Flip', 'Rotate', 'Roll']); addCustomizationProperty(CustomizationType.PRES_TRAIL_SLIDE, 'presentation_effectDirection', 'is what direction the effect is applied.', ['Enter from left', 'Enter from right', 'Enter from bottom', 'Enter from Top', 'Enter from center']); addCustomizationProperty( @@ -34,12 +52,21 @@ const setupPresSlideCustomization = () => { 'presEffectTiming', "is a json object of the format: {type: string, stiffness: number, damping: number, mass: number}. Type is always “custom”. Controls the spring-based timing of the presentation effect animation. Stiffness, damping, and mass control the physics-based properties of spring animations. This is used to create a more natural looking timing, bouncy effects, etc. Use spring physics to adjust these parameters to match the user's description of how they want to animate the effect." ); + addCustomizationProperty(CustomizationType.PRES_TRAIL_SLIDE, 'config_zoom', 'is a number from 0 to 1.0 indicating the percentage we should zoom into the slide.'); + + // boolean values + addCustomizationProperty(CustomizationType.PRES_TRAIL_SLIDE, 'presPlayAudio', 'is a boolean value indicating if we should play audio when we go to the slide.'); + addCustomizationProperty(CustomizationType.PRES_TRAIL_SLIDE, 'presentation_zoomText', 'is a boolean value indicating if we should zoom into text selections when we go to the slide.'); + addCustomizationProperty(CustomizationType.PRES_TRAIL_SLIDE, 'presentation_hideBefore', 'is a boolean value indicating if we should hide the slide before going to it.'); + addCustomizationProperty(CustomizationType.PRES_TRAIL_SLIDE, 'presentation_hide', 'is a boolean value indicating if we should hide the slide during the presentation.'); + addCustomizationProperty(CustomizationType.PRES_TRAIL_SLIDE, 'presentation_hideAfter', 'is a boolean value indicating if we should hide the slide after going to it.'); + addCustomizationProperty(CustomizationType.PRES_TRAIL_SLIDE, 'presentation_openInLightbox', 'is a boolean value indicating if we should open the slide in an overlay or lightbox view during the presentation.'); }; setupPresSlideCustomization(); -export const getSlideTransitionSuggestions = async (inputText: string, history?: string) => { +export const getSlideTransitionSuggestions = async (inputText: string) => { /** * Prompt: Generate an entrance animations from slower and gentler * to bouncier and more high energy @@ -50,15 +77,12 @@ export const getSlideTransitionSuggestions = async (inputText: string, history?: * effect: BOUNCE * effectDirection: LEFT * timingConfig: { - * - * - * * } * } */ const prompt = - "I want to generate four distinct types of slide effect animations. Return a json of the form {effect: string, stiffness: number, damping: number, mass: number}[] with four elements. Effect is the type of animation; its only possible values are ['Zoom', 'Fade in', 'Bounce', 'Flip', 'Rotate', 'Roll']. Stiffness, damping, and mass Stiffness, damping, and mass control the physics-based properties of spring animations. This is used to create a more natural looking timing, bouncy effects, etc. Use spring physics to adjust these parameters to animate the effect."; + "I want to generate four distinct types of slide effect animations. Return a json of the form {effect: string, direction: string, stiffness: number, damping: number, mass: number}[] with four elements. Effect is the type of animation; its only possible values are ['Zoom', 'Fade in', 'Bounce', 'Flip', 'Rotate', 'Roll']. Direction is the direction that the animation starts from; its only possible values are ['Enter from left', 'Enter from right', 'Enter from bottom', 'Enter from Top', 'Enter from center']. Stiffness, damping, and mass control the physics-based properties of spring animations. This is used to create a more natural-looking timing, bouncy effects, etc. Use spring physics to adjust these parameters to animate the effect."; const customInput = inputText ?? 'Make them as contrasting as possible with different effects and timings ranging from gentle to energetic.'; diff --git a/src/client/views/nodes/trails/CubicBezierEditor.tsx b/src/client/views/nodes/trails/CubicBezierEditor.tsx index aba777e55..5f348ddd9 100644 --- a/src/client/views/nodes/trails/CubicBezierEditor.tsx +++ b/src/client/views/nodes/trails/CubicBezierEditor.tsx @@ -20,16 +20,11 @@ export const TIMING_DEFAULT_MAPPINGS = { 'ease-in-out': 'cubic-bezier(0.42, 0, 0.58, 1.0)', }; +/** + * Visual editor for a bezier curve with draggable control points + * */ const CubicBezierEditor = ({ setFunc, currPoints, easeFunc }: Props) => { const [animating, setAnimating] = useState(false); - // const [cPoints, setCPoints] = useState( - // currPoints - // ? currPoints - // : { - // p1: [0.25, 0.1], - // p2: [0.25, 1.0], - // } - // ); const [c1Down, setC1Down] = useState(false); const [c2Down, setC2Down] = useState(false); @@ -71,12 +66,6 @@ const CubicBezierEditor = ({ setFunc, currPoints, easeFunc }: Props) => { }; }; - // useEffect(() => { - // if (!easeFunc.startsWith('cubic')) { - // setFunc(convertToPoints(easeFunc)); - // } - // }, [easeFunc]); - useEffect(() => { if (animating) { setTimeout(() => { @@ -96,10 +85,6 @@ const CubicBezierEditor = ({ setFunc, currPoints, easeFunc }: Props) => { return; } - // setCPoints(prev => ({ - // ...prev, - // p1: [roundToHundredth(prev.p1[0] + e.movementX / EDITOR_WIDTH), roundToHundredth(prev.p1[1] - e.movementY / EDITOR_WIDTH)], - // })); setFunc({ ...currPoints, p1: [roundToHundredth(currPoints.p1[0] + e.movementX / EDITOR_WIDTH), roundToHundredth(currPoints.p1[1] - e.movementY / EDITOR_WIDTH)], @@ -122,10 +107,6 @@ const CubicBezierEditor = ({ setFunc, currPoints, easeFunc }: Props) => { return; } - // setCPoints(prev => ({ - // ...prev, - // p2: [roundToHundredth(prev.p2[0] + e.movementX / EDITOR_WIDTH), roundToHundredth(prev.p2[1] - e.movementY / EDITOR_WIDTH)], - // })); setFunc({ ...currPoints, p2: [roundToHundredth(currPoints.p2[0] + e.movementX / EDITOR_WIDTH), roundToHundredth(currPoints.p2[1] - e.movementY / EDITOR_WIDTH)], diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx index 02233d241..a7a4e08e0 100644 --- a/src/client/views/nodes/trails/PresBox.tsx +++ b/src/client/views/nodes/trails/PresBox.tsx @@ -132,24 +132,28 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { // default presets { effect: PresEffect.Bounce, + direction: PresEffectDirection.Left, stiffness: 400, damping: 15, mass: 1, }, { effect: PresEffect.Fade, + direction: PresEffectDirection.Left, stiffness: 100, damping: 15, mass: 1, }, { effect: PresEffect.Flip, + direction: PresEffectDirection.Left, stiffness: 100, damping: 15, mass: 1, }, { - effect: PresEffect.Roll, + effect: PresEffect.Rotate, + direction: PresEffectDirection.Left, stiffness: 100, damping: 15, mass: 1, @@ -199,9 +203,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { @observable easeDropdownVal = 'ease'; - // @observable bezierControlPoints: { p1: number[]; p2: number[] } = { p1: [0.67, 0.2], p2: [0.37, 0.88] }; @action setBezierControlPoints = (newPoints: { p1: number[]; p2: number[] }) => { - // this.bezierControlPoints = newPoints; this.setEaseFunc(this.activeItem, `cubic-bezier(${newPoints.p1[0]}, ${newPoints.p1[1]}, ${newPoints.p2[0]}, ${newPoints.p2[1]})`); }; @@ -391,16 +393,12 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { @action customizeAnimations = async (input: string) => { - // const testInput = 'change title to Customized Slide, transition for 2.3s with fade in effect'; - // if (!this.slideToModify) return; this.setIsLoading(true); - try { const res = await getSlideTransitionSuggestions(this.animationChat); if (typeof res === 'string') { const resObj = JSON.parse(res); console.log('Parsed GPT Result ', resObj); - // this.activeItem this.setGeneratedAnimations(resObj as AnimationSettings[]); } } catch (err) { @@ -412,7 +410,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { @action customizeWithGPT = async (input: string) => { // const testInput = 'change title to Customized Slide, transition for 2.3s with fade in effect'; - // if (!this.slideToModify) return; this.setIsRecording(false); this.setIsLoading(true); @@ -436,7 +433,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { if (typeof res === 'string') { const resObj = JSON.parse(res); console.log('Parsed GPT Result ', resObj); - // this.activeItem for (let key in resObj) { if (resObj[key]) { console.log('typeof property', typeof resObj[key]); @@ -1733,25 +1729,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { valueLabelDisplay="auto" /> </div> - // <input - // type="range" - // step={step} - // min={min} - // max={max} - // value={value} - // readOnly={true} - // style={{ marginLeft: hmargin, marginRight: hmargin, width: `calc(100% - ${2 * (hmargin ?? 0)}px)`, background: SettingsManager.userColor, color: SettingsManager.userVariantColor }} - // className={`toolbar-slider ${active ? '' : 'none'}`} - // onPointerDown={e => { - // PresBox._sliderBatch = UndoManager.StartBatch('pres slider'); - // document.addEventListener('pointerup', PresBox.endBatch, true); - // e.stopPropagation(); - // }} - // onChange={e => { - // e.stopPropagation(); - // change(e.target.value); - // }} - // /> ); }; @@ -1822,14 +1799,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { Lightbox </div> </Tooltip> - {/* <Tooltip title={<div className="dash-tooltip">Transition movement style</div>}> - <div - className="ribbon-toggle" - style={{ border: `solid 1px ${SettingsManager.userColor}`, color: SettingsManager.userColor, background: activeItem.presEaseFunc === 'ease' ? SettingsManager.userVariantColor : SettingsManager.userBackgroundColor }} - onClick={() => this.updateEaseFunc(activeItem)}> - {`${StrCast(activeItem.presEaseFunc, 'ease')}`} - </div> - </Tooltip> */} </div> {[DocumentType.AUDIO, DocumentType.VID].includes(targetType as any as DocumentType) ? null : ( <> @@ -1838,14 +1807,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { <div className="ribbon-property" style={{ border: `solid 1px ${SettingsManager.userColor}` }}> <input className="presBox-input" type="number" readOnly={true} value={duration} onKeyDown={e => e.stopPropagation()} onChange={e => this.updateDurationTime(e.target.value)} /> s </div> - {/* <div className="ribbon-propertyUpDown" style={{ color: SettingsManager.userBackgroundColor, background: SettingsManager.userColor }}> - <div className="ribbon-propertyUpDownItem" onClick={() => this.updateDurationTime(String(duration), 1000)}> - <FontAwesomeIcon icon={'caret-up'} /> - </div> - <div className="ribbon-propertyUpDownItem" onClick={() => this.updateDurationTime(String(duration), -1000)}> - <FontAwesomeIcon icon={'caret-down'} /> - </div> - </div> */} </div> {PresBox.inputter('0.1', '0.1', '20', duration, targetType !== DocumentType.AUDIO, this.updateDurationTime)} <div className={'slider-headers'} style={{ display: targetType === DocumentType.AUDIO ? 'none' : 'grid' }}> @@ -2020,11 +1981,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { <div className="pres-chat"> <div className="pres-chatbox-container"> <ReactTextareaAutosize - // ref={r => (this._inputref = r)} - // minRows={1} placeholder="Describe how you would like to modify the slide properties." className="pres-chatbox" - // autoFocus={true} value={this.chatInput} onChange={e => { this.setChatInput(e.target.value); @@ -2118,9 +2076,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { setSelectedVal={val => { if (typeof val === 'string') { if (val !== 'custom') { - this.setBezierEditorVisibility(true); this.setEaseFunc(this.activeItem, val); } else { + this.setBezierEditorVisibility(true); this.setEaseFunc(this.activeItem, TIMING_DEFAULT_MAPPINGS.ease); } } @@ -2157,11 +2115,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { <div className="pres-chat"> <div className="pres-chatbox-container"> <ReactTextareaAutosize - // ref={r => (this._inputref2 = r)} - // minRows={1} placeholder="Customize prompt for effect suggestions. Leave blank for random results." className="pres-chatbox" - // autoFocus={true} value={this.animationChat} onChange={e => { this.setAnimationChat(e.target.value); @@ -2206,6 +2161,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { className="presBox-effect-container" onClick={() => { this.updateEffect(elem.effect, false); + this.updateEffectDirection(elem.direction); this.updateEffectTiming(this.activeItem, { type: SpringType.CUSTOM, stiffness: elem.stiffness, @@ -2213,7 +2169,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { mass: elem.mass, }); }}> - <SlideEffect dir={PresEffectDirection.Left as PresEffectDirection} presEffect={elem.effect as PresEffect} tension={elem.stiffness} friction={elem.damping} mass={elem.mass} infinite> + <SlideEffect dir={elem.direction as PresEffectDirection} presEffect={elem.effect as PresEffect} tension={elem.stiffness} friction={elem.damping} mass={elem.mass} infinite> <div className="presBox-effect-demo-box" style={{ backgroundColor: springPreviewColors[i] }}></div> </SlideEffect> </div> @@ -2569,23 +2525,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { /> <div>On slide change</div> </div> - {/* <div className="checkbox-container"> - <input className="presBox-checkbox" - type="checkbox" - onChange={() => activeItem.mediaStop = "afterSlide"} - checked={activeItem.mediaStop === "afterSlide"} - /> - <div className="checkbox-dropdown"> - After chosen slide - <select className="presBox-viewPicker" - style={{ opacity: activeItem.mediaStop === "afterSlide" && this.itemIndex !== this.childDocs.length - 1 ? 1 : 0.3 }} - onPointerDown={e => e.stopPropagation()} - onChange={this.mediaStopChanged} - value={mediaStopDocStr}> - {this.mediaStopSlides} - </select> - </div> - </div> */} </div> </div> </div> diff --git a/src/client/views/nodes/trails/SpringUtils.ts b/src/client/views/nodes/trails/SpringUtils.ts index 5f1c0c6a9..757f27e18 100644 --- a/src/client/views/nodes/trails/SpringUtils.ts +++ b/src/client/views/nodes/trails/SpringUtils.ts @@ -1,4 +1,4 @@ -import { PresEffect, PresMovement } from './PresEnums'; +import { PresEffect, PresEffectDirection, PresMovement } from './PresEnums'; export const springPreviewColors = ['rgb(37, 161, 255)', 'rgb(99, 37, 255)', 'rgb(182, 37, 255)', 'rgb(255, 37, 168)']; // the type of slide effect timing (spring-driven) @@ -21,6 +21,7 @@ export interface SpringSettings { export interface AnimationSettings { effect: PresEffect; + direction: PresEffectDirection; stiffness: number; damping: number; mass: number; |