Skip to content

Commit 733a8ce

Browse files
[Feat/Fix] Easing snapshots (#4)
* create snapshots folder, but ignore its contents * script to generate snapshots of easing plots * fix all broken easings * update readme
1 parent 0e5a555 commit 733a8ce

File tree

5 files changed

+64
-12
lines changed

5 files changed

+64
-12
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ phpunit.xml
77
phpstan.neon
88
testbench.yaml
99
vendor
10+
tests/Snapshots/*.png

README.md

+14
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,20 @@ $x = (new Tween())
5959
composer test
6060
```
6161

62+
### Visual Snapshot Testing
63+
To generate plots of all `Ease` methods, from the project root, run
64+
```bash
65+
./scripts/generateSnapshots
66+
```
67+
The 256x256 PNGs will be generated in the `tests/Snapshots` directory.
68+
These snapshots will be ignored by git, but allow visual inspection of the plots to
69+
compare against known good sources, like [Easings.net](https://easings.net).
70+
71+
> **Note** The `scripts` directory _may_ need to have its permissions changed to allow script execution
72+
```bash
73+
chmod -R 777 ./scripts
74+
```
75+
6276
## Changelog
6377

6478
Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

scripts/generateSnapshots

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#!/usr/bin/env php
2+
<?php
3+
4+
require_once __DIR__.'/../vendor/autoload.php';
5+
6+
use ProjektGopher\FFMpegTween\Enums\Ease as AvailableEasings;
7+
use ProjektGopher\FFMpegTween\Ease;
8+
9+
echo 'starting... (fail fast)'.PHP_EOL;
10+
11+
$time = "X/H";
12+
13+
foreach (AvailableEasings::cases() as $ease) {
14+
echo "Generating snapshot for {$ease->value} easing...".PHP_EOL;
15+
$easeMultiplier = Ease::{$ease->value}($time);
16+
17+
$input = "-f lavfi -i \"color=c=black:s=256x256:d=1\"";
18+
$margin = '28';
19+
$filter = "-vf \"geq=if(eq(round((H-2*{$margin})*({$easeMultiplier}))\,H-Y-{$margin})\,128\,0):128:128\"";
20+
$out = "-frames:v 1 -update 1 tests/Snapshots/{$ease->value}.png";
21+
$redirect = '2>&1'; // redirect stderr to stdout
22+
23+
$cmd = "ffmpeg -y {$input} {$filter} {$out} {$redirect}";
24+
25+
(array) $output = [];
26+
(int) $code = 0;
27+
exec($cmd, $output, $code);
28+
29+
if ($code !== 0) {
30+
echo PHP_EOL;
31+
echo "Failed to generate snapshot for {$ease->value} easing.".PHP_EOL;
32+
echo "Output: ".PHP_EOL;
33+
echo implode(PHP_EOL, $output).PHP_EOL;
34+
exit(1);
35+
}
36+
}

src/Ease.php

+13-12
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,8 @@ public static function EaseInOutExpo(string $time): string
111111
$firstExp = "pow(2\\,20*({$time})-10)/2";
112112
$secondExp = "(2-pow(2\\,-20*({$time})+10))/2";
113113

114-
return "if(eq(({$time})\\,0)\\,0\\,(if(eq(({$time})\\,1)\\,1\\,if(lt(({$time})\\,0.5)\\,pow(2\\,20*({$firstExp})-10)/2)\\,(2-pow(2\\,-20*({$secondExp})+10))/2)))";
114+
// We have to set the return value for 0 and 1 explicitly as we lose accuracy at the 4th decimal place.
115+
return "if(eq(({$time})\\,0)\\,0\\,if(eq(({$time})\\,1)\\,1\\,if(lt(({$time})\\,0.5)\\,{$firstExp}\\,{$secondExp})))";
115116
}
116117

117118
public static function EaseInCirc(string $time): string
@@ -134,7 +135,7 @@ public static function EaseInBack(string $time): string
134135
$c1 = 1.70158;
135136
$c3 = $c1 + 1;
136137

137-
return "{$c1}*pow(({$time})\\,3)-{$c3}*pow(({$time})\\,2)";
138+
return "{$c3}*pow(({$time})\\,3)-{$c1}*pow(({$time})\\,2)";
138139
}
139140

140141
public static function EaseOutBack(string $time): string
@@ -157,7 +158,7 @@ public static function EaseInElastic(string $time): string
157158
{
158159
$c4 = (2 * M_PI) / 3;
159160

160-
return "if(eq(({$time})\\,0)\\,0\\,if(eq(({$time})\\,1)\\,1\\,-pow(2\\,10*({$time})-10)*sin(({$time})*10-10.75)*{$c4}))";
161+
return "if(eq(({$time})\\,0)\\,0\\,if(eq(({$time})\\,1)\\,1\\,-pow(2\\,10*({$time})-10)*sin((({$time})*10-10.75)*{$c4})))";
161162
}
162163

163164
public static function EaseOutElastic(string $time): string
@@ -188,12 +189,12 @@ public static function EaseOutBounce(string $time): string
188189
$n1 = 7.5625;
189190
$d1 = 2.75;
190191
$firstExpr = "{$n1}*pow(({$time})\\,2)";
191-
$secondTime = "(({$time})-1.5)";
192-
$secondExpr = "{$n1}*({$secondTime}/{$d1})*({$secondTime})+0.75";
193-
$thirdTime = "(({$time})-2.25)";
194-
$thirdExpr = "{$n1}*({$thirdTime}/{$d1})*({$thirdTime})+0.9375";
195-
$fourthTime = "(({$time})-2.65)";
196-
$fourthExpr = "{$n1}*({$fourthTime}/{$d1})*({$fourthTime})+0.984375";
192+
$secondTime = "(({$time})-1.5/{$d1})";
193+
$secondExpr = "{$n1}*{$secondTime}*{$secondTime}+0.75";
194+
$thirdTime = "(({$time})-2.25/{$d1})";
195+
$thirdExpr = "{$n1}*{$thirdTime}*{$thirdTime}+0.9375";
196+
$fourthTime = "(({$time})-2.65/{$d1})";
197+
$fourthExpr = "{$n1}*{$fourthTime}*{$fourthTime}+0.984375";
197198

198199
return "if(lt(({$time})\\, 1/{$d1})\\,{$firstExpr}\\,if(lt(({$time})\\,2/{$d1})\\,{$secondExpr}\\,if(lt(({$time})\\,2.5/{$d1})\\,{$thirdExpr}\\,{$fourthExpr})))";
199200
}
@@ -202,9 +203,9 @@ public static function EaseInOutBounce(string $time): string
202203
{
203204
$x1 = self::EaseOutBounce("1-2*({$time})");
204205
$x2 = self::EaseOutBounce("2*({$time})-1");
205-
$gtExpr = "(1-({$x1}))/2";
206-
$ltExpr = "(1+({$x2}))/2";
206+
$ltExpr = "(1-({$x1}))/2";
207+
$gtExpr = "(1+({$x2}))/2";
207208

208-
return "if(lt(({$time})\\,0.5)\\,{$ltExpr}\\,{$gtExpr}";
209+
return "if(lt(({$time})\\,0.5)\\,{$ltExpr}\\,{$gtExpr})";
209210
}
210211
}

tests/Snapshots/.gitkeep

Whitespace-only changes.

0 commit comments

Comments
 (0)