Skip to content

Commit

Permalink
[orx-keyframer] Add envelopes, remove repetitions
Browse files Browse the repository at this point in the history
  • Loading branch information
edwinRNDR committed Jan 9, 2021
1 parent 3e23d77 commit 829e0bb
Show file tree
Hide file tree
Showing 10 changed files with 189 additions and 165 deletions.
165 changes: 111 additions & 54 deletions orx-keyframer/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# orx-keyframer

Create animated timelines by specifying properties and times in keyframes,
then play it back at any speed (even backwards) automatically interpolating properties.
Save, load, use mathematical expressions and callbacks. Powerful and highly reusable.
Create animated timelines by specifying properties and times in keyframes, then play it back at any speed (even
backwards) automatically interpolating properties. Save, load, use mathematical expressions and callbacks. Powerful and
highly reusable.

What this allows you to do:

Expand Down Expand Up @@ -50,7 +50,7 @@ What this allows you to do:
"radius": {
"value": 50.0,
"easing": "linear"
}
}
}
]
```
Expand All @@ -77,95 +77,152 @@ extend {
drawer.circle(animation.position, animation.radius)
}
```

## Easing

All the easing functions of orx-easing are available

- linear
- back-in
- back-out
- back-in-out
- bounce-in
- bounce-out
- bounce-in-out
- circ-in
- circ-out
- circ-in-out
- cubic-in
- cubic-out
- cubic-in-out
- elastic-in
- elastic-out
- elastic-in-out
- expo-in
- expo-out
- expo-in-out
- quad-in
- quad-out
- quad-in-out
- quart-in
- quart-out
- quart-in-out
- quint-in
- quint-out
- quint-in-out
- sine-in
- sine-out
- sine-in-out
- one
- zero
All the easing functions of orx-easing are available

- linear
- back-in
- back-out
- back-in-out
- bounce-in
- bounce-out
- bounce-in-out
- circ-in
- circ-out
- circ-in-out
- cubic-in
- cubic-out
- cubic-in-out
- elastic-in
- elastic-out
- elastic-in-out
- expo-in
- expo-out
- expo-in-out
- quad-in
- quad-out
- quad-in-out
- quart-in
- quart-out
- quart-in-out
- quint-in
- quint-out
- quint-in-out
- sine-in
- sine-out
- sine-in-out
- one
- zero

## More expressive interface

orx-keyframer has two ways of programming key frames. The first is the `"x": <number>` style we have seen before. The
second way uses a dictionary instead of a number value.

For example:

```json
[
{
"time": 0.0,
"x": 320.0,
"y": 240.0
},
{
"time": 10.0,
"easing": "cubic-out",
"x": {
"easing": "cubic-in-out",
"value": 0.0
},
"y": {
"duration": -5.0,
"easing": "cubic-in",
"value": 0.0
}
},
{
"time": 20.0,
"x": 640.0,
"y": 480.0,
"easing": "cubic-in-out"
}
]
```

## Advanced features
Inside the value dictionary one can set `value`, `easing`, `duration` and `envelope`.

orx-keyframer uses two file formats. A `SIMPLE` format and a `FULL` format. For reference check the [example full format .json](src/demo/resources/demo-full-01.json) and the [example program](src/demo/kotlin/DemoFull01.kt).
The full format adds a `parameters` block and a `prototypes` block.
* `value` the target value, required value
* `easing` easing method that overrides the key's easing method, optional value
* `duration` an optional duration for the animation, set to `0` to jump from the previous
value to the new value, a negative value will start the interpolation before `time`. A positive value
wil start the interpolation at `time` and end at `time + duration`
* `envelope` optional 2-point envelope that modifies the playback of the animation. The default envelope is
`[0.0, 1.0]`. Reverse playback is achieved by supplying `[1.0, 0.0]`. To start the animation later try `[0.1, 1.0]`,
to end the animation earlier try `[0.0, 0.9]`

## Advanced features

[Repeats](src/demo/resources/demo-simple-repetitions-01.json), simple key repeating mechanism
orx-keyframer uses two file formats. A `SIMPLE` format and a `FULL` format. For reference check
the [example full format .json](src/demo/resources/demo-full-01.json) and
the [example program](src/demo/kotlin/DemoFull01.kt). The full format adds a `parameters` block and a `prototypes`
block.

[Expressions](src/demo/resources/demo-simple-expressions-01.json), expression mechanism. Currently uses values `r` to indicate repeat index and `t` the last used key time, `v` the last used value (for the animated attribute).
[Expressions](src/demo/resources/demo-simple-expressions-01.json), expression mechanism. Currently uses values `r` to
indicate repeat index and `t` the last used key time, `v` the last used value (for the animated attribute).

Supported functions in expressions:
- `min(x, y)`, `max(x, y)`
- `cos(x)`, `sin(x)`, `acos(x)`, `asin(x)`, `tan(x)`, `atan(x)`, `atan2(y, x)`
- `abs(x)`, `saturate(x)`
- `degrees(x)`, `radians(x)`
- `pow(x,y)`, `sqrt(x)`, `exp(x)`
- `mix(left, right, x)`
- `smoothstep(t0, t1, x)`
- `map(leftBefore, rightBefore, leftAfter, rightAfter, x)`
- `random()`, `random(min, max)`


- `min(x, y)`, `max(x, y)`
- `cos(x)`, `sin(x)`, `acos(x)`, `asin(x)`, `tan(x)`, `atan(x)`, `atan2(y, x)`
- `abs(x)`, `saturate(x)`
- `degrees(x)`, `radians(x)`
- `pow(x, y)`, `sqrt(x)`, `exp(x)`
- `mix(left, right, x)`
- `smoothstep(t0, t1, x)`
- `map(leftBefore, rightBefore, leftAfter, rightAfter, x)`
- `random()`, `random(min, max)`

[Parameters and prototypes](src/demo/resources/demo-full-01.json)

<!-- __demos__ -->

## Demos

### DemoFull01

[source code](src/demo/kotlin/DemoFull01.kt)

![DemoFull01Kt](https://raw.githubusercontent.com/openrndr/orx/media/orx-keyframer/images/DemoFull01Kt.png)

### DemoScrub01

[source code](src/demo/kotlin/DemoScrub01.kt)

![DemoScrub01Kt](https://raw.githubusercontent.com/openrndr/orx/media/orx-keyframer/images/DemoScrub01Kt.png)

### DemoSimple01

[source code](src/demo/kotlin/DemoSimple01.kt)

![DemoSimple01Kt](https://raw.githubusercontent.com/openrndr/orx/media/orx-keyframer/images/DemoSimple01Kt.png)

### DemoSimple02

[source code](src/demo/kotlin/DemoSimple02.kt)

![DemoSimple02Kt](https://raw.githubusercontent.com/openrndr/orx/media/orx-keyframer/images/DemoSimple02Kt.png)

### DemoSimpleExpressions01

[source code](src/demo/kotlin/DemoSimpleExpressions01.kt)

![DemoSimpleExpressions01Kt](https://raw.githubusercontent.com/openrndr/orx/media/orx-keyframer/images/DemoSimpleExpressions01Kt.png)

### DemoSimpleRepetitions01

[source code](src/demo/kotlin/DemoSimpleRepetitions01.kt)

![DemoSimpleRepetitions01Kt](https://raw.githubusercontent.com/openrndr/orx/media/orx-keyframer/images/DemoSimpleRepetitions01Kt.png)
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,17 @@ fun main() = application {
program {
class Animation: Keyframer() {
val position by Vector2Channel(arrayOf("x", "y"))
val radius by DoubleChannel("x")
}
val animation = Animation()
animation.loadFromJson(URL(resourceUrl("/demo-simple-repetitions-01.json")))
animation.loadFromJson(URL(resourceUrl("/demo-envelope-01.json")))
if (System.getProperty("takeScreenshot") == "true") {
extend(SingleScreenshot()) {
this.outputFile = System.getProperty("screenshotPath")
}
}
extend {
animation(seconds)
drawer.circle(animation.position, animation.radius)
drawer.circle(animation.position, 100.0)
}
}
}
25 changes: 25 additions & 0 deletions orx-keyframer/src/demo/resources/demo-envelope-01.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
[
{
"time": 0.0,
"x": 320.0,
"y": 240.0
},
{
"time": 10.0,
"easing": "cubic-in-out",
"x": {
"envelope": [0.5, 1.0],
"value": 0.0
},
"y": {
"envelope": [0.4, 1.0],
"value": 0.0
}
},
{
"time": 20.0,
"x": 640.0,
"y": 480.0,
"easing": "cubic-in-out"
}
]
30 changes: 0 additions & 30 deletions orx-keyframer/src/demo/resources/demo-simple-repetitions-01.json

This file was deleted.

4 changes: 2 additions & 2 deletions orx-keyframer/src/main/antlr/KeyLangLexer.g4
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ DECIMAL : 'Decimal';
STRING : 'String';

// Identifiers
ID : [_]*[a-zA-Z][A-Za-z0-9_]* ;
FUNCTION_ID : [_]*[a-z][A-Za-z0-9_]* ;
ID : [$_]*[a-zA-Z][A-Za-z0-9_]* ;
FUNCTION_ID : [$_]*[a-z][A-Za-z0-9_]* ;

// Literals

Expand Down
18 changes: 3 additions & 15 deletions orx-keyframer/src/main/kotlin/Expressions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ package org.openrndr.extra.keyframer
import org.antlr.v4.runtime.*
import org.antlr.v4.runtime.tree.ParseTreeWalker
import org.antlr.v4.runtime.tree.TerminalNode
import org.openrndr.extra.keyframer.antlr.*
import org.openrndr.extra.keyframer.antlr.KeyLangLexer
import org.openrndr.extra.keyframer.antlr.KeyLangParser
import org.openrndr.extra.keyframer.antlr.KeyLangParserBaseListener
import org.openrndr.extra.noise.uniform
import org.openrndr.math.*
import java.util.*
Expand Down Expand Up @@ -357,20 +359,6 @@ fun evaluateExpression(
functions: FunctionExtensions = FunctionExtensions.EMPTY
): Double? {
val lexer = KeyLangLexer(CharStreams.fromString(input))
//
// lexer.removeErrorListeners()
// lexer.addErrorListener(object : BaseErrorListener() {
// override fun syntaxError(
// recognizer: Recognizer<*, *>?,
// offendingSymbol: Any?,
// line: Int,
// charPositionInLine: Int,
// msg: String?,
// e: RecognitionException?
// ) {
// println("syntax error!")
// }
// })
val parser = KeyLangParser(CommonTokenStream(lexer))
parser.removeErrorListeners()
parser.addErrorListener(object : BaseErrorListener() {
Expand Down
Loading

0 comments on commit 829e0bb

Please sign in to comment.