I'm a knitter. It's one way of expressing my creativity and also passing the time. And it's sometimes super relaxing. And I (and people around me) get to wear some nice, warm, self-made garments.
One ongoing project is that I've knitted some Riddari-sweaters as presents to some of my close ones when they turn 30. Usually, I've just decided on the colors myself, but this time I wanted to ask from the recipient for their color choice.
So, I could have tried to find some pictures of the sweater in potential colors. But there was a chance that I couldn't find those. And it takes some imagination to try to think how some colors play together if you only see a picture of the yarn ball and the sweater in random color. Trust me; I've bought some new yarn in the middle of making a sweater because what I was knitting was not what I had imagined.
I needed a way of visualizing the colors somehow. And thus, the idea for my next project was born. In this blog post, I'll introduce you to Neule.art, a color picker or color visualizer for the Riddari sweater (among other patterns), and how I created it.
If you're interested in the code, you can find it from the Neule.art repository. The code is nowhere perfect, and I know I could polish it a lot, but my goal has been just to get it out and then, maybe at some point, improve the code quality.
The Planning and Decisions
So, I began pondering how to create this site or app. I instantly started thinking about using SVGs for the visualization, as you can manipulate the colors of an SVG pretty straightforwardly.
Another thing to decide on was the technologies. What should I use? React? NextJS? Something else? I wanted to build a page with the least possible amount of JavaScript, so I decided to go with Eleventy. That's a framework I've used before, and my website, for example, is built on Eleventy.
I'm a bit bored with JavaScript and wanted to try if I could build the site without any client-side JS. As Eleventy is a static site generator, this is possible. Even though I use JS for development, the result can be without JavaScript - if I want it that way. But how can the site manage changing colors? Eleventy Serverless and HTML forms to the rescue.
Let's talk next about how I implemented the different components mentioned above.
Getting the SVG
SVG was a great idea, but there was a problem: there were no SVGs for the Riddari-sweater I knew of. First, I thought about drawing the sweater. It sounded like a great plan - until I remembered that I'm not much of an artist. So no drawing.
After spending some time on the internet, I came across image tracing. That sounded like a plan, and after finally purchasing Procreate on my iPad and playing around a bit, I started tracing the shirt. It looked awesome.
It was just that there was no SVG export from the Procreate app. What do? Well, the thing I do best: search for answers. After some time, I had installed Inkscape, and after trial and error, I finally had the shirt in SVG, where it was possible to manipulate colors by CSS.
Building with Eleventy
Building the site could have been a tricky part. Fortunately, I had experience with Eleventy, specifically with serverless functions and Eleventy.
I also wanted to use HTML to its total capacity - in this case, it means using forms and form actions. I also didn't want to use JS on the site unless it was absolutely necessary. And spoiler alert: I didn't have any client-side JS in the first version of the site. Okay, I use Eleventy (which is, indeed, a JavaScript library) for building the site, but everything works with HTML in the production site.
At the time of writing, I'm building some progressive enhancements to change the colors dynamically without reloading the page. However, I still keep in mind those who don't want to or can't have JavaScript enabled in the browser.
But back to the process. I started building the site.
First, I created a static site, showing the SVG of the shirt with default values. Then I added the Eleventy Serverless plugin and dynamic path to the site displaying the SVG. This way, I could pass the four colors for the shirt as a query parameter.
Using the Native HTML Form
Once I had done that, adding the form was the next step. If you're unfamiliar with HTML native forms, they work so that when you hit "send" (or whatever the primary action is), they send the values from the form as an object to the URL you've defined in the action
-attribute. And if you use the "get"-method, you get the values as query parameters - which is perfect for what I was doing.
So, here's a code snippet I'm using in the project (I edited it and stripped away all Nunjucks-syntax I use for passing the data for clarity):
<form method="get" action="/en/colors/" class="colors-form">
<label for="color-a">A (Main color):</label>
<select id="color-a" name="a">
<option value="0059" selected>Black (0059)</option>
<option value="9423">Lagoon (9423)</option>
<!-- More color options -->
</select>
<!-- More color selects -->
<button type="submit">Check the result</button>
</form>
Getting the Data For Yarn Availability
Another thing I wanted to add to the site was a possibility to see if some selected stores had specific colorways available of the Lรจttlopi-yarn (which knitters often use for Icelandic sweaters). And by "selected," I mean stores I either knew have Lรฉttlopi on stock or were easily found on Google.
As I had this approach of not using client-side JavaScript, I needed to store the data in some way Eleventy could utilize it. Also, I didn't want to scrape the sites every time users visited my page. After some consideration, I wrote a function that runs once a day at night, which scrapes the available colors from the selected yarn stores' sites.
I use Github actions and cron job for running the function. It scrapes through the yarn pages in the stores, parses the data to JSON, and then saves the new values into a data file. Then the site gets rebuilt, using the updated data for yarn availability.
Writing the scraper was fun. I used cheerio to get and find the relevant data from the document on the yarn stores' websites. Then I parsed it with JavaScript to JSON. The fun in this was that every site has its way of annotating available yarn. Every store was a new puzzle to solve so that I get the relevant piece of information - which colors of the yarn were available and which were not.
If you go and check the getColors.js-file, you can see that I've been using different techniques for different stores. Sometimes it used an id, sometimes Regex, sometimes splitting the string from specific places, and sometimes looking for a class name.
When I had the yarn data available, I just needed to use it. And then, I had all the pieces together and had the MVP (minimum viable product) ready for publishing.
Publishing
As I had decided to use serverless functions, and as Eleventy has instructions only for Netlify, it was pretty straightforward to use Netlify to host the site. Also, Netlify itself is relatively straightforward, so setting it up was fast - and the fact that I've used Netlify for many things in the past helped in that.
But the most challenging part of publishing the site was to buy the domain - or, rather, decide the domain name for the site. After pondering (and reading the list of possible top-level domains) for some time, it hit me. "Neule.art!" It's perfect. "Neule" means knit garment in Finnish, and hey, knitting is art. Also, from the beginning, I had plans to add other patterns than Riddari to the site, so I didn't want to use Riddari for the domain name.
I bought the domain, spent some time figuring out all the DNS stuff, and finally, the site was live! I was so happy. You know, it's not always obvious that one gets their side project published. I've started so many projects I've never finished, so it feels good to complete something finally. And that it is something I feel proud of and can share.
Sharing the Site
I shared the site with some of my friends, and their response was encouraging. So, I decided to share the project on LinkedIn. Suddenly, it got so many comments and likes, and someone shared it on Facebook's Icelandic sweater/yarn-related groups. On the first day, I got a couple of thousands of visits (it's a lot for me and a niche page).
What was super encouraging were the comments and feedback people shared with me. I was solving a problem for myself - and solved it for many others at the same time. It feels great to be able to help.
What I've Added After the Launch
I launched the site in mid-May. I've been working to improve it since then. I've added a possibility to generate random colors, added a version of the Riddari-sweater where users can change color for every motif (instead of the original pattern's four colors), and added a new yarn store (Lanka-Kaisa).
I've also done a lot of under-the-hood fixes and features, such as adding cypress tests, fixing bugs, and improving the SEO of the website.
The Future
I have plans to add more patterns and yarns to the site. Also, as mentioned, I'm working on improving the user experience by providing the possibility to change colors dynamically.
Also, I'm happy to hear ideas and feature requests to the site - you can either contact me (hello@eevis.codes) or send a feature request through Github.
Top comments (4)
Enjoyed reading this.
Liked how you were able to break-down every part of the project and explain the thoughts behind the decisions you made.
I think, the second to the sixth headings could make great independent technical reads. Especially if you confine them to the scope of building this project.
Now, regarding Riddari sweaters (a topic I know nothing about), what are the rules on colors?
If, and only if, the sweaters can't be composed of a single color throughout, that would be a nice little feature to add.
Or, you might just decide to be opinionated and force us to choose a guided color combination so you can rescue us from composing ugly sweaters.
But then again, ugly sweaters might be what people want.
You could add a guided feature so to speak. I would love to see the algorithm behind that.
But, I'm not so sure such a feature would be possible without JavaScript.
Congrats on building this interesting project. It's not easy to tell what a great deal of steps and acumen it takes to build such a "simple" site, especially when viewed from the published side.
Thank you! Maybe one day, when I have enough time, I'll write a series of blog posts about this project ๐
And for the colors of Riddari; to my knowledge, there are no specific rules. In theory, you could use just two different colors to make some version of the pattern in the yoke visible, but I'd use at least four colors so that the patterns in the sweater would look good. Some knit the sweaters with even more colors.
And when it comes to ugly sweaters - I believe that everyone sees beautiful and ugly in different ways, and there is no definition for ugly color combinations. One combination might seem ugly for me, and beautiful for you and vice versa. There might be some theoretical color combinations that are less ugly - but then again, beauty is in the eye of the beholder. So that's why it would be really hard to build a feature that would guide users to avoid so called ugly sweaters ๐ค Thanks for the idea though!
I loved this so much! This is now of the most beautiful side code projects I've ever seen, congrats!! I'll definitely be knitting a Riddari sweater of my own as soon as I finish the simpler one I'm working on right now, and for sure using Neule.art to figure out the colors!!
Thank you so much! And I'm so happy to hear that neule.art will be used ๐ค