More docs

This commit is contained in:
Aria Minaei 2021-09-18 16:31:05 +02:00
parent 378d9b7abf
commit d7542883f7
7 changed files with 64 additions and 9 deletions

View file

@ -4,7 +4,29 @@ Theatre.js is an animation library for high-fidelity motion graphics. It is desi
Theatre can be used both programmatically _and_ visually. Theatre can be used both programmatically _and_ visually.
Theatre works with all rendering stacks. You can use it to animate DOM elements, THREE.js objects, or any kind of JavaScript variable. You can use Theatre.js to:
* Animate 3D objects made with THREE.js or other 3D libraries
![s](https://raw.githubusercontent.com/AriaMinaei/theatre-docs/main/docs/.vuepress/public/preview-3d-short.gif)
* Animate HTML/SVG via React or other libraries
![s](https://raw.githubusercontent.com/AriaMinaei/theatre-docs/main/docs/.vuepress/public/preview-dom.gif)
* Design micro-interactions
![s](https://raw.githubusercontent.com/AriaMinaei/theatre-docs/main/docs/.vuepress/public/preview-micro-interaction.gif)
* Choreograph generative interactive art
![s](https://raw.githubusercontent.com/AriaMinaei/theatre-docs/main/docs/.vuepress/public/preview-generative.gif)
* Or animate any other JS variable
![s](https://raw.githubusercontent.com/AriaMinaei/theatre-docs/main/docs/.vuepress/public/preview-console.gif)
## Documentation and Tutorials ## Documentation and Tutorials

View file

@ -11,6 +11,6 @@ export {default as iterateAndCountTicks} from './derivations/iterateAndCountTick
export {default as iterateOver} from './derivations/iterateOver' export {default as iterateOver} from './derivations/iterateOver'
export {default as prism} from './derivations/prism/prism' export {default as prism} from './derivations/prism/prism'
export {default as pointer, getPointerParts, isPointer} from './pointer' export {default as pointer, getPointerParts, isPointer} from './pointer'
export type {Pointer} from './pointer' export type {Pointer, PointerType} from './pointer'
export {default as Ticker} from './Ticker' export {default as Ticker} from './Ticker'
export {default as PointerProxy} from './PointerProxy' export {default as PointerProxy} from './PointerProxy'

View file

@ -11,6 +11,11 @@ import {InvalidArgumentError} from '@theatre/shared/utils/errors'
import {validateName} from '@theatre/shared/utils/sanitizers' import {validateName} from '@theatre/shared/utils/sanitizers'
import userReadableTypeOfValue from '@theatre/shared/utils/userReadableTypeOfValue' import userReadableTypeOfValue from '@theatre/shared/utils/userReadableTypeOfValue'
import deepEqual from 'fast-deep-equal' import deepEqual from 'fast-deep-equal'
import type {IDerivation, PointerType} from '@theatre/dataverse'
import {isPointer} from '@theatre/dataverse'
import {isDerivation, valueDerivation} from '@theatre/dataverse'
import type {$IntentionalAny, VoidFn} from '@theatre/shared/utils/types'
import coreTicker from './coreTicker'
export {types} export {types}
/** /**
@ -32,6 +37,8 @@ export {types}
* const config = {state} // here the config contains our saved state * const config = {state} // here the config contains our saved state
* const project = getProject("a-unique-id", config) * const project = getProject("a-unique-id", config)
* ``` * ```
*
* Learn more about exporting https://docs.theatrejs.com/in-depth/#exporting
*/ */
export function getProject(id: string, config: IProjectConfig = {}): IProject { export function getProject(id: string, config: IProjectConfig = {}): IProject {
const {...restOfConfig} = config const {...restOfConfig} = config
@ -92,7 +99,7 @@ const deepValidateOnDiskState = (projectId: string, s: OnDiskState) => {
const validateProjectIdOrThrow = (value: string) => { const validateProjectIdOrThrow = (value: string) => {
if (typeof value !== 'string') { if (typeof value !== 'string') {
throw new InvalidArgumentError( throw new InvalidArgumentError(
`Argument 'name' in \`Theatre.getProject(name, ...)\` must be a string. Instead, it was ${userReadableTypeOfValue( `Argument 'projectId' in \`Theatre.getProject(projectId, ...)\` must be a string. Instead, it was ${userReadableTypeOfValue(
value, value,
)}.`, )}.`,
) )
@ -101,13 +108,36 @@ const validateProjectIdOrThrow = (value: string) => {
const idTrimmed = value.trim() const idTrimmed = value.trim()
if (idTrimmed.length !== value.length) { if (idTrimmed.length !== value.length) {
throw new InvalidArgumentError( throw new InvalidArgumentError(
`Argument 'name' in \`Theatre.getProject("${value}", ...)\` should not have surrounding whitespace.`, `Argument 'projectId' in \`Theatre.getProject("${value}", ...)\` should not have surrounding whitespace.`,
) )
} }
if (idTrimmed.length < 3) { if (idTrimmed.length < 3) {
throw new InvalidArgumentError( throw new InvalidArgumentError(
`Argument 'name' in \`Theatre.getProject("${value}", ...)\` should be at least 3 characters long.`, `Argument 'projectId' in \`Theatre.getProject("${value}", ...)\` should be at least 3 characters long.`,
)
}
}
/**
* Calls `callback` every time the pointed value of `pointer` changes.
*
* @param pointer A pointer (like `object.props.x`)
* @param callback The callback is called every time the value of pointerOrDerivation changes
* @returns An unsubscribe function
*/
export function onChange<O, P extends PointerType<O> | IDerivation<O>>(
pointer: P,
callback: (value: O) => void,
): VoidFn {
if (isPointer(pointer)) {
const derivation = valueDerivation(pointer)
return derivation.tapImmediate(coreTicker, callback as $IntentionalAny)
} else if (isDerivation(pointer)) {
return pointer.tapImmediate(coreTicker, callback as $IntentionalAny)
} else {
throw new Error(
`Called onChange(p) where p is neither a pointer nor a derivation.`,
) )
} }
} }

View file

@ -99,7 +99,7 @@ export default class Project {
`while you are using @theatre/core along with @theatre/sutdio. But since @theatre/studio ` + `while you are using @theatre/core along with @theatre/sutdio. But since @theatre/studio ` +
`is not loaded, the state of project "${id}" will be empty.\n\n` + `is not loaded, the state of project "${id}" will be empty.\n\n` +
`To fix this, you need to add @theatre/studio into the bundle and export ` + `To fix this, you need to add @theatre/studio into the bundle and export ` +
`the projet's state. Learn how to do that at https://docs.theatrejs.com/export.html`, `the projet's state. Learn how to do that at https://docs.theatrejs.com/in-depth/#exporting`,
) )
} }
}, 1000) }, 1000)

View file

@ -11,7 +11,7 @@ import type {$IntentionalAny} from '@theatre/shared/utils/types'
*/ */
export type IProjectConfig = { export type IProjectConfig = {
/** /**
* The state of the project, as [exported](https://docs.theatrejs.com/export.html) by the studio. * The state of the project, as [exported](https://docs.theatrejs.com/in-depth/#exporting) by the studio.
*/ */
state?: $IntentionalAny state?: $IntentionalAny
} }

View file

@ -65,7 +65,10 @@ const ProjectDetails: React.FC<{
This will create a JSON file with the state of your project. You can This will create a JSON file with the state of your project. You can
commit this file to your git repo and include it in your production commit this file to your git repo and include it in your production
bundle. bundle.
<a href="https://docs.theatrejs.com/export.html" target="_blank"> <a
href="https://docs.theatrejs.com/in-depth/#exporting"
target="_blank"
>
Here is a quick guide on how to export to production. Here is a quick guide on how to export to production.
</a> </a>
</ExportTooltip> </ExportTooltip>

View file

@ -106,7 +106,7 @@ const InConflict: React.FC<{
<Message> <Message>
Browser state is not based on disk state.{' '} Browser state is not based on disk state.{' '}
<a <a
href="https://docs.theatrejs.com/export.html#conflict" href="https://docs.theatrejs.com/in-depth/#exporting"
target="_blank" target="_blank"
> >
Learn more. Learn more.