From b96f17ce9c935021b18678a88c5d52d032bd9565 Mon Sep 17 00:00:00 2001
From: Kaustubh Maske Patil <37668193+nikochiko@users.noreply.github.com>
Date: Tue, 12 Mar 2024 14:41:47 +0530
Subject: [PATCH 1/3] Add SVG backend
---
examples/dune | 7 ++++
examples/svg.ml | 7 ++++
lib/backend_svg.ml | 82 +++++++++++++++++++++++++++++++++++++++++++--
lib/backend_svg.mli | 9 +++--
lib/context.ml | 4 +--
lib/context.mli | 2 +-
lib/joy.ml | 21 ++++++++++++
lib/joy.mli | 2 ++
8 files changed, 126 insertions(+), 8 deletions(-)
create mode 100644 examples/svg.ml
diff --git a/examples/dune b/examples/dune
index f716550..7d8436f 100644
--- a/examples/dune
+++ b/examples/dune
@@ -1,6 +1,8 @@
(executable
(name axes)
(modules axes)
+ (modes js)
+ (preprocess (pps js_of_ocaml-ppx))
(libraries joy))
(executable
@@ -137,3 +139,8 @@
(name smile)
(modules smile)
(libraries joy))
+
+(executable
+ (name svg)
+ (modules svg)
+ (libraries joy))
diff --git a/examples/svg.ml b/examples/svg.ml
new file mode 100644
index 0000000..b497048
--- /dev/null
+++ b/examples/svg.ml
@@ -0,0 +1,7 @@
+open Joy
+
+let _ =
+ init_svg ();
+ show [ circle 50; rectangle 100 100 ];
+ Printf.printf "%s\n" (Joy.Context.writeSVG ())
+
diff --git a/lib/backend_svg.ml b/lib/backend_svg.ml
index e0c304c..438557c 100644
--- a/lib/backend_svg.ml
+++ b/lib/backend_svg.ml
@@ -1,4 +1,80 @@
-type context = unit
+type context = {
+ shapes: Shape.shape list ref;
+ size: int * int;
+ axes: bool;
+}
+
+let show ctx shapes =
+ ignore (ctx.shapes := !(ctx.shapes) @ shapes)
+
+let create ~size ~axes = {
+ shapes = ref [];
+ size;
+ axes;
+}
+
+let string_of_color (r, g, b, a) =
+ Printf.sprintf "rgba(%d, %d, %d, %f)" r g b a
+
+let svg_coords_of_point (w, h) ({ x; y }: float Shape.point) =
+ ( x +. (float_of_int w) /. 2.0, (float_of_int h) /. 2.0 -. y )
+
+(* Helper function to convert color to SVG attribute *)
+let svg_color_attribute name color =
+ Printf.sprintf "%s=\"%s\"" name (string_of_color color)
+
+(* Helper function to convert point to a string *)
+let string_of_svg_coords (x, y) =
+ Printf.sprintf "%f,%f" x y
+
+(* Function to render a circle *)
+let render_circle ctx ({ c; radius; stroke; fill }: Shape.circle) =
+ let cx, cy = svg_coords_of_point ctx.size c in
+ Printf.sprintf ""
+ cx cy radius
+ (svg_color_attribute "stroke" stroke)
+ (svg_color_attribute "fill" fill)
+
+(* Function to render an ellipse *)
+let render_ellipse ctx ({ c; rx; ry; rotation; stroke; fill }: Shape.ellipse) =
+ let cx, cy = svg_coords_of_point ctx.size c in
+ Printf.sprintf ""
+ cx cy rx ry rotation
+ (svg_color_attribute "stroke" stroke)
+ (svg_color_attribute "fill" fill)
+
+(* Function to render a polygon *)
+let render_polygon ctx ({ vertices; stroke; fill }: Shape.polygon) =
+ let string_of_point ({ x; y }: float Shape.point) =
+ string_of_svg_coords (svg_coords_of_point ctx.size { x; y })
+ in
+ let points = String.concat " " (List.map string_of_point vertices) in
+ Printf.sprintf ""
+ points
+ (svg_color_attribute "stroke" stroke)
+ (svg_color_attribute "fill" fill)
+
+(* Function to render a line *)
+let render_line ctx ({ a; b; stroke }: Shape.line) =
+ let ax, ay = svg_coords_of_point ctx.size a in
+ let bx, by = svg_coords_of_point ctx.size b in
+ Printf.sprintf ""
+ ax ay bx by
+ (svg_color_attribute "stroke" stroke)
+
+(* Recursive function to render shapes *)
+let rec render_shape ctx s =
+ match s with
+ | Shape.Circle c -> render_circle ctx c
+ | Shape.Ellipse e -> render_ellipse ctx e
+ | Shape.Line l -> render_line ctx l
+ | Shape.Polygon p -> render_polygon ctx p
+ | Shape.Complex shapes -> String.concat "" (List.map (render_shape ctx) shapes)
+
+let write ctx =
+ let shapes = !(ctx.shapes) in
+ let svg = String.concat "" (List.map (render_shape ctx) shapes) in
+ let (width, height) = ctx.size in
+ let svg = Printf.sprintf "" width height svg in
+ svg
-let show _ctx _shapes = ()
-let create _ = ()
diff --git a/lib/backend_svg.mli b/lib/backend_svg.mli
index d7ff084..80047c2 100644
--- a/lib/backend_svg.mli
+++ b/lib/backend_svg.mli
@@ -1,4 +1,9 @@
-type context = unit
+type context = {
+ shapes: Shape.shape list ref;
+ size: int * int;
+ axes: bool;
+}
val show : context -> Shape.shapes -> unit
-val create : unit -> context
+val create : size:int * int -> axes:bool -> context
+val write : context -> string
diff --git a/lib/context.ml b/lib/context.ml
index 876a3db..9fd8939 100644
--- a/lib/context.ml
+++ b/lib/context.ml
@@ -32,10 +32,10 @@ let writePNG ?ctx filename =
raise (Unsupported_output_format "SVG context cannot render to PNG")
| LazyContext _ -> failwith "Lazy.writePNG ctx filename"
-let writeSVG ?ctx =
+let writeSVG ?ctx _ =
let ctx = match ctx with Some ctx -> ctx | None -> get_default () in
match ctx with
| CairoContext _ ->
raise (Unsupported_output_format "Cairo context cannot render to SVG")
- | SVGContext _ -> failwith "SVG.writeSVG ctx"
+ | SVGContext ctx -> Backend_svg.write ctx
| LazyContext _ -> failwith "Lazy.writeSVG ctx"
diff --git a/lib/context.mli b/lib/context.mli
index d789c84..9b08a84 100644
--- a/lib/context.mli
+++ b/lib/context.mli
@@ -10,5 +10,5 @@ val get_default : unit -> context
val set_default : context -> unit
val show : ?ctx:context -> Shape.shapes -> unit
val set_line_width : ?ctx:context -> int -> unit
-val writeSVG : ?ctx:context -> string
+val writeSVG : ?ctx:context -> unit -> string
val writePNG : ?ctx:context -> string -> unit
diff --git a/lib/joy.ml b/lib/joy.ml
index d8c19eb..a1f794d 100644
--- a/lib/joy.ml
+++ b/lib/joy.ml
@@ -2,6 +2,8 @@ include Random
include Shape
include Transform
include Color
+
+module Context = Context
module Backend_cairo = Backend_cairo
module Backend_svg = Backend_svg
module Backend_lazy = Backend_lazy
@@ -32,4 +34,23 @@ let init ?(size = (500, 500)) ?(line_width = 1) ?(axes = false) _ =
in
show ~ctx:ctx_container [ x_axis; y_axis ]
+let init_svg ?(size = (500, 500)) ?(axes = false) _ =
+ let ctx = Backend_svg.create ~size ~axes in
+ let ctx_container = Context.SVGContext ctx in
+ Context.set_default ctx_container;
+ if axes then
+ let half_w, half_h =
+ ctx.size |> Util.tmap float_of_int |> Util.tmap (fun x -> x /. 2.0)
+ in
+ let gray = Color.color 128 128 128 ~a:0.5 in
+ let x_axis =
+ line ~a:{ x = -.half_w; y = 0. } { x = half_w; y = 0. }
+ |> with_stroke gray
+ in
+ let y_axis =
+ line ~a:{ x = 0.; y = -.half_h } { x = 0.; y = half_h }
+ |> with_stroke gray
+ in
+ show ~ctx:ctx_container [ x_axis; y_axis ]
+
let write ?(filename = "joy.png") () = Context.writePNG filename
diff --git a/lib/joy.mli b/lib/joy.mli
index 1b7be45..4aca9d2 100644
--- a/lib/joy.mli
+++ b/lib/joy.mli
@@ -1,3 +1,4 @@
+module Context = Context
module Backend_cairo = Backend_cairo
module Backend_svg = Backend_svg
module Backend_lazy = Backend_lazy
@@ -38,6 +39,7 @@ val yellow : color
val transparent : color
val rgb : int -> int -> int -> color
val init : ?size:int * int -> ?line_width:int -> ?axes:bool -> unit -> unit
+val init_svg : ?size:int * int -> ?axes:bool -> unit -> unit
val write : ?filename:string -> unit -> unit
val show : ?ctx:context -> shapes -> unit
val set_line_width : ?ctx:context -> int -> unit
From ea925a37907a1e43373910403c44769e1d44459c Mon Sep 17 00:00:00 2001
From: Kaustubh Maske Patil <37668193+nikochiko@users.noreply.github.com>
Date: Tue, 12 Mar 2024 15:14:30 +0530
Subject: [PATCH 2/3] Fix ellipse rotation type (float -> int)
---
lib/backend_svg.ml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/backend_svg.ml b/lib/backend_svg.ml
index 438557c..1420cb1 100644
--- a/lib/backend_svg.ml
+++ b/lib/backend_svg.ml
@@ -38,7 +38,7 @@ let render_circle ctx ({ c; radius; stroke; fill }: Shape.circle) =
(* Function to render an ellipse *)
let render_ellipse ctx ({ c; rx; ry; rotation; stroke; fill }: Shape.ellipse) =
let cx, cy = svg_coords_of_point ctx.size c in
- Printf.sprintf ""
+ Printf.sprintf ""
cx cy rx ry rotation
(svg_color_attribute "stroke" stroke)
(svg_color_attribute "fill" fill)
From 26c043e6f31820e883659ada1dd201018fc8372c Mon Sep 17 00:00:00 2001
From: Kaustubh Maske Patil <37668193+nikochiko@users.noreply.github.com>
Date: Thu, 14 Mar 2024 10:33:28 +0530
Subject: [PATCH 3/3] remove all deps except SVG
---
.gitignore | 6 +-
dev-examples/{dune => dune.old} | 0
examples/circle_packing.ml | 2 +-
examples/dune | 5 --
examples/svg.ml | 7 --
lib/backend_cairo.ml | 113 ++++----------------------------
lib/backend_cairo.mli | 22 ++-----
lib/backend_lazy.ml | 1 +
lib/backend_lazy.mli | 1 +
lib/backend_svg.ml | 40 ++++++++---
lib/backend_svg.mli | 9 ++-
lib/context.ml | 21 +++++-
lib/context.mli | 6 +-
lib/dune | 3 +-
lib/joy.ml | 10 ++-
lib/joy.mli | 12 ++--
16 files changed, 99 insertions(+), 159 deletions(-)
rename dev-examples/{dune => dune.old} (100%)
delete mode 100644 examples/svg.ml
diff --git a/.gitignore b/.gitignore
index 031a270..5be8e30 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,8 @@
_build
.vscode
.DS_Store
-*.png
\ No newline at end of file
+*.png
+*.cmi
+*.cmx
+*.cma
+*.o
diff --git a/dev-examples/dune b/dev-examples/dune.old
similarity index 100%
rename from dev-examples/dune
rename to dev-examples/dune.old
diff --git a/examples/circle_packing.ml b/examples/circle_packing.ml
index fc3670b..fa3426a 100644
--- a/examples/circle_packing.ml
+++ b/examples/circle_packing.ml
@@ -32,7 +32,7 @@ let palette =
]
(* utility Functions *)
-let rand_nth coll = List.length coll |> random |> List.nth coll
+let rand_nth coll = List.length coll |> Joy.random |> List.nth coll
let tmap f (a, b) = (f a, f b)
(* Pareto distribution float random for radii *)
diff --git a/examples/dune b/examples/dune
index e259940..f4e7610 100644
--- a/examples/dune
+++ b/examples/dune
@@ -140,11 +140,6 @@
(modules smile)
(libraries joy))
-(executable
- (name svg)
- (modules svg)
- (libraries joy))
-
(executable
(name simple_rotate_ellipse)
(modules simple_rotate_ellipse)
diff --git a/examples/svg.ml b/examples/svg.ml
deleted file mode 100644
index b497048..0000000
--- a/examples/svg.ml
+++ /dev/null
@@ -1,7 +0,0 @@
-open Joy
-
-let _ =
- init_svg ();
- show [ circle 50; rectangle 100 100 ];
- Printf.printf "%s\n" (Joy.Context.writeSVG ())
-
diff --git a/lib/backend_cairo.ml b/lib/backend_cairo.ml
index 3d485fa..2b390e6 100644
--- a/lib/backend_cairo.ml
+++ b/lib/backend_cairo.ml
@@ -1,109 +1,18 @@
-type context = {
- cairo_ctx : Cairo.context;
- surface : Cairo.Surface.t;
- size : int * int;
- background_color : int * int * int * float;
- axes : bool;
-}
+type context = { dummy: string; size: int * int }
-let write ctx filename =
- Cairo.PNG.write ctx.surface filename;
- Cairo.Surface.finish ctx.surface
-
-let set_color ctx color =
- let to_float i = float_of_int i /. 255. in
- let r, g, b, a = color in
- let r, g, b = Util.tmap3 to_float (r, g, b) in
- Cairo.set_source_rgba ctx.cairo_ctx r g b a
-
-let set_background ctx color =
+let string_of_color color =
let r, g, b, a = color in
- let to_float i = float_of_int i /. 255. in
- let r, g, b = Util.tmap3 to_float (r, g, b) in
- Cairo.set_source_rgba ctx.cairo_ctx r g b a;
- Cairo.paint ctx.cairo_ctx ~alpha:a;
- Cairo.fill ctx.cairo_ctx
-
-(** Sets the width of lines for both stroke of shapes and line primitives.
- Can be any positive integer, with larger numbers producing thicker lines. *)
-let set_line_width ctx line_width =
- Cairo.set_line_width ctx.cairo_ctx (float_of_int line_width)
-
-let draw_circle ctx (cx, cy) radius stroke fill =
- Cairo.arc ctx.cairo_ctx cx (Float.neg cy) ~r:radius ~a1:0. ~a2:(Float.pi *. 2.);
- set_color ctx stroke;
- Cairo.stroke_preserve ctx.cairo_ctx;
- set_color ctx fill;
- Cairo.fill_preserve ctx.cairo_ctx;
- Cairo.Path.clear ctx.cairo_ctx
-
-let draw_ellipse ctx (cx, cy) rx ry rotation stroke fill =
- (* Save the current transformation matrix *)
- let save_matrix = Cairo.get_matrix ctx.cairo_ctx in
-
- (* Apply rotation *)
- let radians = Util.to_radians rotation in
- Cairo.rotate ctx.cairo_ctx radians;
-
- (* Translate and scale to create an ellipse from a circle *)
- Cairo.translate ctx.cairo_ctx cx (Float.neg cy);
- Cairo.scale ctx.cairo_ctx rx ry;
-
- (* Arc from 0 to 2pi is a circle *)
- Cairo.arc ctx.cairo_ctx 0. 0. ~r:1. ~a1:0. ~a2:(2. *. Float.pi);
-
- (* Restore the original transformation matrix *)
- Cairo.set_matrix ctx.cairo_ctx save_matrix;
-
- set_color ctx stroke;
- Cairo.stroke_preserve ctx.cairo_ctx;
- set_color ctx fill;
- Cairo.fill_preserve ctx.cairo_ctx;
+ Printf.sprintf "(%d, %d, %d, %f)" r g b a
- Cairo.Path.clear ctx.cairo_ctx
+let create ~background_color ~size ~line_width ~axes =
+ let s = Printf.sprintf "create: background_color=%s size=(%d, %d) line_width=%d axes=%b\n"
+ (string_of_color background_color) (fst size) (snd size) line_width axes in
+ { dummy = s; size = size }
-let draw_line ctx (x1, y1) (x2, y2) stroke =
- set_color ctx stroke;
- Cairo.move_to ctx.cairo_ctx x1 (Float.neg y1);
- Cairo.line_to ctx.cairo_ctx x2 (Float.neg y2);
- Cairo.stroke ctx.cairo_ctx
+let show _ctx _shapes = ()
-let draw_polygon ctx vertices stroke fill =
- let x, y = List.hd vertices in
- let t = List.tl vertices in
- Cairo.move_to ctx.cairo_ctx x (Float.neg y);
- List.iter (fun (x', y') -> Cairo.line_to ctx.cairo_ctx x' (Float.neg y')) t;
- Cairo.Path.close ctx.cairo_ctx;
- set_color ctx stroke;
- Cairo.stroke_preserve ctx.cairo_ctx;
- set_color ctx fill;
- Cairo.fill ctx.cairo_ctx
+let set_line_width _ctx _line_width = ()
-let show ctx shapes =
- let rec render = function
- | Shape.Circle circle ->
- draw_circle ctx (circle.c.x, circle.c.y) circle.radius circle.stroke
- circle.fill
- | Shape.Ellipse ellipse ->
- draw_ellipse ctx (ellipse.c.x, ellipse.c.y) ellipse.rx ellipse.ry
- ellipse.rotation ellipse.stroke ellipse.fill
- | Shape.Line line ->
- draw_line ctx (line.a.x, line.a.y) (line.b.x, line.b.y) line.stroke
- | Shape.Polygon polygon ->
- let to_tuple (point : float Shape.point) = (point.x, point.y) in
- draw_polygon ctx
- (List.map to_tuple polygon.vertices)
- polygon.stroke polygon.fill
- | Shape.Complex complex -> List.iter render complex
- in
- List.iter render shapes
+let write _ctx _filename = ()
-let create ~background_color ~line_width ~size ~axes =
- let w, h = size in
- let surface = Cairo.Image.create Cairo.Image.ARGB32 ~w ~h in
- let cairo_ctx = Cairo.create surface in
- Cairo.translate cairo_ctx (w / 2 |> float_of_int) (h / 2 |> float_of_int);
- let ctx = { cairo_ctx; surface; size = (w, h); background_color; axes } in
- set_background ctx background_color;
- set_line_width ctx line_width;
- ctx
+let clear _ctx = ()
diff --git a/lib/backend_cairo.mli b/lib/backend_cairo.mli
index b6b23e5..b80897c 100644
--- a/lib/backend_cairo.mli
+++ b/lib/backend_cairo.mli
@@ -1,20 +1,8 @@
-type context = {
- cairo_ctx : Cairo.context;
- surface : Cairo.Surface.t;
- size : int * int;
- background_color : Color.color;
- axes : bool;
-}
+type context = { dummy: string; size: int * int }
-val set_color : context -> Color.color -> unit
-val set_background : context -> Color.color -> unit
+val create : background_color:int * int * int * float ->
+ size:int*int -> line_width:int -> axes:bool -> context
+val show : context -> Shape.shape list -> unit
val set_line_width : context -> int -> unit
-val show : context -> Shape.shapes -> unit
val write : context -> string -> unit
-
-val create :
- background_color:Color.color ->
- line_width:int ->
- size:int * int ->
- axes:bool ->
- context
+val clear : context -> unit
diff --git a/lib/backend_lazy.ml b/lib/backend_lazy.ml
index e0c304c..93508e4 100644
--- a/lib/backend_lazy.ml
+++ b/lib/backend_lazy.ml
@@ -2,3 +2,4 @@ type context = unit
let show _ctx _shapes = ()
let create _ = ()
+let clear _ctx = ()
diff --git a/lib/backend_lazy.mli b/lib/backend_lazy.mli
index d7ff084..b3a116e 100644
--- a/lib/backend_lazy.mli
+++ b/lib/backend_lazy.mli
@@ -2,3 +2,4 @@ type context = unit
val show : context -> Shape.shapes -> unit
val create : unit -> context
+val clear : context -> unit
diff --git a/lib/backend_svg.ml b/lib/backend_svg.ml
index 1420cb1..94fac4d 100644
--- a/lib/backend_svg.ml
+++ b/lib/backend_svg.ml
@@ -1,17 +1,26 @@
+open Js_of_ocaml
+
type context = {
shapes: Shape.shape list ref;
size: int * int;
axes: bool;
+ elt: Dom_html.divElement Js.t;
}
-let show ctx shapes =
- ignore (ctx.shapes := !(ctx.shapes) @ shapes)
-
-let create ~size ~axes = {
- shapes = ref [];
- size;
- axes;
-}
+let create ~size ~axes ~eltId =
+ let elt =
+ Js.Opt.get
+ (Js.Opt.bind
+ (Dom_html.document##getElementById (Js.string eltId))
+ Dom_html.CoerceTo.div)
+ (fun _ -> failwith "Could not find element with id")
+ in
+ {
+ shapes = ref [];
+ size;
+ axes;
+ elt;
+ }
let string_of_color (r, g, b, a) =
Printf.sprintf "rgba(%d, %d, %d, %f)" r g b a
@@ -71,10 +80,23 @@ let rec render_shape ctx s =
| Shape.Polygon p -> render_polygon ctx p
| Shape.Complex shapes -> String.concat "" (List.map (render_shape ctx) shapes)
-let write ctx =
+let make_svg ctx =
let shapes = !(ctx.shapes) in
let svg = String.concat "" (List.map (render_shape ctx) shapes) in
let (width, height) = ctx.size in
let svg = Printf.sprintf "" width height svg in
svg
+let write ctx =
+ let svg = make_svg ctx in
+ let elt = ctx.elt in
+ elt##.innerHTML := Js.string svg
+
+let show ctx shapes =
+ ctx.shapes := !(ctx.shapes) @ shapes;
+ write ctx
+
+let clear ctx =
+ ctx.shapes := [];
+ write ctx
+
diff --git a/lib/backend_svg.mli b/lib/backend_svg.mli
index 80047c2..c410597 100644
--- a/lib/backend_svg.mli
+++ b/lib/backend_svg.mli
@@ -2,8 +2,11 @@ type context = {
shapes: Shape.shape list ref;
size: int * int;
axes: bool;
+ elt: Js_of_ocaml.Dom_html.element Js_of_ocaml.Js.t;
}
-val show : context -> Shape.shapes -> unit
-val create : size:int * int -> axes:bool -> context
-val write : context -> string
+val show : context -> Shape.shape list -> unit
+val create : size:int * int -> axes:bool -> eltId:string -> context
+val make_svg : context -> string
+val write : context -> unit
+val clear : context -> unit
diff --git a/lib/context.ml b/lib/context.ml
index 9fd8939..e12e19a 100644
--- a/lib/context.ml
+++ b/lib/context.ml
@@ -10,13 +10,20 @@ let default = ref (LazyContext (Backend_lazy.create ()))
let get_default _ = !default
let set_default ctx = default := ctx
-let show ?ctx shapes =
+let show ?ctx (shapes: Shape.shape list) =
let ctx = match ctx with Some ctx -> ctx | None -> get_default () in
match ctx with
| CairoContext ctx -> Backend_cairo.show ctx shapes
| SVGContext ctx -> Backend_svg.show ctx shapes
| LazyContext ctx -> Backend_lazy.show ctx shapes
+let clear ?ctx _ =
+ let ctx = match ctx with Some ctx -> ctx | None -> get_default () in
+ match ctx with
+ | CairoContext ctx -> Backend_cairo.clear ctx
+ | SVGContext ctx -> Backend_svg.clear ctx
+ | LazyContext ctx -> Backend_lazy.clear ctx
+
let set_line_width ?ctx int =
let ctx = match ctx with Some ctx -> ctx | None -> get_default () in
match ctx with
@@ -32,10 +39,18 @@ let writePNG ?ctx filename =
raise (Unsupported_output_format "SVG context cannot render to PNG")
| LazyContext _ -> failwith "Lazy.writePNG ctx filename"
-let writeSVG ?ctx _ =
+(* let writeSVG ?ctx _ =
let ctx = match ctx with Some ctx -> ctx | None -> get_default () in
match ctx with
| CairoContext _ ->
raise (Unsupported_output_format "Cairo context cannot render to SVG")
| SVGContext ctx -> Backend_svg.write ctx
- | LazyContext _ -> failwith "Lazy.writeSVG ctx"
+ | LazyContext _ -> failwith "Lazy.writeSVG ctx" *)
+
+let makeSVG ?ctx _ =
+ let ctx = match ctx with Some ctx -> ctx | None -> get_default () in
+ match ctx with
+ | CairoContext _ ->
+ raise (Unsupported_output_format "Cairo context cannot render to SVG")
+ | SVGContext ctx -> Backend_svg.make_svg ctx
+ | LazyContext _ -> failwith "Lazy.makeSVG ctx"
diff --git a/lib/context.mli b/lib/context.mli
index 9b08a84..a3a57b5 100644
--- a/lib/context.mli
+++ b/lib/context.mli
@@ -8,7 +8,9 @@ exception Unsupported_output_format of string
val get_default : unit -> context
val set_default : context -> unit
-val show : ?ctx:context -> Shape.shapes -> unit
+val show : ?ctx:context -> Shape.shape list -> unit
+val clear : ?ctx:context -> unit -> unit
val set_line_width : ?ctx:context -> int -> unit
-val writeSVG : ?ctx:context -> unit -> string
+
+val makeSVG : ?ctx:context -> unit -> string
val writePNG : ?ctx:context -> string -> unit
diff --git a/lib/dune b/lib/dune
index 4790058..c4b408d 100644
--- a/lib/dune
+++ b/lib/dune
@@ -1,4 +1,5 @@
(library
(name joy)
(public_name joy)
- (libraries cairo2))
+ (preprocess (pps js_of_ocaml-ppx))
+ (libraries js_of_ocaml))
diff --git a/lib/joy.ml b/lib/joy.ml
index a1f794d..ebfcd2a 100644
--- a/lib/joy.ml
+++ b/lib/joy.ml
@@ -1,4 +1,3 @@
-include Random
include Shape
include Transform
include Color
@@ -8,9 +7,14 @@ module Backend_cairo = Backend_cairo
module Backend_svg = Backend_svg
module Backend_lazy = Backend_lazy
+let random = Random.random
+let frandom = Random.frandom
+let fractal_noise = Random.fractal_noise
+
type context = Context.context
let show = Context.show
+let clear = Context.clear
let set_line_width = Context.set_line_width
let init ?(size = (500, 500)) ?(line_width = 1) ?(axes = false) _ =
@@ -34,8 +38,8 @@ let init ?(size = (500, 500)) ?(line_width = 1) ?(axes = false) _ =
in
show ~ctx:ctx_container [ x_axis; y_axis ]
-let init_svg ?(size = (500, 500)) ?(axes = false) _ =
- let ctx = Backend_svg.create ~size ~axes in
+let init_svg ?(size = (500, 500)) ?(axes = false) eltId =
+ let ctx = Backend_svg.create ~size ~axes ~eltId in
let ctx_container = Context.SVGContext ctx in
Context.set_default ctx_container;
if axes then
diff --git a/lib/joy.mli b/lib/joy.mli
index 4aca9d2..3437b17 100644
--- a/lib/joy.mli
+++ b/lib/joy.mli
@@ -22,10 +22,6 @@ val translate : int -> int -> transformation
val scale : float -> transformation
val compose : transformation -> transformation -> transformation
val repeat : int -> transformation -> transformation
-val random : ?min:int -> int -> int
-val frandom : ?min:float -> float -> float
-val noise : float list -> float
-val fractal_noise : ?octaves:int -> float list -> float
val with_stroke : color -> transformation
val with_fill : color -> transformation
val map_stroke : (color -> color) -> transformation
@@ -38,8 +34,14 @@ val blue : color
val yellow : color
val transparent : color
val rgb : int -> int -> int -> color
+val color : ?a:float -> int -> int -> int -> color
val init : ?size:int * int -> ?line_width:int -> ?axes:bool -> unit -> unit
-val init_svg : ?size:int * int -> ?axes:bool -> unit -> unit
+val init_svg : ?size:int * int -> ?axes:bool -> string -> unit
val write : ?filename:string -> unit -> unit
val show : ?ctx:context -> shapes -> unit
+val clear : ?ctx:context -> unit -> unit
val set_line_width : ?ctx:context -> int -> unit
+
+val random : ?min:int -> int -> int
+val frandom : ?min:float -> float -> float
+val fractal_noise : ?octaves:int -> float list -> float