Coder Social home page Coder Social logo

theatre-js / theatre Goto Github PK

View Code? Open in Web Editor NEW
10.7K 115.0 333.0 26.98 MB

Motion design editor for the web

Home Page: https://www.theatrejs.com

License: Apache License 2.0

JavaScript 0.65% Shell 0.01% TypeScript 82.53% HTML 16.75% CSS 0.06%
animation threejs generative-art motion-design r3f devtools

theatre's Introduction

Theatre.jsTheatre.js

Motion Design, for the web

GitHub branch checks state Join us on Discord Follow Theatre.js on Twitter Watch on YouTube

โœจ Update: Theatre.js 1.0 is around the corner. We have temporarily moved development to a private repo so we can iterate faster. We'll push our work back to this public repo soon. Terms and license will remain OSS, as before. (Also, we're hiring โ€“ join the core team!).

Theatre.js is an animation library for high-fidelity motion graphics. It is designed to help you express detailed animation, enabling you to create intricate movement, and convey nuance.

Theatre.js can be used both programmatically and visually.


You can use Theatre.js to:

  • Animate 3D objects made with THREE.js or other 3D libraries

    s

    Art by drei.lu

  • Animate HTML/SVG via React or other libraries

    s

  • Design micro-interactions

    s

  • Choreograph generative interactive art

    s

  • Or animate any other JS variable

    s

Documentation and Tutorials

The docs are at theatrejs.com/docs:

Community and support

Join our friendly community on Discord, follow the updates on twitter or write us an email.

Development and contributing

If you want to change the source of Theatre, have a look at the guide here.

Proposing fixes and changes

You can always get help with bugfixes or discuss changes with our community on Discord, or directly open an issue on Github.

Helping with outstanding issues

Feel free to chime in on any issue. We have also labeled some issues with "Help wanted" or "Good first issue" if you're just getting started with the codebase.

Helping with documentation

The documentation website's repo is here.

Writing/recording tutorials

If you make tutorials or video content about Theatre, tell us to showcase it here :)

License

Your use of Theatre.js is governed under the Apache License Version 2.0:

  • Theatre's core (@theatre/core) is released under the Apache License. Same goes for most packages in this repository.
  • The studio (@theatre/studio) is released under the AGPL 3.0 License. This is the package that you use to edit your animations, setup your scenes, etc. You only use the studio during design/development. Your project's final bundle only includes @theatre/core, so only the Apache License applies.

theatre's People

Contributors

0xflotus avatar ad2018 avatar akre54 avatar andrewprifer avatar ariaminaei avatar clementroche avatar colelawrence avatar cory-glooh avatar danvoyce avatar dependabot[bot] avatar donmccurdy avatar eltociear avatar fulopkovacs avatar jmyrland avatar joaogsleite avatar juniorxsound avatar mslooten avatar nksaraf avatar palehazy avatar steam0r avatar timohausmann avatar tomorrowevening avatar vezwork avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

theatre's Issues

Need a helpful warning if studio is imported but no initialized

Since tree-shaking in different build systems is not bullet proof, there are situations where the user intends for @theatre/studio to not be included in the bundle but it still ends up in there. We can help the user avoid this situation by emitting a warning if the studio is imported but studio.initialize() is not called within a time period.

Thanks @RuiOrey for the report :)

Eslint not recognising unused Keyword import

When the following is added to a file within theatre/studio and Keyframe is not used within that file, eslint does not pick this up

import type {Keyframe} from '@theatre/core/projects/store/types/SheetState_Historic'

A very minor issue, but never the less would be nice to understand what's causing this and if it's happening anywhere else.

We're currently using eslint-plugin-unused-imports: 1.1.5 and I've also replicated this issue with version 2.0.0

Add SkinnedMesh as an editable type

Hi, it would be great to have SkinnedMesh as an editable type, so that models with skeletal animations can be played/edited. Currently I believe only mesh is exposed.

Thanks so much!

Feature request: Copy+Paste keyframes

Description

It would be great to be able to copy and paste keyframes, since it's a feature that I use quite a lot when I create loops (and some other times too).

Implementation

UX-wise the easiest solution might be adding new items (Copy Keyframe, Paste Keyframe) to the context menu that appears when the user right clicks on a keyframe in the sequence editor (right now ("@theatre/studio": "0.4.7") it's just contains one item: Delete Keyframe).

image

More accurate transport controls in sequences

Currently, trying to time events accurately to music is tricky, as it's very hard to correctly place the playhead.

  • Add hotkeys that move the playhead by set time intervals (e.g. 100ms, 500ms, 1s)
  • Add a way to manually enter a timestamp to place the playhead, e.g. by double clicking the timeline legend.
  • Preview the sound while moving the playhead/scrubbing the timeline in a sequence, as e.g. Premiere or DAW software allow you to.
  • Snap the playhead to beats or measures while holding a certain hotkey. This would depend on a preconfigured BPM/beat level value, maybe even an event that signals changes in these values - this would be especially useful for music that changes in BPM. Measures could be visualized by vertical lines in the sequence panel. If a BPM/level is configured, hotkeys could be added that move the playhead between beats.

These features will make it far easier to create timelines that need to sync up to music accurately.

Lottie

Nice tool! Can animations created in Theatre.js also be exported as Lottie animations so that they can be used in apps?

Improve keyframe selection

Opening this issue since I've heard it from multiple sources now, keyframe selection is currently not as ideal as it probably could be.

Key problems right now:

  • Keyframes can only be selected through box selection, not individually
  • Box selection is hidden behind a modifier key
  • Box selection cannot be initiated anywhere in the dope sheet area, only on a track

Suggestions for improvements:

  • Display available modifiers in a status bar (#69)
  • Have separate drag areas for the sequence position and the box selection (many examples of this in other software)
  • Fix the box selection start area

Expose playback state changes

Relevant discussion here.

Summary: Expose changes to the playback state of a sequence, including changes to its position, and its playing/paused state. This allows creating a custom UI for scrubbing through the timeline, play/pausing the animation, etc.

API sketch:

import {onChange} from '@theatre/core'

onChange(sequence.props.position, (newPos) => {console.log('pos: ' + newPos)})

sequence.position = 10 // logs "pos: 10"
import {onChange} from '@theatre/core'

onChange(sequence.props.playState, (playState) => {console.log(playState)})

sequence.play() // logs {state: 'playing'} 
// 10s later, logs {state: 'paused'}

Feature request: Select multiple keyframes with the mouse in the Sequence Editor

Description

There are times when I want to move multiple keyframes at once in the sequence editor. These times I instinctively try to make a rectangle selection with the mouse, which moves the playhead here.

Implementation

Here's a rough sketch of the rectangle selection tool to illustrate my point:

select-multiple-frames

I haven't thought about how to resolve the conflict between moving the playhead and the multiple keyframe selection tool yet.

Need sandbox.io example

Could you provide a working sandbox for this project on sandbox.io as an example for integration?

Use SVG images?

It looks like a lot of the images for the UI could easily be converted to SVG, which would make them show up clearly on any display pixel density and also decrease load time by a good bit (since svgs are xml files and can be minified and gzipped, or inlined)

obj.onValuesChange not triggered if running project from core.getProject();

Hello,

first of all, i have to say that theaterjs is a pretty need piece of software imo. i'm not really into es6, but managed to wrap threejs/studio an integrate it into an angular application pretty easy. The studio part works except of some self-inflicted css fuckery flawless. :)

I'm stuck at the moment to play() a persisted project. No matter if i'm using the theater localstorage implementation nor if i try to load a json project exported from studio.createContentOfSaveFile(projectUuid);. I will atttach an excample json, looks good to me, but i do not get how the revision history works, maybe it's part of the problem. I digged into the js code a bit and learned that project.ready.then(()=>{}) will never resolve if studio is imported. I'm now able to run sheet.sequence.play() ->

//resolving persisted sheet
const [sheet, setSheet] = useState(project.sheet('Scene', 'default'));

//start sequence after component mounted
  useEffect(() => {
    project.ready.then(() => {
      sheet.sequence.play().then((finished: boolean) => {
        if (finished) {
          console.log('Playback finished');
        } else {
          console.log('Playback interrupted');
        }
      });
    });
  });

The squence plays and also logs when the playback finishes. What i'm trying to do in the first place to use a bunch of React.FC which are coupled to SequenceObjects, which works works in studio mode. but if i'm reloading the objects from the persistent sequence and listen to subscribe to onValuesChange on these objects, the event is emmited once, and neveer again.
Maybe somebody has an idea what could make this work. Here some code ->

//resolving the old sequence objects
const obj: ISheetObject<EditorElementProps> = sheet.object(curDef.id, EditorElementDefaultPropeties);

//reinitialzing the linked component
    if (curDef.type === 'image') {
      return <Image
        id={curDef.id}
        key={'c' + curDef.id}
        sheet={curDef.sheet}
        payload={curDef.payload}
        selectedObject={curDef.selectedObject}
        rotation={0}
        CurState={null}
        obj={obj}/>;
    } 
    
  //linking 
 const [style, setSyle] = useState<EditorElementStyle>(obj.value);
 
//subscribing to value change
    useLayoutEffect(() => {
      const unsubscribeFromChanges = curState.childObj.onValuesChange((newValues) => {
        setSyle(newValues);
        Object.assign(moveable.props, [moveable.props, {left: newValues.x}]);
        moveable.updateRect();
      });
    }, []);

state.json -> https://gist.github.com/my5t3ry/c060d339bc7e13a29fc9fd65d776e80e#file-state-json

thank you : )

Theatre.js runs faster in development with studio UI open than in production

On my current three.js project I've noticed a drastic drop in FPS when closing the studio UI.
I'm experimenting the same poor performance using a built version without loading the studio.

Here is a short video showing the FPS drop when closing the UI and the FPS rising again after opening it.

theatredebug.mp4

I assumed it may be something related to my project so I tried to recreate the issue in a minimal reproduction example.

I forked a previous theater.js example and made this
https://codesandbox.io/s/theatre-js-0-4-7-perf-difference-with-without-studio-pgudj?file=/src/index.js

You'll notice that if you open the UI, the animation will run better, the 4000ms setInterval run correctly etc while when the studio is closed the animation is less smooth, the setInterval doesn't seem to trigger anymore etc

On my project I'm not even able to run the performance debug tool when I close the studio UI.

I'm not sure where to look at or what other informations I could give to figure out where this is coming from.
Let me know if you have questions / need additional informations.

edit : here I have the same issue and I removed everything related to @theatre/studio
https://codesandbox.io/s/theatre-js-0-4-7-perf-difference-when-no-studio-sjgob?file=/src/index.js

edit2 : I can reproduce it with latest Chrome, Firefox, Edge on windows 10
Chrome version 96.0.4664.110 (Build officiel) (64 bits)
Edge Version 96.0.1054.62 (Official build) (64-bit)
Firefox Version 95.0.2

Studio - mousewheel+shift on chrome windows always zooms out

Hi, thanks for the amazing library, it is being ultra useful.
I'm facing an issue:

  • using the mousewheel + shift on the studio timeline seems to always zoom out

Was able to circumvent this by @AriaMinaei advice of dragging the lower scrollbar to scale and for now is good to go for me.
But anyway here is the bug report.
Thanks!

Sequencing of stringLiterals (string-based state)

Hey! And thanks for making this awesome framework ๐Ÿ‘๐Ÿ‘

As of now, sequencing of string literals does not seem to be supported. It would be nice to have the option to sequence between the given values to the string literal.

Consider the following example:

const dinoStates = ['idle', 'scared', 'run'];

const Dino = ({ sheet }) => {
  const obj = sheet.object('Dino', {
    y: t.number(0),
    stateIndex: t.number(0, { range: [0, dinoStates.length], nudgeMultiplier: 1 }),
  });

  const [dinoState, setDinoState] = useState({
    y: 0,
    state: 'idle',
  });

  useLayoutEffect(() => {
    return obj.onValuesChange(({ y, stateIndex }) => {
      setDinoState({
        y,
        state: y < 0 ? 'jump' : dinoStates[Math.round(stateIndex)],
      });
    });
  }, [obj]);
  
  // ... etc ...

Instead of relying on the stateIndex above, if sequencing was supported, I could simplify the example above as:

const Dino = ({ sheet }) => {
  const obj = sheet.object('Dino', {
    y: t.number(0),
    // ๐Ÿ‘‡ explicit mapping of state as a stringLiteral type, with given values (instead of a "stateIndex")
    state: t.stringLiteral('idle', { idle: 'Idle', run: 'Run', jump: 'Jump', scared: 'Scared' }),
  });

  const [dinoState, setDinoState] = useState({
    y: 0,
    state: 'idle',
  });

  useLayoutEffect(() => {
    return obj.onValuesChange(({ y, state}) => {
      setDinoState({
        y,
        state: y < 0 ? 'jump' : state, // ๐Ÿ‘ˆ no need for a lookup based on an index
      });
    });
  }, [obj]);
  
  // ... etc ...

Support labeled frames and/or framegroups

Hi, this is a transcription of part of a discord conversation on theatrejs channel, moved here by suggestion of @AriaMinaei .

Basically I'm using the timeline for scrollable website transitions...
so labelling a frame group would probably be the most flexible (it would be possible to name either one frame or several ones) to work with that, instead of having to take note of individual time frame for each transition.
On Flash at least and very probably on other editors, there was an ability to name a keyframe or a range of keyframes.

image

Having that, the usage in terms of play or some sort of playToPosition(frame time or frame name) api could be something like the following: it would nice to be to be able to say "go to that frame group" either jump there instantaneously or playing from the current sequence position.
It could diverge slightly if when the play is triggered was from a frame before or after that frame group

  • if I was on a frame before the frame group it would play until the beginning of the framegroup,
  • if the current position was after, it could play to the end of the framegroup)...

Other parameter for that would be either stop on hitting the framegroup or also playing it through.

well I guess this might sound confusing but feel free to ask me any clarifications

Great work!

Status

Hi guys.
The project was terminated?

Refactor the data server module to another package

The current data server module that runs on nodejs is buggy and gets slow in big projects.

For now, we can just separate it from theatrejs and put it in another package and fix it there. The temporary fix would be to make it cache the data file and not read it from disk every time the client requests to read/update data.

That'll probably be enough for theatrejs-0.1, and for later releases we can focus on creating a real data structure for timeline data.

Clamp numerical ranges

Would be nice to have this kind of flexible behaviour for ranges of numerical values:

  1. Clamp numerical ranges on drag
  2. Allow input of values out of range, when entering numbers from keyboard.
    • Would allow for better UX for designers or anybody figuring out perfect settings
  1. would still allow developer to override values occasionally.

`NODE_ENV` set to production disables sequence timeline and ability to edit keyframes

What?

When building a project that uses the studio npm package - and NODE_ENV is set to production the sequence pane (timeline) doesn't show up and keyframes become un-editable

Steps to reproduce

  • Create a new project with create-react-app and add @theathre/core / @theathre/studio
  • Run build command
  • Serve the built project, no timeline appears and the properties become un-editable
  • (Animations still play if I hit the space bar with the animated object selected - but sequence editor does not show / keyframes are not editable)

Additional context

When NODE_ENV is set to development this is what shows

dev

When NODE_ENV is set to production this is what shows

prd

Feature request: Collapse object properties in the Sequence Editor

Description

Sometimes the sequence editor becomes a bit crowded so it would be nice to have an option to hide the information that the user currently does not have to see. (If this feature exists, then I'm sorry, I just couldn't find it. ๐Ÿ˜… )

Implementation

Maybe clicking on the caret next to the name of the object could hide its properties? Here's a rough sketch about what I have in mind (the poperties of the first item, left arm is collapsed on the picture):
image

Link to demo

Hi,
the link to demo, links to demo of griddify.

CommonJS build breaks with NextJS

If I try to use theatre on NextJS I randomly get following error:

Error [ERR_REQUIRE_ESM]: require() of ES Module /.../node_modules/lodash-es/get.js from /.../node_modules/@theatre/dataverse/dist/index.js not supported.
Instead change the require of get.js in /.../node_modules/@theatre/dataverse/dist/index.js to a dynamic import() which is available in all CommonJS modules.

The error happened to other developers in my company, and with a different setup of NextJS.

If I understand right, lodash-es is an ES module library and theatre output is a CommonJS build. So there is a clash between commonjs and esm?

I suppose a solution could be to use type="module" instead of type="commonjs"? Or change the configuration of the compiler to generates dynamic import() instead of require() ?

Is there any reason why you chose CommonJS instead of an ESM build?

FYI we use lodash-es as a dependency in our project

Ability to select a predefined easing between keyframes (e.g. 'linear')

Feature request based on this thread.

The default easing between two keyframes is by default set to ease-in-out after inserting a new keyframe. This is fine for most cases, but in some cases it might be useful to provide a way to select another easing between to keyframes, like linear.

E.g. when right-clicking the easing-curve between 2 keyframes, it would be nice to present a menu of predefined easing-curves to provide a quick way to set a curve without having to manually adjust the handles.

The prime example for this, is trying to get a perfectly linear curve between two keyframes. Today, if the keyframes are spread far apart, it is quite tricky to get the curve perfectly linear. One workaround is to adjust the state.json manually.

It would be nice to support a predefined set of easing-curves, like how css have a set of predefined easing functions:

  • linear [cubic-bezier(0.0, 0.0, 1.0, 1.0)]
  • ease [cubic-bezier(0.25, 0.1, 0.25, 1.0)]
  • ease-in [cubic-bezier(0.42, 0.0, 1.0, 1.0)]
  • ease-in-out [cubic-bezier(0.42, 0.0, 0.58, 1.0)]
  • ease-out [cubic-bezier(0.0, 0.0, 0.58, 1.0)]

Add FFMPEG Rendering Module to Theatre.js

Based off of @mrdoob's project Frame.js there is a way to render out <canvas /> elements in the browser. It could be nice to add this same render functionality to Theatre.js. FFMPEG is loaded here and I think it can also be loaded as an ES6 module. The render logic can be found here.

I've actually already rigged this up in my own personal project. If you have an idea of where or how this could be implemented, I'd be happy to contribute and make a PR for it.

Awesome project!

How to use it?

Could you also put few notes on how to use use/run theaterjs?

Studio: shift + mousewheel to pan the sequence is not synced

Mentioned on, and probably related to #19

When using shift + scroll in the sequence editor of the studio, the sequence pans left/right based on the scroll direction.

After scrolling (in either the keyframes-window or easing-window), the windows and scrollbar is out of sync:
fbsOYFf9Zy

failed to run example

First of all, the theatre/examples/dom-cra/src/index.js doesnt have a import app statement which render an error, I'm wondering if this example has been tested ever. And here is errors after correcting the issue:

Error: t.compound() expects an object, like: {x: 10}. null given.
sanitizeCompoundProps
src/propTypes/internals.ts:87
  84 | const sanitizedProps: IValidCompoundProps = {}
  85 | if (process.env.NODE_ENV !== 'production') {
  86 |   if (typeof props !== 'object' || !props) {
> 87 |     throw new InvalidArgumentError(
     | ^  88 |       `t.compound() expects an object, like: {x: 10}. ${userReadableTypeOfValue(
  89 |         props,
  90 |       )} given.`,
View compiled
compound
src/propTypes/index.ts:82
  79 | validateCommonOpts('t.compound(props, opts)', opts)
  80 | return {
  81 |   type: 'compound',
> 82 |   props: sanitizeCompoundProps(props),
     | ^  83 |   valueType: null as $IntentionalAny,
  84 |   [propTypeSymbol]: 'TheatrePropType',
  85 |   label: opts?.label,
View compiled
TheatreSheet.object
src/sheets/TheatreSheet.ts:121
  118 | 
  119 |   return existingObject.publicApi as $IntentionalAny
  120 | } else {
> 121 |   const sanitizedConfig = compound(config)
      | ^  122 |   const object = internal.createObject(
  123 |     sanitizedPath,
  124 |     nativeObject,
View compiled
Box
src/App.js:14
  11 | 
  12 | const Box = ({id, sheet, selectedObject}) => {
  13 |     // This is cheap to call and always returns the same value, so no need for useMemo()
> 14 |   const obj = sheet.object(id, null, boxObjectConfig)
  15 | 
  16 |   const isSelected = selectedObject === obj
  17 | 

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.