GithubHelp home page GithubHelp logo

creativescala / doodle Goto Github PK

View Code? Open in Web Editor NEW
320.0 320.0 72.0 13.1 MB

Compositional vector graphics in Scala / Scala.JS

Home Page: https://creativescala.org/doodle/

License: Apache License 2.0

Scala 94.65% Shell 0.03% Batchfile 0.03% Java 5.24% JavaScript 0.06%
creative-coding hacktoberfest scala visualization

doodle's People

Contributors

akiomik avatar custommonkey avatar d6y avatar danielost avatar ddworak avatar domesticmouse avatar indraastra avatar jcabala avatar jenshalm avatar jo-osborne avatar joe-warren-roo avatar julienrf avatar lucascaval avatar matmoore avatar ml10 avatar namn avatar noelhwelsh avatar noelwelsh avatar sethtisue avatar tkfu avatar vosid8 avatar xuwei-k avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

doodle's Issues

Refactor bitmap support

The Bitmap algebra provides some basic support for loading bitmaps but it is limited in the following ways:

  • It doesn't represent that loading a bitmap can fail for various reasons (file not found, incorrect format, etc.)
  • It loads bitmaps as a Picture (strictly speaking, it is loaded as the F in the algebra but in the current implementation this basically means Picture). This means we don't have a separate type representing bitmaps, which is a problem because bitmaps are distinct from the vector graphics model of the rest of Doodle and we can do interesting operations on them that don't make sense on vector images and vice versa.

What it should do instead:

  • the Bitmap algebra should be parameterized by at least one type, the type of bitmaps, and possibly by an effect type. I don't think we've abstracted over effect types elsewhere in Doodle so the effect type can be ignored if it adds too much complexity.
  • change the Bitmap algebra so that the main method reflects the possibility of failure (e.g. returns an IO, Either, or a Try. Probably an Either is better as it doesn't fix the error to be an Exception, and so works across different backends with different error handling strategies. Could abstract over error handling with the MonadError type class but I'm not convinced it's warranted.) Probably returning an IO is best as that is used in other parts of Doodle.
  • add some utilities to Bitmap to load a bitmap when you don't care about errors.
  • backends should implement ToPicture to convert a particular bitmap type into the backend specific Picture type.

Concretely, we're looking at an interface like

trait LoadBitmap[Specifier, Bitmap] {
  def load(specifier: Specifier): IO[Bitmap]
}

where Specifier is the type of information that we used to specify where to find a bitmap (e.g. File on the JVM, String on the browser) and Bitmap is the type of the resulting bitmap (BufferedImage on the JVM.) Backend specific implementations could provide their own utility methods that augment the above.

Here are some links to relevant backend information:

run in doodleJS fails

In sbt:

> project doodleJS
> run

results in:

[info] Running Main
org.mozilla.javascript.EcmaError: TypeError: Cannot call method "getElementById" of undefined (Ldoodle_js_package$.sjsir#205)
    at org.mozilla.javascript.ScriptRuntime.constructError(ScriptRuntime.java:3701)
    at org.mozilla.javascript.ScriptRuntime.constructError(ScriptRuntime.java:3679)
    at org.mozilla.javascript.ScriptRuntime.typeError(ScriptRuntime.java:3707)
    at org.mozilla.javascript.ScriptRuntime.typeError2(ScriptRuntime.java:3726)
    at org.mozilla.javascript.ScriptRuntime.undefCallError(ScriptRuntime.java:3743)
    at org.mozilla.javascript.ScriptRuntime.getPropFunctionAndThisHelper(ScriptRuntime.java:2269)
    at org.mozilla.javascript.ScriptRuntime.getPropFunctionAndThis(ScriptRuntime.java:2247)
    at org.mozilla.javascript.ScriptRuntime.getElemFunctionAndThis(ScriptRuntime.java:2215)
    at org.mozilla.javascript.gen.Ldoodle_js_package__sjsir_7._c_anonymous_12(Ldoodle_js_package$.sjsir:205)
    at org.mozilla.javascript.gen.Ldoodle_js_package__sjsir_7.call(Ldoodle_js_package$.sjsir)
    at org.mozilla.javascript.optimizer.OptRuntime.call1(OptRuntime.java:32)
    at org.mozilla.javascript.gen.Ldoodle_js_package__sjsir_7._c_anonymous_3(Ldoodle_js_package$.sjsir:13)
    at org.mozilla.javascript.gen.Ldoodle_js_package__sjsir_7.call(Ldoodle_js_package$.sjsir)
    at org.mozilla.javascript.optimizer.OptRuntime.call2(OptRuntime.java:42)
    at org.mozilla.javascript.gen.LMain__sjsir_4._c_anonymous_3(LMain$.sjsir:13)
    at org.mozilla.javascript.gen.LMain__sjsir_4.call(LMain$.sjsir)
    at org.mozilla.javascript.optimizer.OptRuntime.callProp0(OptRuntime.java:85)
    at org.mozilla.javascript.gen.LMain__sjsir_4._c_anonymous_4(LMain$.sjsir:16)
    at org.mozilla.javascript.gen.LMain__sjsir_4.call(LMain$.sjsir)
    at org.mozilla.javascript.optimizer.OptRuntime.callProp0(OptRuntime.java:85)
    at org.mozilla.javascript.gen.LMain__sjsir_4._c_anonymous_7(LMain$.sjsir:28)
    at org.mozilla.javascript.gen.LMain__sjsir_4.call(LMain$.sjsir)
    at org.mozilla.javascript.optimizer.OptRuntime.callProp0(OptRuntime.java:85)
    at org.mozilla.javascript.gen._Users_psnively_Desktop_doodle_js_target_scala_2_11_doodle_launcher_js_5._c_script_0(/Users/psnively/Desktop/doodle/js/target/scala-2.11/doodle-launcher.js:1)
    at org.mozilla.javascript.gen._Users_psnively_Desktop_doodle_js_target_scala_2_11_doodle_launcher_js_5.call(/Users/psnively/Desktop/doodle/js/target/scala-2.11/doodle-launcher.js)
    at org.mozilla.javascript.ContextFactory.doTopCall(ContextFactory.java:394)
    at org.mozilla.javascript.ScriptRuntime.doTopCall(ScriptRuntime.java:3102)
    at org.mozilla.javascript.gen._Users_psnively_Desktop_doodle_js_target_scala_2_11_doodle_launcher_js_5.call(/Users/psnively/Desktop/doodle/js/target/scala-2.11/doodle-launcher.js)
    at org.mozilla.javascript.gen._Users_psnively_Desktop_doodle_js_target_scala_2_11_doodle_launcher_js_5.exec(/Users/psnively/Desktop/doodle/js/target/scala-2.11/doodle-launcher.js)
    at org.mozilla.javascript.Context.evaluateString(Context.java:1078)
    at org.scalajs.jsenv.rhino.package$ContextOps$.evaluateFile$extension(package.scala:21)
    at org.scalajs.jsenv.rhino.RhinoJSEnv.org$scalajs$jsenv$rhino$RhinoJSEnv$$internalRunJS(RhinoJSEnv.scala:152)
    at org.scalajs.jsenv.rhino.RhinoJSEnv$Runner.run(RhinoJSEnv.scala:60)
    at org.scalajs.sbtplugin.ScalaJSPluginInternal$.org$scalajs$sbtplugin$ScalaJSPluginInternal$$jsRun(ScalaJSPluginInternal.scala:358)
    at org.scalajs.sbtplugin.ScalaJSPluginInternal$$anonfun$37$$anonfun$apply$23$$anonfun$apply$24.apply(ScalaJSPluginInternal.scala:418)
    at org.scalajs.sbtplugin.ScalaJSPluginInternal$$anonfun$37$$anonfun$apply$23$$anonfun$apply$24.apply(ScalaJSPluginInternal.scala:412)
    at scala.Function1$$anonfun$compose$1.apply(Function1.scala:47)
[trace] Stack trace suppressed: run last doodleJS/compile:run for the full output.
java.lang.RuntimeException: Exception while running JS code: TypeError: Cannot call method "getElementById" of undefined (Ldoodle_js_package$.sjsir#205)
    at scala.sys.package$.error(package.scala:27)
    at org.scalajs.jsenv.rhino.RhinoJSEnv.org$scalajs$jsenv$rhino$RhinoJSEnv$$internalRunJS(RhinoJSEnv.scala:168)
    at org.scalajs.jsenv.rhino.RhinoJSEnv$Runner.run(RhinoJSEnv.scala:60)
    at org.scalajs.sbtplugin.ScalaJSPluginInternal$.org$scalajs$sbtplugin$ScalaJSPluginInternal$$jsRun(ScalaJSPluginInternal.scala:358)
    at org.scalajs.sbtplugin.ScalaJSPluginInternal$$anonfun$37$$anonfun$apply$23$$anonfun$apply$24.apply(ScalaJSPluginInternal.scala:418)
    at org.scalajs.sbtplugin.ScalaJSPluginInternal$$anonfun$37$$anonfun$apply$23$$anonfun$apply$24.apply(ScalaJSPluginInternal.scala:412)
    at scala.Function1$$anonfun$compose$1.apply(Function1.scala:47)
[trace] Stack trace suppressed: run last doodleJS/compile:run for the full output.
[error] (doodleJS/compile:run) Exception while running JS code: TypeError: Cannot call method "getElementById" of undefined (Ldoodle_js_package$.sjsir#205)
[error] Total time: 9 s, completed Mar 15, 2015 12:06:05 PM

Realistically, this is unsurprising, because the default Javascript runtime is Rhino, and with Doodle you really want to fastOptJS anyway, so you can see the output in the browser. But so as to have run or test not crash, it might be good to at least make the default Javascript runtime be PhantomJS, so at least there is a "proper" DOM to render into.

Add parametric curves

Write a small library of common parametric curves:

  • circle
  • rose spiral
  • catmull-rom interpolated spline

Parametric curve should be A => Point, where A is Normalized / Angle / etc. as appropriate.

Path MoveTo doesnt move to the right place

MoveTo in paths doesn't seem to be working as expected for me - here is a quick example from sbt console to show you what I mean:

val c = implicitly[doodle.backend.Canvas].asInstanceOf[doodle.jvm.Java2DCanvas]
val i = implicitly[doodle.backend.Interpreter].asInstanceOf[doodle.backend.StandardInterpreter]
def axes(xLen: Int, yLen: Int) = Path(List(
  MoveTo(Vec(-xLen/2,0)), 
  LineTo(Vec(xLen/2,0)),
  MoveTo(Vec(0,-yLen/2)),
  LineTo(Vec(0,yLen/2))))
axes(100,100).draw(i,c)
val linePath = Path(List(
  MoveTo(Vec(0,0)),
  LineTo(Vec(10,10))
))
linePath.draw(i,c)

And the output:
screenshot 2015-10-22 02 51 16

I'm trying to add support for rotating images and drawing circular arcs in paths, and ran into this while testing. If you can give me a pointer to what might be wrong, id be happy to take a crack at fixing it!

fill color lives on as stroke color

Shared mutable state strikes again. The fill color for the wee circle reappears as the stroke color for the large circle. Maria from ScalaBridge just found this.

circle(5).fillColor(Color.red) on circle(10) above circle(20)

image

I didn't look very closely but deleting this line fixes it.

Not submitting as a PR because I'm not convinced I understand what's going on.

publish to Maven Central?

for a getting-started library like this, I think it would be better to remove any possible road bump for newcomers. only having the library available via a custom resolver is a road bump; seen on Gitter today:

does anyone know where I can find the scala doodle lib ? can't find it on mvn central

Fix Text Layout

Text layout on both Java2D and SVG seems wrong (see, e.g. BoxesAndArrows.flatMap.draw). Investigate this and resolve if possible.

Unable to use doodle's GitHub master as a RootProject in sbt

I'm attempting to configure my project's build.sbt so that it depends on doodle's master GitHub branch so that I can make use of your latest additions to animations:

lazy val doodleProject = RootProject(uri("https://github.com/underscoreio/doodle.git"))
//lazy val doodleProject = RootProject( uri("git://github.com/dragos/dupcheck.git") )

lazy val root = (project in file("."))
  .settings(
    name := "gridworld",
    version := "1.0",
    scalaVersion := "2.11.7",
    //resolvers += "Underscore Training" at "https://dl.bintray.com/underscoreio/training",
    //libraryDependencies += "underscoreio" %% "doodle" % "0.1.0",
    initialCommands in console := """
      |import doodle.core._
      |import doodle.syntax._
      |import doodle.jvm._
      |import doodle.examples._
    """.trim.stripMargin
  )
  .dependsOn(doodleProject)

With this configuration, running sbt will give this error:

[info] Loading project definition from /Users/admin/.sbt/0.13/staging/bc969347ae8d770695a8/doodle/project
java.lang.AssertionError: assertion failed: Directory /local/dev/gridworld/js is not contained in build root /Users/admin/.sbt/0.13/staging/bc969347ae8d770695a8/doodle
        at scala.Predef$.assert(Predef.scala:179)
        at sbt.Load$.checkProjectBase(Load.scala:345)
        at sbt.Load$.sbt$Load$$resolve$1(Load.scala:380)
        at sbt.Load$$anonfun$resolveBase$1.apply(Load.scala:383)
        at sbt.Load$$anonfun$resolveBase$1.apply(Load.scala:383)
        at scala.Function1$$anonfun$compose$1.apply(Function1.scala:47)
        at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
        at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
        at scala.collection.immutable.List.foreach(List.scala:318)
        at scala.collection.TraversableLike$class.map(TraversableLike.scala:244)
        at scala.collection.AbstractTraversable.map(Traversable.scala:105)
        at sbt.Load$.projects(Load.scala:407)
        at sbt.Load$.loaded(Load.scala:308)
        at sbt.Load$.loadAll(Load.scala:334)
        at sbt.Load$.loadURI(Load.scala:289)
        at sbt.Load$.load(Load.scala:285)
        at sbt.Load$.load(Load.scala:276)
        at sbt.Load$.apply(Load.scala:130)
        at sbt.Load$.defaultLoad(Load.scala:36)
        at sbt.BuiltinCommands$.doLoadProject(Main.scala:481)
        at sbt.BuiltinCommands$$anonfun$loadProjectImpl$2.apply(Main.scala:475)
        at sbt.BuiltinCommands$$anonfun$loadProjectImpl$2.apply(Main.scala:475)
        at sbt.Command$$anonfun$applyEffect$1$$anonfun$apply$2.apply(Command.scala:58)
        at sbt.Command$$anonfun$applyEffect$1$$anonfun$apply$2.apply(Command.scala:58)
        at sbt.Command$$anonfun$applyEffect$2$$anonfun$apply$3.apply(Command.scala:60)
        at sbt.Command$$anonfun$applyEffect$2$$anonfun$apply$3.apply(Command.scala:60)
        at sbt.Command$.process(Command.scala:92)
        at sbt.MainLoop$$anonfun$1$$anonfun$apply$1.apply(MainLoop.scala:98)
        at sbt.MainLoop$$anonfun$1$$anonfun$apply$1.apply(MainLoop.scala:98)
        at sbt.State$$anon$1.process(State.scala:184)
        at sbt.MainLoop$$anonfun$1.apply(MainLoop.scala:98)
        at sbt.MainLoop$$anonfun$1.apply(MainLoop.scala:98)
        at sbt.ErrorHandling$.wideConvert(ErrorHandling.scala:17)
        at sbt.MainLoop$.next(MainLoop.scala:98)
        at sbt.MainLoop$.run(MainLoop.scala:91)
        at sbt.MainLoop$$anonfun$runWithNewLog$1.apply(MainLoop.scala:70)
        at sbt.MainLoop$$anonfun$runWithNewLog$1.apply(MainLoop.scala:65)
        at sbt.Using.apply(Using.scala:24)
        at sbt.MainLoop$.runWithNewLog(MainLoop.scala:65)
        at sbt.MainLoop$.runAndClearLast(MainLoop.scala:48)
        at sbt.MainLoop$.runLoggedLoop(MainLoop.scala:32)
        at sbt.MainLoop$.runLogged(MainLoop.scala:24)
        at sbt.StandardMain$.runManaged(Main.scala:53)
        at sbt.xMain.run(Main.scala:28)
        at xsbt.boot.Launch$$anonfun$run$1.apply(Launch.scala:109)
        at xsbt.boot.Launch$.withContextLoader(Launch.scala:128)
        at xsbt.boot.Launch$.run(Launch.scala:109)
        at xsbt.boot.Launch$$anonfun$apply$1.apply(Launch.scala:35)
        at xsbt.boot.Launch$.launch(Launch.scala:117)
        at xsbt.boot.Launch$.apply(Launch.scala:18)
        at xsbt.boot.Boot$.runImpl(Boot.scala:41)
        at xsbt.boot.Boot$.main(Boot.scala:17)
        at xsbt.boot.Boot.main(Boot.scala)
[error] java.lang.AssertionError: assertion failed: Directory /local/dev/gridworld/js is not contained in build root /Users/admin/.sbt/0.13/staging/bc969347ae8d770695a8/doodle
[error] Use 'last' for the full log.

I'm new to sbt, so I could easily be doing something wrong. However, if I switch out the RootProject with the example given in the sbt docs, then running sbt works just fine:

lazy val doodleProject = RootProject( uri("git://github.com/dragos/dupcheck.git") )

Publish Doodle artefact

We should make the library part of Doodle available somewhere (possibly Bintray).

Doing so would require reorganising the codebase a little, splitting libraries from examples. Not sure what the implications are for JS either.

Text rendering on SVG backend is not centered

Text is not properly located on the y-axis on the SVG backend. Need to better understanding the coordinates used in the SVGRect returned from getBBox to understand how to get the correct layout.

Add `Image` element that directly renders on the underlying`Canvas`

Some images (e.g. large fractals) require so many points that representing them as an Image data structure in-memory is infeasible. We have the Canvas API that draws directly onto the screen (or file) without (much) memory allocation.

We need to make this available as an additional element in the Image algebraic data type.

E.g.

final case class Render(width: Int, height: Int, f: Canvas => Unit) extends Image

Here is has a nominal width and height for layout purposes.

Then update backends to call f with the Canvas instances.

Coordinates edges

I would like to show the coordinate edges so when I see the drawing I can have the context. What can I do?
Thanks
Reynaldo

Create a site for Doodle

Having a little site for Doodle to host documentation would be very nice. We could perhaps use the 47degrees sbt-microsite project to get this done easily.

Transformations or Multiple Images per Canvas?

It looks like right now Doodle doesn't have the ability to draw multiple doodle.core.Image objects in the same context? Each draw() call opens a new rendering window.

It also looks like Doodle doesn't support transitions? That is, moving something once it's been drawn on a canvas?

Does doodle plan to add these things? Is there any way I might do drawing with Doodle's high level API and then access the lower level Java2D objects to do more complicated things like transitions and adding other drawings to a canvas?

Travis build failing

From most recent run:

[error] bad option: '-Ypartial-unification'
[error] bad option: '-Ypartial-unification'
[error] (doodleJVM/compile:compileIncremental) Compilation failed
[error] (doodleJS/compile:compileIncremental) Compilation failed
[error] Total time: 31 s, completed Mar 9, 2017 8:17:38 PM

Reorder how context transforms are applied

Doodle currently applies the inner most ContextTransform. E.g.

circle(10).fillColor(Color.red).fillColor(Color.blue)

will produce a red circle. A more sensible semantics is to produce a blue circle.

Cross build to 2.12

Doodle currently builds for 2.11 only. It would be great to cross build to both 2.11 and 2.12

Update write options for images to include Base64 string

I would like to post images generated from doodle to Twitter. The required format is Base 64 string. Currently, doodle only allows writing to png, jpg, or gif. Can you please update to allow the user to write to a Base64 string to make this process easier? Thanks!

Example console commands in README don't work

Note that I'm a scala noob. It seems likely that I'm missing something that would be obvious if I was more familiar with the language and its packaging conventions. Anyway, updating my build.sbt and attempting the README commands results in:

[info] Loading project definition from C:\code\scratch\scala\scala-scratch\project
[info] Set current project to hello-world (in build file:/C:/code/scratch/scala/scala-scratch/)
> console
[info] Starting scala interpreter...
[info]
Welcome to Scala 2.12.1 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_144).
Type in expressions for evaluation. Or try :help.

scala> (circle(10) fillColor Color.red).draw
<console>:12: error: not found: value circle
       (circle(10) fillColor Color.red).draw
        ^
<console>:12: error: not found: value Color
       (circle(10) fillColor Color.red).draw

Which looks like unresolved symbols; I managed to fix that:

scala> import doodle.core._
import doodle.core._

scala> (circle(10) fillColor Color.red).draw
<console>:15: error: not found: value circle
       (circle(10) fillColor Color.red).draw

Well, sort of. Looking at the example code it seems that circle may have been moved to Image.circle?

scala> (Image.circle(10) fillColor Color.red).draw                                
<console>:15: error: value draw is not a member of doodle.core.Image              
       (Image.circle(10) fillColor Color.red).draw                                
                                              ^                                   

??? I managed to get a different error message following another import:

scala> import doodle.syntax._
import doodle.syntax._

scala> (Image.circle(10) fillColor Color.red).draw
<console>:18: error: could not find implicit value for parameter draw: doodle.backend.Interpreter.Draw
       (Image.circle(10) fillColor Color.red).draw
                                              ^

I wonder if I need to import a backend, but none of doodle.backend._, doodle.jvm, nor doodle.jvm._ manage to get past this error.

Scala.js artifacts are not published

Scala.js artifacts are not published due to some configuration error that results in the following:

java.lang.RuntimeException: error uploading to
 https://api.bintray.com/maven/noelwelsh/maven/maven/underscoreio/doodle_sjs0.6_2.11
 /a78e60eee4873ec2328fe748f49023226c98635d-SNAPSHOT/doodle_sjs0.6_2.11-
 a78e60eee4873ec2328fe748f49023226c98635d-SNAPSHOT.pom: 
{"message":"Provided artifact path does not comply with Maven's convention"}

(Manual line breaks added for readability above.)

Somebody with too much time on their hands needs to dig into the build to work out what is going wrong.

move to monix 3.0.0-RC2

would you mind updating your monix dependency to 3.0.0-RC2? some source changes (maybe just one?) will be needed:

sbt:root> animate/compile
[warn] Credentials file /Users/tisue/.sbt/sonatype_credential does not exist
[warn] Credentials file /Users/tisue/.sbt/sonatype_credential does not exist, ignoring it
[warn] Credentials file /Users/tisue/.sbt/sonatype_credential does not exist, ignoring it
[info] Compiling 65 Scala sources to /Users/tisue/doodle/core/target/scala-2.12/classes ...
[info] Done compiling.
[info] Compiling 6 Scala sources to /Users/tisue/doodle/animate/target/scala-2.12/classes ...
[error] /Users/tisue/doodle/animate/src/main/scala/doodle/animate/java2d/Java2dAnimator.scala:47:31: type mismatch;
[error]  found   : cats.effect.IO[A]
[error]  required: monix.eval.Task[?]
[error]       .mapEval(img => e.render(canvas)(algebra => img(algebra)))
[error]                               ^
[error] one error found
[error] (animate / Compile / compileIncremental) Compilation failed
[error] Total time: 13 s, completed Jan 4, 2019 9:12:40 AM

context: this would allow me to keep Doodle in the Scala 2.12 community build. currently it is failing

Extend allowable fills with gradients

Filling with gradients is supported by both SVG and Java2D (I think). It would be useful to expose this functionality within Doodle as it opens up more creative possibilities.

  • See what SVG and Java2D support
  • Model as an algebraic data type (probably gradient = linear | radial)
  • Extend DrawingContext to allow gradient fills
  • Implement in backends

Error on first run

I cloned the repo from github, ran 'sbt' followed by 'console'. Things appeared all right. But then:

`scala> draw(Circle(10) fillColor Color.red)
<console>:26: error: not found: value draw
       draw(Circle(10) fillColor Color.red)
       ^
`

What am I doing wrong? I am on Ubuntu 14.04 64-bit with OpenJDK 7.

Star solution is drawing extra initial line

Given the example solution code:

def star(sides: Int, skip: Int, radius: Double) = {
    val centerAngle = 360.degrees * skip / sides
    val elements = (0 to sides) map { index =>
        LineTo(Vec.polar(centerAngle * index, radius))
    }
    Path(elements) lineWidth 2
}

produces the following star for me:

star with extra line

with the following code piece: draw(star(10, 3, 100))

MissingRequirementError

When running sbt I get the following error:

$ sbt
[info] Loading project definition from C:\Workspace\doodle\project
[info] Compiling 1 Scala source to C:\Workspace\doodle\project\target\scala-2.10\sbt-0.13\classes...
[error] error while loading , error in opening zip file
scala.reflect.internal.MissingRequirementError: object scala.runtime in compiler mirror not found.
at scala.reflect.internal.MissingRequirementError$.signal(MissingRequirementError.scala:16)
at scala.reflect.internal.MissingRequirementError$.notFound(MissingRequirementError.scala:17)
at scala.reflect.internal.Mirrors$RootsBase.getModuleOrClass(Mirrors.scala:48)
at scala.reflect.internal.Mirrors$RootsBase.getModuleOrClass(Mirrors.scala:40)
at scala.reflect.internal.Mirrors$RootsBase.getModuleOrClass(Mirrors.scala:61)
at scala.reflect.internal.Mirrors$RootsBase.getPackage(Mirrors.scala:172)
at scala.reflect.internal.Mirrors$RootsBase.getRequiredPackage(Mirrors.scala:175)
at scala.reflect.internal.Definitions$DefinitionsClass.RuntimePackage$lzycompute(Definitions.scala:183)
at scala.reflect.internal.Definitions$DefinitionsClass.RuntimePackage(Definitions.scala:183)
at scala.reflect.internal.Definitions$DefinitionsClass.RuntimePackageClass$lzycompute(Definitions.scala:184)
at scala.reflect.internal.Definitions$DefinitionsClass.RuntimePackageClass(Definitions.scala:184)
at scala.reflect.internal.Definitions$DefinitionsClass.AnnotationDefaultAttr$lzycompute(Definitions.scala:1024)
at scala.reflect.internal.Definitions$DefinitionsClass.AnnotationDefaultAttr(Definitions.scala:1023)
at scala.reflect.internal.Definitions$DefinitionsClass.syntheticCoreClasses$lzycompute(Definitions.scala:1153)
at scala.reflect.internal.Definitions$DefinitionsClass.syntheticCoreClasses(Definitions.scala:1152)
at scala.reflect.internal.Definitions$DefinitionsClass.symbolsNotPresentInBytecode$lzycompute(Definitions.scala:1196)
at scala.reflect.internal.Definitions$DefinitionsClass.symbolsNotPresentInBytecode(Definitions.scala:1196)
at scala.reflect.internal.Definitions$DefinitionsClass.init(Definitions.scala:1261)
at scala.tools.nsc.Global$Run.(Global.scala:1290)
at xsbt.CachedCompiler0$$anon$2.(CompilerInterface.scala:106)
at xsbt.CachedCompiler0.run(CompilerInterface.scala:106)
at xsbt.CachedCompiler0.run(CompilerInterface.scala:95)
at xsbt.CompilerInterface.run(CompilerInterface.scala:26)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at sbt.compiler.AnalyzingCompiler.call(AnalyzingCompiler.scala:101)
at sbt.compiler.AnalyzingCompiler.compile(AnalyzingCompiler.scala:47)
at sbt.compiler.AnalyzingCompiler.compile(AnalyzingCompiler.scala:41)
at sbt.compiler.AggressiveCompile$$anonfun$3$$anonfun$compileScala$1$1.apply$mcV$sp(AggressiveCompile.scala:97)
at sbt.compiler.AggressiveCompile$$anonfun$3$$anonfun$compileScala$1$1.apply(AggressiveCompile.scala:97)
at sbt.compiler.AggressiveCompile$$anonfun$3$$anonfun$compileScala$1$1.apply(AggressiveCompile.scala:97)
at sbt.compiler.AggressiveCompile.sbt$compiler$AggressiveCompile$$timed(AggressiveCompile.scala:162)
at sbt.compiler.AggressiveCompile$$anonfun$3.compileScala$1(AggressiveCompile.scala:96)
at sbt.compiler.AggressiveCompile$$anonfun$3.apply(AggressiveCompile.scala:139)
at sbt.compiler.AggressiveCompile$$anonfun$3.apply(AggressiveCompile.scala:86)
at sbt.inc.IncrementalCompile$$anonfun$doCompile$1.apply(Compile.scala:38)
at sbt.inc.IncrementalCompile$$anonfun$doCompile$1.apply(Compile.scala:36)
at sbt.inc.IncrementalCommon.cycle(IncrementalCommon.scala:31)
at sbt.inc.Incremental$$anonfun$1.apply(Incremental.scala:39)
at sbt.inc.Incremental$$anonfun$1.apply(Incremental.scala:38)
at sbt.inc.Incremental$.manageClassfiles(Incremental.scala:66)
at sbt.inc.Incremental$.compile(Incremental.scala:38)
at sbt.inc.IncrementalCompile$.apply(Compile.scala:26)
at sbt.compiler.AggressiveCompile.compile2(AggressiveCompile.scala:153)
at sbt.compiler.AggressiveCompile.compile1(AggressiveCompile.scala:70)
at sbt.compiler.AggressiveCompile.apply(AggressiveCompile.scala:45)
at sbt.Compiler$.apply(Compiler.scala:74)
at sbt.Compiler$.apply(Compiler.scala:65)
at sbt.Defaults$.sbt$Defaults$$compileTaskImpl(Defaults.scala:789)
at sbt.Defaults$$anonfun$compileTask$1.apply(Defaults.scala:781)
at sbt.Defaults$$anonfun$compileTask$1.apply(Defaults.scala:781)
at scala.Function1$$anonfun$compose$1.apply(Function1.scala:47)
at sbt.$tilde$greater$$anonfun$$u2219$1.apply(TypeFunctions.scala:40)
at sbt.std.Transform$$anon$4.work(System.scala:63)
at sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:226)
at sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:226)
at sbt.ErrorHandling$.wideConvert(ErrorHandling.scala:17)
at sbt.Execute.work(Execute.scala:235)
at sbt.Execute$$anonfun$submit$1.apply(Execute.scala:226)
at sbt.Execute$$anonfun$submit$1.apply(Execute.scala:226)
at sbt.ConcurrentRestrictions$$anon$4$$anonfun$1.apply(ConcurrentRestrictions.scala:159)
at sbt.CompletionService$$anon$2.call(CompletionService.scala:28)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
error scala.reflect.internal.MissingRequirementError: object scala.runtime in compiler mirror not found.
Project loading failed: (r)etry, (q)uit, (l)ast, or (i)gnore?

Scala and java versions:
PS C:\Workspace\doodle> scala -version
Scala code runner version 2.11.5 -- Copyright 2002-2013, LAMP/EPFL
PS C:\Workspace\doodle> java -version
java version "1.8.0_25"
Java(TM) SE Runtime Environment (build 1.8.0_25-b18)
Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode)

Path image coordinate system horizontally flipped?

I'm not getting the following image when running the same snippet of code:

screenshot from 2016-01-17 17 44 20

Here's what I see:

screenshot from 2016-01-17 17 47 11

And when overlaid on a larger image ((image on Rectangle(200, 200)).draw):

screenshot from 2016-01-17 17 48 10

The only thing that draws as it should as per the example output is the decagon, which makes sense because it's symmetric. It might be related to issue #20.

BoundingBox calculation is not stack safe

Memoising the calculation at the time of construction, which is stack-safe, should solve the issue.

Need to augment stack safety spec to check for Above / Beside which use bounding box calculations to ensure this is fixed.

Refactor base64 support

Base64 support was added as a method to the Writer effect type class. It would be better factored into its own type class. Perform this refactoring.

Installation

I am very new to this library. I got a book "Creative Scala"; to follow this book, I need to install this library. I added the dependent library in my build.sbt file.

libraryDependencies += "creativescala.org" %% "doodle" % "0.9.0-SNAPSHOT"

But build does not work, it says the library is not available in MAVEN repository.

I tried it to create a JAR file from your source code, still I could not build it.

Is there any work *.jar file, so that I can directly use in my sample project.

Thanks alot !

Convert `Picture` to `BufferedImage`

Create a stable Java2D specific method to convert a Picture to a BufferedImage. This will allow fun pixel art in conjunction with #85. This should be a new kind of effect type class, I think.

We already have a ToPicture type class. Perhaps FromPicture is the natural counterpart here? Not sure they would be symmetric though---rendering a picture is an effect but converting to a picture is not.

error: could not find implicit value for parameter canvas: doodle.backend.Canvas

Because I've been unable to build doodle's master as a dependency in sbt (#16), I simply cloned the repo, sbt publish-local, and then I'm executing my code with scala -classpath doodle_2.11.jar mycode.scala

When mycode.scala looks like this:

import doodle.core._
import doodle.syntax._
import doodle.jvm._
import doodle.examples._

object Test {
  def main(args: Array[String]) {
    Circle(10).draw
  }
}

I get the error could not find implicit value for parameter interpreter: doodle.backend.Interpreter. I noticed that I can add this import at the top:

import doodle.backend.StandardInterpreter._

and that no longer seems to be a problem. Instead, I get error: could not find implicit value for parameter canvas: doodle.backend.Canvas.

Is scala -classpath not the right way to be referencing the library or are there additional import statements I need since the 0.1 release? Or, perhaps I need to create a Canvas object and pass it to something?

Initial running Fails with Java 8 / Windows 7

P90Puma@P90PUMA-X58A ~/git/doodle (develop)
$ sbt.bat console
Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=512m; sup
port was removed in 8.0
[info] Loading project definition from C:\Users\P90Puma\git\doodle\project
Missing bintray credentials C:\Users\P90Puma.bintray.credentials. Some bintray
features depend on this.
[info] Set current project to doodle (in build file:/C:/Users/P90Puma/git/doodle
/)
[error] Not a valid command: %*
[error] %*
[error] ^

P90Puma@P90PUMA-X58A ~/git/doodle (develop)
$ java -version
java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b15)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)

P90Puma@P90PUMA-X58A ~/git/doodle (develop)
$ which java
/c/ProgramData/Oracle/Java/javapath/java

Java2D support for outlined fonts

Text in SVG supports separate stroke and fill. They way we currently draw text on Java2D uses the stroke color as the fill. We can get more control over text rendering using the TextLayout API, and in particular either the draw or getOuline methods on TextLayout.

Add Golden Tests for SVG

Golden testing is the technique we use for end-to-end testing. The essential idea is to compare output against known good output.

We have golden tests for the Java2D backend, comparing rendered PNGs. We should add tests for the SVG backend. It's not immediately clear how to implement this. We could compare textual output but this is a bit fragile to non-semantic changes. We also cannot easily visualize the output to make sure it's actually correct (or see where it is wrong). Ideally we'd find some Java package that can render SVG to a bitmap.

Implement categorical data and bar charts

Basic support for charts exists on feature/plotting. This currently supports only scatter plots, and 2D numeric data. I'd like to implement bar charts as the next chart type. This requires supporting categorical data.

Longer term we'll need more complex data types. Part of the work here is exploring different representations. A non-goal, at this point, is to support multiple plots / series per chart.

Here are some of the tasks:

  • Extend Series to support categorical data
  • Factor chart interpreter into reusable components
  • Implement bar charts

Reinstate Scala.js build

Build Doodle 0.9 for Scala.js:

  • add Scala.js plugin
  • put Java2D backend into the JVM build
  • make other projects shared builds
  • implement SVG backend for JS
  • clean up "old" directories
  • test it actually works

Set window title?

Right now the window that doodle opens to draw an image is always titled "Doodle." Is there any way to change this?

screen shot 2015-08-04 at 21 52 35

Extend `Canvas` API with `circle` method.

Since we want to allow direct access to the Canvas API it could do with being a bit more featureful. Being able to draw a circle would be a very useful method. SVG can draw a circle directly. Java2D cannot but there is code showing how to convert a circle to a Bezier curve in the backend already.

Other methods might be useful. We can open separate issues for them.

Semantics of `at` are unclear

The semantics of at when combined with our combinators such as beside and above are unclear. For example, this does not render what I expect:

(Circle(10).fillColor(Color.darkBlue) beside 
  (Circle(10).fillColor(Color.aliceBlue).at(10,10) on Circle(10).fillColor(Color.red)))

Specifically, I don't expect a gap between the darkBlue and red circles.

No java2d animation shown on Linux

Hi,

I did a small try with your latest commit (Release 0.9.4-SNAPSHOT), built locally using sbt publishLocal and then tried using an ammonite script based on your example named PulsingCircle. When I tried to start it I got a very small window frame, not a 600x600 one, with nothing inside it, when I resize it, I can only see a small white rectangle, and everything else is black.

image

import $ivy.`org.creativescala::doodle:0.9.4-SNAPSHOT`
import cats.instances.all._
import doodle.core._
import doodle.syntax._
import doodle.java2d.effect._
import doodle.java2d._
import doodle.java2d.algebra._
import doodle.interact.syntax._
import monix.reactive.Observable

val frame = Frame.size(600, 600)

def circle(diameter: Int): Picture[Unit] =
  Picture{ implicit algebra =>
    algebra.circle(diameter.toDouble).strokeColor(Color.crimson).strokeWidth(3.0)
  }

val animation: Observable[Picture[Unit]] =
  Observable
    .repeat(1)
    .scan((3, 10)){ (state, _) =>
      val (inc, diameter) = state
      if(diameter >= 500) (-3, diameter - 3)
      else if(diameter <= 10) (1, diameter + 3)
      else (inc, diameter + inc)
    }
    .map{ case (_, d) => circle(d) }


val r = for {
    canvas <- frame.canvas
    frames  = animation
  } yield frames.animateFrames(canvas)

r.unsafeRunAsync(println _)

scala.io.StdIn.readLine("Enter to exit...") // required when run as a script

You really did a great job with the doodle API, this is exactly the kind of vector graphics I was looking for :)

`Monad` instance for `Picture`

Picture needs a Monad type class instances for the Size algebra to be any use. This requires the underlying F has a Monad instance.

SVG Renderer misplaces ClosedPath

Hey man, I really like what you've done here and it's cool to see the project alive and kicking. As far as I'm aware this is the best tool for generating Svg out of Scala so I appreciate it!

I'm having an issue with some Svg output.

Given:

val rect = Image.rectangle(200, 200).strokeColor(Color.red)
val rect2 = ClosedPath(List(
  MoveTo(Cartesian(0.0, 0.0)),
  LineTo(Cartesian(200.0, 0.0)),
  LineTo(Cartesian(200.0, 200.0)),
  LineTo(Cartesian(0.0, 200.0)),
  LineTo(Cartesian(0.0, 0.0))
))

val frame = doodle.svg.effect.Frame("svg").fitToPicture(10)
rect.write[Svg]((wd / "rect-200.svg").toString, frame)(svgWriter)
rect2.write[Svg]((wd / "rect2-200.svg").toString, frame)(svgWriter)

The first rect correctly yields a Rect(10, 10, 200, 200) where Rect(x,y,w,h) on a canvas of 220 by 220.
The latter path yields a path with:
d: M 0,0 M 0,0 L 200,0 L 200,200 L 0,200 L 0,0 Z
transform: matrix(1.0,0.0,0.0,-1.0,0.0,0.0)

In this case we get a Rect(10, 210, 200, 200). As soon as I remove the transformation the rectangle moves to be center in the viewbox but I suspect for the wrong reason (it'll be upside down). I suspect the y-mirror transformation fails because the transforms are applied around the 'origin' of the shape. In the case of a svg rect that's its centroid. In the case of a path it's the coordinates of the very first draw call.

Entire Svg output for rect2: https://gist.github.com/Pucilowski/ace2dce5f15872ebca173b345cbd6826?short_path=fde0c33

Thanks for the time you're putting into this!

Add affine transforms

We should be able to perform arbitrary affine transforms (scale, rotate, shear, reflection) on images, allowing greater expressiveness.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.