Innovative SVG Creations with ToolipsSVG: A Journey Ahead
Written on
Chapter 1: Introduction to ToolipsSVG
At the moment, I'm in the midst of rapidly developing numerous packages. This month has seen the launch of Toolips 0.3, along with its first extension, ToolipsSVG. I'm also nearing the completion of ToolipsSession 0.4 and a patch for Toolips 0.3.1, which offers further enhancements to the package. It's a considerable amount of work, and quite time-consuming. My development is primarily divided into two paths: one beginning with ToolipsServables and concluding with Gattino, while the other starts with ParametricProcesses and culminates in Olive.
ToolipsServables > ToolipsSVG > Gattino
ParametricProcesses + ToolipsServables > Toolips > ToolipsSession > Olive
Although there are additional packages involved, these pathways illustrate the significant milestones toward finalizing the initial three sections of the ecosystem: Toolips, Olive, and Gattino. Currently, my focus is entirely on completing ToolipsSession 0.4. Once that's finished, I’ll be wrapping up Gattino and reworking the deprecated ToolipsMarkdown TextStyleModifier into a new Olive dependency for syntax highlighting.
As for Gattino, we are incredibly close to its release. Both ToolipsServables and ToolipsSVG are fully functional and ready to go, allowing me to launch Gattino in the near future. I’m excited about this development; few visualization libraries offer this level of customization and introspection. Additionally, having it directly connected to templating syntax and a full web-development framework is fantastic. This will greatly benefit my projects, particularly in creating dashboards and management APIs within the Toolips web applications I’m working on.
The first video, titled "SVG File - Tulip Flourish Card - Assembly Tutorial (Cricut, Silhouette, ScanNCut)", showcases how to assemble an intricate SVG design. This resource is perfect for anyone interested in practical applications of SVG in crafting and design.
Chapter 2: Exploring ToolipsSVG's Potential
To better understand the capabilities of the Gattino package before its launch, it’s beneficial to explore what ToolipsSVG can achieve independently. My passion for art and graphic design influences much of my work, and I strive to integrate these artistic elements into my software through its Graphical User Interface. One of the most effective tools for this interactive art is the Scalable Vector Graphics (SVG) format, which can be rendered in web browsers alongside HTML elements.
The main goal of ToolipsSVG is to support Gattino, but I also envision using this extension for various other applications involving SVG. One such project that has lingered in the background is Vulta—a basic SVG engine for Julia based on RPC. My aim with Vulta is to develop simple games, such as a web-based version of checkers, to demonstrate its capabilities and provide a foundation for others interested in exploring this technology.
Every package I develop has its own story. Having spent considerable time on these larger projects, I draw from my extensive experiences in creating similar software in the past. Gattino directly evolves from a previous project called Prrty, which in turn was inspired by Hone. Interestingly, Toolips and Olive originated from a single project called Jockey, a notebook editor with its own web server. This project has transformed over the years into Toolips, a robust and extensible server-development framework capable of powering both the new Olive and any other projects I envision, including a DNS server, proxy server, and several full-stack web apps and APIs.
I also see ToolipsSVG as a vital component of OliveCreator. Many readers likely know that this is a personal project I’m deeply passionate about, and I plan to surround it with the SVG art that has represented my journey for so long.
As we proceed, it’s clear that 2024 promises exciting advancements in this area. Although ToolipsSVG's offerings might seem straightforward, the potential applications of this compact API are quite significant, especially within the contexts I intend to explore.
The second video, "Pretty Paper Tulip Flower Tutorial (Rolled Flowers)", provides a delightful guide to crafting rolled paper flowers, showcasing the artistic possibilities of SVG design.
Chapter 3: Working with ToolipsSVG
Using ToolipsSVG is akin to working with standard Toolips components, allowing for seamless composition and styling. Here's a simple example of using ToolipsSVG to create an SVG window and add a circle:
new_window::Component{:svg} = svg(width = 500, height = 500)
newcircle::Component{:circle} = circle(cx = 250, cy = 250, r = 20)
style!(newcircle, "fill" => "blue")
push!(new_window, newcircle)
display("text/html", new_window)
Let’s get creative! In the following example, I’ll employ a loop to draw a grid of circles, each colored based on divisibility:
wind = svg("sampwind", width = 100, height = 100)
CHANGEME = 2
CHANGEME2 = 10
CHANGEME3 = 7
function draw_space(x::Int64, y::Int64)
circ = circle("$x-$y", r = 1, cx = x, cy = y)
if x % CHANGEME == 0 && ~(x % CHANGEME2 == 0)
style!(circ, "fill" => "red")elseif y % CHANGEME2 == 0
style!(circ, "fill" => "green")elseif x % CHANGEME3 == 0 || y % CHANGEME3 == 0
style!(circ, "fill" => "orange")else
style!(circ, "fill" => "blue")end
push!(wind, circ)
end
current = [0, 0]
while current[2] < 100
if current[1] == 100
current[1] = 0
current[2] += 1
end
current[1] += 1
draw_space(current ...)
end
wind
Let’s design the Julia logo next:
w, h = 250, 250
window = svg("julia_over", width = w, height = h)
each_w = (w - 10) / 3
each_height = h / 2
circs = [begin
circ = circle(cx = (each_w * e), cy = each_height, r = 10)
style!(circ, "fill" => "#$color")
circ
end for (e, color) in enumerate(("D5635C", "60AD51", "AA79C1"))]
window[:children] = Vector{AbstractComponent}(circs)
window
Since ToolipsSVG is based on ToolipsServables, we can easily add client events to these visuals. For instance, the following demo features a box that moves when we click on the visualization:
# create the window
window = svg("julia3", width = w, height = h)
style!(window, "transition" => 2s)
nothing
# create the rect
myrec = rect("samp-rect", width = 50, height = 50, x = 25, y = 90)
style!(myrec, "stroke-width" => 2px, "fill" => "lightblue", "stroke" => "#333333", "transition" => 2s)
push!(window, myrec)
nothing
# bind the rect
ToolipsSVG.ToolipsServables.on(window, "click") do cl
cl["samp-rect"] = "x" => 160
style!(cl, window, "background-color" => "black")
end
Another intriguing feature of ToolipsSVG is the shape interface, which is a typed parametric interface for managing various shapes. We can easily convert between different shapes using the set_shape function:
window[:children][1] = set_shape(myrec, :star)
Additionally, the package provides a set_size! and set_position! interface for consistently adjusting the size and shape of any component. The final noteworthy feature is the Component{:path} interface, which simplifies drawing custom paths in Julia. Here’s a straightforward example of creating a square:
squarepath = path("new-square")
M!(squarepath, 50, 50)
L!(squarepath, 100, 50)
L!(squarepath, 100, 100)
L!(squarepath, 50, 100)
L!(squarepath, 50, 50)
Z!(squarepath)
svg(width = 150, height = 150, children = [squarepath])
For those with a bit more SVG knowledge, here's a more complex example creating a heart shape:
cuteheart = path("heart")
M!(cuteheart, 12, "21.593c-5.63-5.539-11-10.297-11-14.402",
"0-3.791 3.068-5.191 5.281-5.191 1.312", 0, "4.151.501",
5.719, 4.457, "1.59-3.968", "4.464-4.447",
"5.726-4.447", 2.54, 0, 5.274, 1.621, 5.274, 5.181, 0,
"4.069-5.136 8.625-11", "14.402m5.726-20.583c-2.203", "0-4.446 1.042-5.726 3.238-1.285-2.206-3.522-3.248-5.719-3.248-3.183",
"0-6.281", "2.187-6.281", 6.191, 0, 4.661, 5.571, 9.429, 12, 15.809, "6.43-6.38 12-11.148 12-15.809",
"0-4.011-3.095-6.181-6.274-6.181")
display("text/html", ToolipsSVG.h3(text = "thank you all for reading friends :)", align = "center"))
display("text/html", div("-", align = "center", children = [svg(width = 25, height = 25, children = [cuteheart])]))
Chapter 4: Concluding Thoughts and Future Developments
There remains a significant amount of work ahead—numerous projects to complete this year. I'm committed to assembling a remarkable suite of tools. Recently, I've released various updates, from Toolips 0.3 to multiple extensions, and I'm gearing up for the Gattino launch next month. Currently, I’m finalizing ToolipsSession for the 0.4 release, after which I’ll focus on Gattino 0.1. Although the journey still seems lengthy, it’s steadily becoming more manageable. With Gattino's release, I’ll return to Olive while continuing to push forward with all my ongoing projects.
My mission is to demonstrate the value of what you’re following me for—exciting projects are on the horizon for the community. I've invested significant effort into building this community and the necessary infrastructure to create an engaging environment for all of us. The support I receive is heartening, especially during overwhelming times. My focus has shifted towards generating as much art as possible with minimal licensing restrictions. Although many of my works fall under the Medium Partner Program, they are also Creative Commons licensed, allowing for sharing and engagement.
Ultimately, my goal is to create work that resonates with and enhances the lives of others. The essence of creation lies in the attention and appreciation it garners. My ambition is to contribute enduring art, prioritizing creativity in a collaborative framework.
I'm thrilled as OliveCreator approaches realization. I eagerly await the day I can share links to this project in a blog post, enabling readers to learn, share, and collaborate remotely. The Julia package ecosystem has recently surpassed 10,000 packages, and I’m excited to see my contributions grow within this innovative programming language.
In closing, I'm looking forward to the release of ToolipsSession 0.4 and an invigorating phase of development for both Olive and Gattino. I appreciate your ongoing support and enthusiasm. Thank you for being part of this journey! ❤