Last active
April 2, 2023 10:13
-
-
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/ee32d12bec9a2c6d4b84fcd64699055a64501b71
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.1.1" | |
//> 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