diff --git a/.gitignore b/.gitignore index dbcdb89550f..d8f2d4b230a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ .DS_Store .cache -*.swp +*.sw* build firefox/ tests/coverage/ diff --git a/docs/components/animation.md b/docs/components/animation.md new file mode 100644 index 00000000000..cedfea97549 --- /dev/null +++ b/docs/components/animation.md @@ -0,0 +1,182 @@ +--- +title: Animation +type: components +layout: docs +parent_section: components +source_code: src/components/animation.js +examples: + - title: Generated Animations + src: https://glitch.com/~aframe-shooting-stars +--- + +[animationtimeline]: https://www.npmjs.com/package/aframe-animation-timeline-component + +The animation component lets us animate and tween values including: + +- Component values (e.g., `position`, `visible`) +- Component property values (e.g., `light.intensity`) + +We can also tween values directly for better performance versus going through +`.setAttribute`, such as by animating values: + +- On the `object3D` (e.g., `object3D.position.y`, `object3D.rotation.z`) +- Directly within a component (e.g., `components.material.material.color`, `components.text.material.uniforms.opacity.value`), + +For example, translating a box: + +```html + +``` + +Or orbiting a sphere in a 5-meter radius: + +```html + + + +``` + +Read more below for additional options and discovering how to properly animate +different types of values. + + + +## API + +### Properties + +| Property | Description | Default Value | Values | +| -------- | ----------- | ------------- | ------ | +| property | Property to animate. Can be a component name, a dot-delimited property of a component (e.g., `material.color`), or a plain attribute. | | | +| isRawProperty | Flag to animate an arbitrary object property outside of A-Frame components for better performance. If set to true, for example, we can set `property` to like `components.material.material.opacity`. If `property` starts with `components` or `object3D`, this will be inferred to `true`. | false | | +| from | Initial value at start of animation. If not specified, the current property value of the entity will be used (will be sampled on each animation start). It is best to specify a `from` value when possible for stability. | null | | +| to | Target value at end of animation. | null | | +| type | Right now only supports `color` for tweening `isRawProperty` color XYZ/RGB vector values. | '' | | +| delay | How long (milliseconds) to wait before starting. | 0 | | +| dir | Which dir to go from `from` to `to`. | normal | alternate, reverse | +| dur | How long (milliseconds) each cycle of the animation is. | 1000 | | +| easing | Easing function of animation. To ease in, ease out, ease in and out. | easeInQuad | See [easings](#easings) | +| elasticity | How much to bounce (higher is stronger). | 400 | | +| loop | How many times the animation should repeat. If the value is `true`, the animation will repeat infinitely. | 0 | | +| round | Whether to round values. | false | | +| startEvents | Comma-separated list of events to listen to trigger a restart and play. Animation will not autoplay if specified. `startEvents` will **restart** the animation, use `pauseEvents` to resume it. If there are other animation components on the entity animating the same property, those animations will be automatically paused to not conflict. | null | | +| pauseEvents | Comma-separated list of events to listen to trigger pause. Can be resumed with `resumeEvents`. | null | | +| resumeEvents | Comma-separated list of events to listen to trigger resume after pausing. | null | | +| autoplay | Whether or not the animation should `autoplay`. Should be specified if the animation is defined for the [`animation-timeline` component][animationtimeline]. | null | | +| enabled | If disabled, animation will stop and startEvents will not trigger animation start. | true | + +### Multiple Animations + +The component's base name is `animation`. We can attach multiple animations to +one entity by name-spacing the component with double underscores (`__`): + +```html + +``` + +### Easings + +Easings define the accelerations and speed throughout the cycle of the +animation. + +| easeIn | easeOut | easeInOut | Others | +|---------------|----------------|------------------|--------| +| easeInQuad | easeOutQuad | easeInOutQuad | linear | +| easeInCubic | easeOutCubic | easeInOutCubic | | +| easeInQuart | easeOutQuart | easeInOutQuart | | +| easeInQuint | easeOutQuint | easeInOutQuint | | +| easeInSine | easeOutSine | easeInOutSine | | +| easeInExpo | easeOutExpo | easeInOutExpo | | +| easeInCirc | easeOutCirc | easeInOutCirc | | +| easeInBack | easeOutBack | easeInOutBack | | +| easeInElastic | easeOutElastic | easeInOutElastic | | + +### Events + +| Property | Description | +| -------- | ----------- | +| animationbegin | Animation began. Event detail contains `name` of animation. | +| animationcomplete | Animation completed. Event detail contains `name` of animation. | + +### Members + +Accessed as `el.components.animation.`. + +| Member | Description | +|-----------|----------------------------| +| animation | anime.js object. | +| config | Config passed to anime.js. | + +## Animating Different Types of Values + +We'll go over different cases of animating different types of values. + +### Component Values + +We can animate a single-property component value (e.g., `property: visible`, +we'll go over booleans in a bit) or animate a property of a multi-property +component using a dot `.` as a separator (e.g., `property: light.intensity`, +`property: material.color`). + +If the property is a `vec3`, that is also supported (e.g., `property: +someComponent.vec3Value; to: 5 5 5`). + +However, animating component values this way is not the most optimal way as it +will invoke `.setAttribute` on each frame of the animation. For an animation +here or there, it won't be a big deal, but we can save time and memory by +animating values directly. + +A special note to try not to animate values of the `geometry` component as that +will recreate the geometry on each tick. Rather animate `scale` if we want to +animate the size. + +### Boolean Values + +We can "animate" boolean values where the `to` value will be applied at the end +of the animation. Like `property: visible; from: false; to: true; dur: 1`. + +### Direct Values through `object3D` and `components` + +The animation component supports animating values directly through `object3D` +or `components`. + +For example, we can animate values on `object3D` like `property: +object3D.position.z; to: 5` which will tween the entity's `object3D.position.z` +value directly without calling `.setAttribute`; it's the most direct way and +lets us animate a single axis at a time. Note, for `object3D.rotation`, degrees +are used. + +Or we can animate values by reaching into `components`. For example, rather than +animating `property: material.opacity` which would call `.setAttribute` on each +frame, we can animate the opacity value directly with `property: +components.material.material.opacity`. We use a dot-delimited path to walk the +object tree to find the value we want to animate, and the animation process +under the hood reduces down to changing a number. + +#### Direct Color Values + +We can animate three.js color values directly, but we'll need to specify `type: +color`. So rather than animating `property: material.color`, we can do +`property: components.material.material.color; type: color`. + +A note on color values, we can specify color values using hex, color names, +hsl, or rgb (e.g., `from: red; to: #FFCCAA` or `from: rgb(100, 100, 100); to: +hsl(213, 100%, 70%)`).. + +## Using anime.js Directly + +anime is a popular and powerful animation engine. The component prefers to do +just basic tweening and touches the surface of what anime can do (e.g., +timelines, motion paths, progress, seeking). If we need more animation +features, create a separate component that invokes anime.js directly. anime is +accessible via **`AFRAME.ANIME`**. + +Read through and explore the [anime.js +documentation](https://github.com/juliangarnier/anime) and +[website](https://animejs.com). + +## See Also + +- [animation-timeline component][animationtimeline] diff --git a/docs/components/cursor.md b/docs/components/cursor.md index 4b1a56910bf..fbdee711454 100644 --- a/docs/components/cursor.md +++ b/docs/components/cursor.md @@ -87,7 +87,7 @@ AFRAME.registerComponent('cursor-listener', { | downEvents | Array of additional events on the entity to *listen* to for triggering `mousedown` (e.g., `triggerdown` for vive-controls). | [] | | fuse | Whether cursor is fuse-based. | false on desktop, true on mobile | | fuseTimeout | How long to wait (in milliseconds) before triggering a fuse-based click event. | 1500 | -| rayOrigin | Where the intersection ray is cast from (i.e.,entity or mouse) | entity +| rayOrigin | Where the intersection ray is cast from (i.e.,entity or mouse). `rayOrigin: mouse` is extremely useful for VR development on a mouse and keyboard. | entity | upEvents | Array of additional events on the entity to *listen* to for triggering `mouseup` (e.g., `trackpadup` for daydream-controls). | [] | To further customize the cursor component, we configure the cursor's dependency @@ -160,23 +160,21 @@ interactions is that it requires the user to turn their head a lot. ## Adding Visual Feedback -[animation]: ../core/animations.md +[animation]: ./animation.md To add visual feedback to the cursor to show when the cursor is clicking or -fusing, we can use the [animation system][animation]. When the cursor +fusing, we can use the [animation component][animation]. When the cursor intersects the entity, it will emit an event, and the animation system will pick up event with the `begin` attribute: ```html - - - - + ``` [cursor-codepen]: https://codepen.io/Absulit/pen/WEKjqm diff --git a/docs/components/embedded.md b/docs/components/embedded.md index 0cf54a63414..840c4b959a4 100644 --- a/docs/components/embedded.md +++ b/docs/components/embedded.md @@ -32,7 +32,7 @@ a-scene { ``` -An example of an embedded scene: +An inline example of an embedded scene: @@ -44,14 +44,11 @@ An example of an embedded scene:
- - - - - - - - + + + + +
diff --git a/docs/components/material.md b/docs/components/material.md index 8a259824d87..c53da54cd4e 100644 --- a/docs/components/material.md +++ b/docs/components/material.md @@ -625,14 +625,12 @@ We then apply the component to the entity with the custom shader: ```html - - + diff --git a/docs/components/visible.md b/docs/components/visible.md index fcf558a6fcf..48ccdbb3e17 100644 --- a/docs/components/visible.md +++ b/docs/components/visible.md @@ -7,7 +7,13 @@ source_code: src/components/visible.js examples: [] --- -The visible component determines whether to render an entity. +The visible component determines whether to render an entity. If set to +`false`, then the entity will not be visible nor drawn. + +Visibility effectively applies to all children. If an entity's parent or +ancestor entity has visibility set to false, then the entity will also not be +visible nor draw. It's a common pattern to create container entities that +contain an entire group of entities that you can flip on an off with `visible`. ## Example @@ -22,18 +28,7 @@ The visible component determines whether to render an entity. | true | The entity will be rendered and visible; the default value. | | false | The entity will not be rendered nor visible. The entity will still exist in the scene. | -## Animating Visibility - -The visible value can be "animated" to delay the visibility of an entity: - -```html - - - - -``` - -## Updating Visible +## Updating Visibility [update]: ../introduction/javascript-events-and-dom-apis.md#updating-a-component-with-setattribute @@ -50,3 +45,19 @@ el.setAttribute('visible', false); Updates at the three.js level will still be reflected when doing `entityEl.getAttribute('visible');`. + +## Hiding Entity Until Texture Loaded + +[event-set]: https://github.com/ngokevin/kframe/tree/master/components/event-set + +While we can do this with, the [event-set][event-set] component, we can also do +this with the built-in animation component. Here's an example of updating +visibility on an event. + +```html + + + material="src: #myTexture" + visible="false"> +``` diff --git a/docs/core/animations.md b/docs/core/animations.md deleted file mode 100644 index 903ede06368..00000000000 --- a/docs/core/animations.md +++ /dev/null @@ -1,218 +0,0 @@ ---- -title: Animations -type: core -layout: docs -parent_section: core -order: 6 -source_code: src/core/a-animation.js -examples: [] ---- - -> Also check out the -> [aframe-animation-component](https://github.com/ngokevin/kframe/tree/master/components/animation/) - -We can add animations in A-Frame attaching an `` element as a -child of the entity to animate. - -As an introductory example, to define a 5-meter orbit on an entity about the -Y-axis that takes 10 seconds, we can offset its position and animate the -rotation of a parent entity. This animation starts with the initial rotation -about the Y-axis of 0 degrees and goes around to 360 degrees. It's defined with -a duration of 10000 milliseconds, maintains the final value on each cycle of -the animation, and loops indefinitely. - -```html - - - - -``` - - - -## Attributes - -Here is an overview of animation attributes. We'll go into more detail below. - -| Attribute | Description | Default Value | -|-----------|------------------------------------------------------------------------------------------------------------------------|----------------| -| attribute | Attribute to animate. To specify a component attribute, use `componentName.property` syntax (e.g., `light.intensity`). | rotation | -| begin | Event name to wait on before beginning animation. | '' | -| delay | Delay (in milliseconds) or event name to wait on before beginning animation. | 0 | -| direction | Direction of the animation (between `from` and `to`). One of `alternate`, `alternateReverse`, `normal`, `reverse`. | normal | -| dur | Duration in (milliseconds) of the animation. | 1000 | -| easing | Easing function of the animation. There are very many to choose from. | ease | -| end | Event name to wait on before stopping animation. | '' | -| fill | Determines effect of animation when not actively in play. One of `backwards`, `both`, `forwards`, `none`. | forwards | -| from | Starting value. | Current value. | -| repeat | Repeat count or `indefinite`. | 0 | -| to | Ending value. Must be specified. | None | - -## Animating Different Types of Properties - -A-Frame's animation system can animate different types of properties. - -### vec3 Properties - -A-Frame has standard `vec3` components (i.e., `position`, `rotation`, -and `scale`). These components consist of three factors: X, Y, and Z. We can -pass three space-delimited numbers to the `from` and `to` attributes just as we -would define them on an entity. In this case, the animation system will assume -we are animating a `vec3` value. - -For example, if we want to animate an entity going from one spot to another, we -can animate the `position` component. - -```html - - - -``` - -### Boolean Properties - -A-Frame has standard components that accept a single boolean value. Boolean -values can be "animated" as well by flipping the boolean at the end of each -animation cycle. - -For example, we can define an animation that toggles off the visibility of an -entity after 5 seconds. - -```html - - - -``` - -### Numeric Properties - -We can animate numeric attributes as well. For example, we can animate the -intensity of the light primitive. - -```html - - - -``` - -### Color Properties - -We can animate any component property that has a color type. For example, we -can animate a box from white to red. - -```html - - - -``` - -### Component Properties - -We can animate a certain property of a multi-property component. To do so, we -select the component property using the dot syntax: -`componentName.propertyName`. - -For example, to animate a cone's top radius, we can select the `radiusTop` -value with `geometry.radiusTop`. - -```html - - - -``` - -## Begin - -The `begin` attribute defines when the animation should start playing. - -This can either be a *number*, representing milliseconds to wait, or an *event -name* to wait for. For example, we can define an animation that waits 2 seconds -before scaling an entity. - -```html - - - -``` - -Or we can define an animation that waits for the parent element to trigger an -event named `fade` before fading an entity. - -```html - - - -``` - -```js -// Trigger an event to begin fading. -document.querySelector('#fading-cube').emit('fade'); -``` - -## Direction - -The `direction` attribute defines which way to animate between the starting -value and the final value. - -When we define an alternating direction, the animation will go back and forth -between the `from` and `to` values like a yo-yo. Alternating directions only -take affect when we repeat the animation. - -| Value | Description | -|-------------------|-------------------------------------------------------------------------------------------------------------| -| alternate | On even-numbered cycles, animate from `from` to `to`. On odd-numbered cycles, animation from `to` to `from` | -| alternate-reverse | On odd-numbered cycles, animate from `from` to `to`. On even-numbered cycles, animation from `to` to `from` | -| normal | Animate from `from` to `to`. | -| reverse | Animate from `to` to `from`. | - -## Easing - -The `easing` attribute defines the easing function of the animation, which -defaults to `ease`. There are too many easing functions to list, but we can -implicitly explain them. - -One possible value is `linear`. And the basic easing functions are `ease`, -`ease-in`, `ease-out`, and `ease-in-out`. - -Then there are more groups of easing functions. The above basic easing -functions prefix each group of easing functions. The groups of easing functions -are `cubic`, `quad`, `quart`, `quint`, `sine`, `expo`, `circ`, `elastic`, -`back`, and `bounce`. - -For example, the `cubic` group of easing functions would consist of -`ease-cubic`, `ease-in-cubic`, `ease-out-cubic`, `ease-in-out-cubic`. - -## Fill - -The `fill` attribute defines the effect of animation when not actively in play. -Think of `fill` as what values the animation sets on the entity *before* and/or -*after* each animation cycle. Below are the possible values for `fill` and -their effects. - -| Value | Description | -|-----------|-----------------------------------------------------------------------------------------------------------------------------------------------| -| backwards | Before the animation starts, set the starting value to the `from` value. | -| both | Combine the effects of both backwards fill and forwards fill. | -| forwards | After the animation finishes, the final value will stay at the `to` value. The default fill. | -| none | Before the animation starts, set the starting value to the initial value. After the animation finishes, reset the value to the initial value. | - -## Repeat - -The `repeat` attribute defines how often the animation repeats. We call each -repeat of the animation a cycle. Repeat can either be a number that counts down -on each animation cycle until it reaches `0` at which point the animation will -end, or we can set `repeat` to `indefinite` and the animation will loop -continuously until the animation is manually removed or stopped. - -## Events - -The `` element emits a couple of events. - -| Event Name | Description | -|----------------|-----------------------------------------------------------------------------------------------------------------------------------------| -| animationend | Emitted when the animation finishes. In case of repeats, emitted when the repeat count reaches `0`. Not emitted for indefinite repeats. | -| animationstart | Emitted immediately when the animation begins playing. | diff --git a/docs/core/entity.md b/docs/core/entity.md index 15b88c8e4ce..a8ce6e8a715 100644 --- a/docs/core/entity.md +++ b/docs/core/entity.md @@ -170,15 +170,13 @@ entity.is('selected'); // >> true ### `emit (name, detail, bubbles)` -[animation-begin]: ./animations.md#begin +[animation]: ../components/animation.md `emit` emits a custom DOM event on the entity. For example, we can emit an event to -[trigger an animation][animation-begin]: +[trigger an animation][animation]: ```js -// -// -// +// entity.emit('rotate'); ``` diff --git a/docs/guides/building-a-360-image-gallery.md b/docs/guides/building-a-360-image-gallery.md index d4eb7ab59d2..261a0ea2cc1 100644 --- a/docs/guides/building-a-360-image-gallery.md +++ b/docs/guides/building-a-360-image-gallery.md @@ -65,7 +65,7 @@ This is the starting point for our scene: [a-sky]: ../primitives/a-sky.md [ams]: ../core/asset-management-system.md -[animation-begin]: ../core/animations.md#begin +[animation-begin]: ../components/animation.md [camera]: ../primitives/a-camera.md [component]: ../core/component.md [cursor]: ../components/cursor.md diff --git a/examples/animation/aframe-logo/index.html b/examples/animation/aframe-logo/index.html index e6265e7b394..9930e5b6f98 100644 --- a/examples/animation/aframe-logo/index.html +++ b/examples/animation/aframe-logo/index.html @@ -9,135 +9,96 @@ - + + - - + - - + + diff --git a/examples/animation/arms/index.html b/examples/animation/arms/index.html index 06a131e2ffc..0d6a4a4d295 100644 --- a/examples/animation/arms/index.html +++ b/examples/animation/arms/index.html @@ -11,55 +11,47 @@ + + - - + - - + - - + - - + - - + - - - + - - - - + @@ -99,7 +91,6 @@ - @@ -113,37 +104,29 @@ - - - - - + + - - + - - + - - + - - + - @@ -152,38 +135,29 @@ - - - - - - + + - - + - - + - - + - - + - @@ -192,37 +166,30 @@ - - + - - + - - + - - + - - + - - + - @@ -230,34 +197,28 @@ - - + - - + - - + - - + - - + - @@ -265,28 +226,23 @@ - - + - - + - - + - - + - - + @@ -298,12 +254,10 @@ - - + diff --git a/examples/animation/generic-logo/index.html b/examples/animation/generic-logo/index.html index 135d7eb7cc5..bfc8ce1f5f1 100644 --- a/examples/animation/generic-logo/index.html +++ b/examples/animation/generic-logo/index.html @@ -9,8 +9,7 @@ - + @@ -18,14 +17,12 @@ -