< Open Source Library / >


npm run case_study

VueXYZ is a collection of Vue 3 composables for creative coding.

VueXYZ is a new approach to creative coding using Vue’s reactivity to return data, unlike most creative coding libraries that directly draw to a canvas. Back in the day, such as when I was working on The Engine @ MIT, I found myself repeating a lot of logic and math. The challenge was that while these aforementioned libraries existed, a lot of the time I was needing to instead position DOM elements on the screen using some level of geometry data, which may need to be shared between Vue components.

I’ll skip most of the details comparing approaches, but if you’re interested here’s the initial article I posted when I open-sourced this library.

This project is something I’ve wanted to put together for a while, and it’s been brewing under different names during that time. I initially called it “Vue Ricochet”, as I described my day job to anyone who asked as “bouncing objects around the screen”. After all, if you tell people you’re a “creative frontend engineer”, you’ll often just get blank stares.

Vue Ricochet used a component-driven approach that implemented a custom renderer in Vue’s lifecycle. It would take any DOM passed within the slot of a Vue component and arrange those elements equidistantly along the edge of a defined shape. For example, you could pass in 10 images and tell it to arrange those in a circle, or along an arc. This approach worked well, but seemed a little short-sighted. It didn’t feel feature-complete, or anywhere near as flexible as I wanted it to be - it solved a very narrow need.

Creative programming.
The homepage demo, showing diagram-style shape outlines transforming into realized polygons.

Then, along came Vue 3’s composable architecture. Switching from the options API to the composition API and taking on the mindset of working with composable chunks of logic just made perfect sense for this type of library. So the idea was born that VueXYZ could be a collection of composables, allowing developers to pick and choose what they needed. This felt like a missing portion of the VueUse library - in fact, I did initially submit this as a PR for a new add-on, although antfu was sunsetting new feature additions at the time. That said, he was very gracious in his response, and that was appreciated 🙌

So I decided to continue to move forward and split it off into it’s own library. The idea ended up being simple - to focus on geometry. I’d argue most creative coding is based around generating and manipulating geometry, and that’s what VueXYZ is for and it’s core. Vue’s reactivity adds a fun and tangible layer of interactivity to that which other creative coding libraries don’t have - I can have geometry that reacts to other data, seamlessly. Or, I can pass geometry through multiple utility methods to manipulate it before using it various ways in different components. If I change the input (say, the number of vertices in a polygon) it’ll all flow downstream through Vue’s reactivity, making highly-generative artwork a reality. Canvas, SVG, WebGL, DOM, it doesn’t matter- VueXYZ provides the data, you do with it what you want.

Creative programming.
A demo from VueXYZ.org, showing a rotating polygon, while highlighting a point around the edge of the polygon as it spins.

It took a few weeks to get the initial subset of features in place, mostly a collection of 2D primitive composables, such as useCircle or usePentagon figured out logically. But there was an inflection point, and the library really started coming together once I locked in exactly how these composables would return data. You see, I wanted to standardize all primitives to simply generate vertices, edges and faces so that they could all be expanded upon with utility methods. This was slightly more challenging than expected, as circles are defined very differently than squares - but ultimately things became more and more consistent.

One of my proudest technical approaches is the way edges work. You see, every single primitive can be described as a series of edges that are either line segments or cubic Bezier curve segments. From here, utility methods such as finding point n along a single edge can be developed, and from there we can extrapolate to full utilities like usePointOnPrimitive that are capable of taking a percentage value and positioning a new vertex anywhere along the edge of a primitive shape. It doesn’t matter if you’re drawing a triangle, an arc, or an irregular polygon - this approach just works. Vue’s reactivity really shines here, as when the polygon data changes, or the percentage value changes, you get back the new positional vertex immediately, in real-time, to use however you want.

Creative programming.
A demo from VueXYZ.org showing how easy it is to reactively position DOM elements in unusual layouts.

Which brings me to rendering. I quickly found out that while VueXYZ is not rendering-focused, you can’t have a documentation site talking about these concepts without visually showing them. At the same time, there’s many ways people can choose to use these composables, and I didn’t want it to be difficult to choose to render to canvas, or to SVG, should they want to. Thanks to the edges definition above, it was straightforward to put together svgPath and drawToCanvas methods to greatly simplify that process.

On top of that, to resolve my initial needs of positioning DOM elements based on this data, I added a useStyleTransform composable. This is probably one of my favorite implementations. It takes any vertex, from anywhere, and returns a style tag that can be binded to a DOM element. The tag adds position: absolute and then uses transform: translate3D(...) to position the element based on the input vertex. It works like a dream. Combine that with other utility methods and it’s suddenly easy to position a DOM element along an arc, and animate both the arc and the position of the element in interesting and creative ways.

Creative programming.

While still relatively new (60 GitHub stars at the time of writing this), I hoping the library can be useful to the Vue community in the long run. I plan to continue to build it one composable at a time, and write/talk about it’s potential usages publicly as it grows. It doesn’t have to be a massively impactful tool - just useful enough for anyone who would otherwise need to figure out the math themselves. I would love to see any demos of what people make with VueXYZ, and hopefully this will inspire others to think outside of the box, whether that’s in regular UI work or in using Vue to create digital artwork and interactive experiences.

If you’re interesting in learning more, I’ve put together a detailed documentation site with a handful of smaller demos at https://vuexyz.org. Feel free to reach out if you have any ideas or want to contribute, your input would be welcome!