-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #55 from theckman/new_spinner_gifs
Update README spinner gifs, add tooling + notes used to create them
- Loading branch information
Showing
6 changed files
with
295 additions
and
83 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
# demo | ||
|
||
This program is the helper used to create the gifs in the README. What follows | ||
are notes for when I do this in the future. | ||
|
||
### Overview | ||
|
||
The software in this `demo` folder is used to demonstrate all of the spinners | ||
that exist, and to help generate the GIFs used for the README.md file in the | ||
root of this repo. | ||
|
||
There are two helper scripts in the `scripts/` folder. `ffmpeg.sh` helps with | ||
converting the h.264 .mp4 files into .gif files. The `rename.go` program then | ||
helps rename those .gif files into the right name for committing to the | ||
repository. | ||
|
||
The GIFs are stored in a sister GitHub repository, [github.com/theckman/yacspin-gifs](https://github.com/theckman/yacspin-gifs) | ||
to avoid cluttering up this repo with binary files (images). | ||
|
||
#### Checklist | ||
|
||
- [ ] start a screen recording of the terminal using Apple QuickTime Player | ||
- [ ] start the demo program (`main.go`) and let it run entirely before stopping the QuickTime recording | ||
- [ ] load the .mov file into Adobe Preimere, and cut the clip down into the individual 10 second clips of each spinner | ||
- [ ] turn the clips in the original Sequence into Subsequences | ||
- [ ] use media encoder to export those subsequences to their own files, matching source with Adaptive High Bitrate | ||
- [ ] use the `scripts/ffmpeg.sh` script to convert the `.mp4` files into `.gif` files | ||
- [ ] `go run` the `scripts/rename.go` program, to rename the `.gif` files to match the names we expect | ||
|
||
#### QuickTime Capture Sizes | ||
|
||
When using the Apple QuickTime Player to capture the screen recording, you can | ||
have it only capture a specific area of the screen. These are the capture sizes | ||
I played with on my Apple 16" M1 Max MBP laptop. | ||
|
||
Please note, that the video files rendered from these captures tend to have | ||
about 2x the resolution. Keep that in mind when deciding how large of an area | ||
you want to capture. | ||
|
||
Capture Size (pixels) | Font Size | ||
----------------------|---------- | ||
650w x 24h | 18 | ||
340w x 12h | 10 | ||
1300w x 47h | 38 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
// This program was used to generate the gifs in the README file | ||
|
||
package main | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"os/signal" | ||
"runtime" | ||
"runtime/debug" | ||
"syscall" | ||
"time" | ||
|
||
"github.com/theckman/yacspin" | ||
) | ||
|
||
func main() { | ||
// disable GC | ||
debug.SetGCPercent(-1) | ||
|
||
cfg := yacspin.Config{ | ||
Frequency: 200 * time.Millisecond, | ||
CharSet: yacspin.CharSets[36], | ||
SuffixAutoColon: true, | ||
Suffix: " example spinner", | ||
Message: "initial message", | ||
Colors: []string{"fgYellow"}, | ||
} | ||
|
||
spinner, err := yacspin.New(cfg) | ||
if err != nil { | ||
fmt.Fprintf(os.Stderr, "failed to create spinner: %v\n", err) | ||
os.Exit(1) | ||
} | ||
|
||
// handle SIGINT / SIGTERM without needing terminal reset | ||
sigc := make(chan os.Signal, 2) | ||
signal.Notify(sigc, syscall.SIGINT, syscall.SIGTERM) | ||
go func() { | ||
<-sigc | ||
_ = spinner.Stop() | ||
os.Exit(0) | ||
}() | ||
|
||
// run GC once before we start to render | ||
runtime.GC() | ||
|
||
time.Sleep(3 * time.Second) | ||
|
||
for i := 0; i < len(yacspin.CharSets); i++ { | ||
spinner.Message("initial message") | ||
|
||
// interesting charsets for recording sizing: 19, 36 | ||
_ = spinner.CharSet(yacspin.CharSets[i]) | ||
|
||
_ = spinner.Start() | ||
|
||
time.Sleep(5 * time.Second) | ||
|
||
spinner.Message("updated message") | ||
|
||
time.Sleep(5 * time.Second) | ||
|
||
_ = spinner.Stop() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
#!/bin/bash | ||
|
||
#### | ||
# | ||
# Convert *.mp4 files in the current directory to GIFs at 10 FPS | ||
# | ||
#### | ||
|
||
function main() { | ||
for file in *.mp4; | ||
do | ||
basename=$(echo "${file}" | sed -e 's/\.mp4$//') | ||
|
||
ffmpeg -i "${basename}.mp4" -vf "fps=10,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" -loop 0 "${basename}.gif" | ||
done | ||
} | ||
|
||
main |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
package main | ||
|
||
import ( | ||
"flag" | ||
"fmt" | ||
"os" | ||
"path/filepath" | ||
"strconv" | ||
"strings" | ||
"syscall" | ||
) | ||
|
||
func main() { | ||
var sim bool | ||
var glob string | ||
|
||
flag.BoolVar(&sim, "sim", false, "simulate") | ||
flag.StringVar(&glob, "glob", "", "glob to use for matching files, must end in *.gif") | ||
flag.Parse() | ||
|
||
if !strings.HasSuffix(glob, "*.gif") { | ||
fmt.Fprintln(os.Stderr, "-glob flag required and must end in *.gif") | ||
os.Exit(int(syscall.EINVAL)) | ||
} | ||
|
||
m, err := filepath.Glob(glob) | ||
if err != nil { | ||
fmt.Fprintf(os.Stderr, "failed to glob %s: %v\n", glob, err) | ||
os.Exit(1) | ||
} | ||
|
||
if len(m) == 0 { | ||
fmt.Fprintf(os.Stderr, "no files matched glob %s\n", glob) | ||
os.Exit(1) | ||
} | ||
|
||
idx := strings.Index(glob, "*") | ||
|
||
for _, match := range m { | ||
num := strings.TrimSuffix(match[idx:], ".gif") | ||
|
||
ni, err := strconv.Atoi(num) | ||
if err != nil { | ||
fmt.Fprintf(os.Stderr, "failed to convert number in %s to integer: %v\n", match, err) | ||
os.Exit(1) | ||
} | ||
|
||
ni-- | ||
|
||
newName := fmt.Sprintf("%d.gif", ni) | ||
|
||
if sim { | ||
fmt.Printf("would rename %s to %s\n", match, newName) | ||
continue | ||
} | ||
|
||
if err := os.Rename(match, newName); err != nil { | ||
fmt.Fprintf(os.Stderr, "failed to rename %s to %s\n", match, newName) | ||
os.Exit(1) | ||
} | ||
} | ||
} |