Last active
May 25, 2024 10:20
-
-
Save dacr/c0eeb3adcd7181d2eab8e97e273c8713 to your computer and use it in GitHub Desktop.
Trying to animate vector graphics using doodle library. / published by https://github.com/dacr/code-examples-manager #b6b3e414-1fea-47a1-8948-98fadb10b257/4516908852ab08297955bd8aa88572800d6cc13d
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
// summary : Trying to animate vector graphics using doodle library. | |
// keywords : scala, vector-graphics, doodle, examples, @testable | |
// publish : gist | |
// authors : Noel Welsh, David Crosson | |
// license : Apache NON-AI License Version 2.0 (https://raw.githubusercontent.com/non-ai-licenses/non-ai-licenses/main/NON-AI-APACHE2) | |
// id : b6b3e414-1fea-47a1-8948-98fadb10b257 | |
// created-on : 2019-06-25T21:04:29Z | |
// managed-by : https://github.com/dacr/code-examples-manager | |
// run-with : scala-cli $file | |
// --------------------- | |
//> using scala "3.4.2" | |
//> using dep "org.creativescala::doodle:0.10.1" | |
// --------------------- | |
// Example coming from doodle examples code (PulsingCircle.scala), author is Noel Welsh | |
// https://github.com/creativescala/doodle/blob/master/java2d/src/main/scala/doodle/java2d/examples/PulsingCircle.scala | |
object TryIt { | |
import cats.instances.all._ | |
import doodle.core._ | |
import doodle.effect.Writer.Gif | |
import doodle.syntax.all._ | |
import doodle.java2d.effect._ | |
import doodle.interact.syntax._ | |
import fs2.Stream | |
import cats.effect.IO | |
import doodle.java2d._ | |
import cats.effect.unsafe.implicits.global | |
val frame = Frame.size(600, 600).background(Color.darkMagenta) | |
val strokeWidth = 9.0 | |
val gapWidth = 6.0 | |
val minimumDiameter = gapWidth + strokeWidth | |
val maxNumberOfDisks = 15 | |
def disk(count: Int): Picture[Unit] = | |
count match { | |
case 0 => | |
circle[Algebra, Drawing](minimumDiameter.toDouble).noFill | |
.strokeWidth(strokeWidth) | |
case n => | |
circle[Algebra, Drawing]( | |
(n * 2 * (strokeWidth + gapWidth) + minimumDiameter) | |
).noFill | |
.strokeWidth(strokeWidth) | |
} | |
def background(count: Int): Picture[Unit] = { | |
def iter(count: Int): Picture[Unit] = | |
count match { | |
case 0 => | |
disk(count) | |
case n => | |
disk(count).on(iter(n - 1)) | |
} | |
iter(count).strokeWidth(strokeWidth.toDouble).strokeColor(Color.darkGray) | |
} | |
def pulse(count: Int): Picture[Unit] = | |
count match { | |
case 0 => disk(0).strokeColor(Color.crimson) | |
case 1 => | |
disk(1) | |
.strokeColor(Color.crimson) | |
.on(disk(0).strokeColor(Color.crimson.spin(30.degrees))) | |
case n => | |
disk(n) | |
.strokeColor(Color.crimson) | |
.on( | |
disk(n - 1) | |
.strokeColor(Color.crimson.spin(30.degrees)) | |
) | |
.on( | |
disk(n - 2) | |
.strokeColor(Color.crimson.spin(60.degrees)) | |
) | |
} | |
val animation: Stream[IO, Picture[Unit]] = | |
Stream(1).repeat | |
.scan((1, 0)) { (state, _) => | |
val (inc, count) = state | |
if (count >= maxNumberOfDisks) (-1, maxNumberOfDisks - 1) | |
else if (count <= 0) (1, 1) | |
else (inc, count + inc) | |
} | |
.map { case (_, c) => pulse(c).on(background(maxNumberOfDisks)) } | |
def go() = | |
animation.animate(frame) | |
def write() = | |
animation.take(maxNumberOfDisks * 2).write[Gif]("bouncy-circles.gif", frame) | |
} | |
//TryIt.go() | |
//scala.io.StdIn.readLine("Enter to exit...") // required when run as a script | |
TryIt.write() | |
//scala.io.StdIn.readLine("Enter to exit...") // required when run as a script | |
//System.exit(0) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment