Code Explanation
The code for this project consists of two python files code.py and card_maker_helpers.py, as well as two template files card.template.html and snowflake.template.svg.
card_maker_helpers.py
This file contains several helper functions as well as a class which are all imported and used by the code.py file. Helper functions:
-
svg_points()Converts points from alistoftuplesinto a string that is in SVG polygon comma separated syntax. -
distance()A simple distance calculation to determine how far apart two points are. -
random_polygon()Generates and returns the points for a random polygon. Special care is taken inside this function to not generate any line segments that intersect with existing segments chosen for the random polygon. This ensures the shape doesn't cross back over itself. -
fill_polygon()Draws and fills in the given polygon in the providedBitmapusing the specified color. -
draw_snowflake()Draws all of the polygons that make up a snowflake in the providedBitmap.
There is also a class PointHighlighterCache which provides a pool of small crosshair images to be placed in the snowflake maker screen at the points where the user clicks the mouse.
This class ensures that only as many highlighters as are needed get created. It re-uses any existing ones before creating new ones.
The first point gets colored green and the rest are black. Once the first point is clicked again it will close the shape and draw the polygon.
Template Files
The two template files are meant to be used with the adafruit_templateengine library. The library allows code to fill in specified parts of the templates using data that was generated dynamically, in our case by the user drawing their snowflake, and entering the card messages and other options.
snowflake.template.svg is an SVG image file. SVG files are actually just plain text XML files that contain geometry data about what shapes to draw. This template contains a for loop that draws 4 copies of each polygon from a list. The main copy in the top left is drawn in its normal orientation, the other copies are mirrored vertically and/or horizontally to create the snowflake patterns. CircuitPython doesn't support viewing SVG files directly, but web browsers do.
card.template.html is an HTML web page greeting card template. The page uses CSS to be laid out in 4 quadrants that add up to the size a plain sheet of paper. Two quadrants are mirrored vertically to account for the folds that will be made to the card after printing. The front image file, front message, and inside message all get filled in with values that are entered or selected on the card setup page.
code.py
The main project code file is responsible for the high level functionality and behavior of the app. It sets up all of the visual elements, adding them into two separate Groups. One Group for the card setup screen, and another for the snowflake maker screen. A PageLayout is used to easily change between the different screens.
Card Setup Screen
In the main loop, the code checks the keyboard and mouse for input events and reacts to them according to which screen is showing and whether any of the input boxes have focus. CheckBoxes are toggled when they get clicked. Input boxes will get focus when clicked, and will add typed characters to the end of their input if they have focus.
When the generate button is clicked, the following tasks occur to prepare the card file:
- Validation to ensure a front image has been selected.
- If the user opted to use a snowflake image for the front, the snowflake.svg file is rendered from the polygons drawn in the snowflake maker screen. The file gets written to the CPSAVES drive.
- If one of the custom image files is selected, that file gets copied from CIRCUITPY to CPSAVES.
- If the front emoji checkbox is checked the front message is appended together with the emoji characters.
- The card HTML template is rendered using data entered by the user. The card.html file gets written to the CPSAVES drive.
- All of the card details are also stored as JSON in the file card_data.json in CPSAVES. When the app launches it will check for this file and try to load the data from it to let the user resume from the last card they made.
The last button is for remounting the CPSAVES drive to the computer. This is used after the card has been generated to refresh the files visible to the PC. CPSAVES uses the FAT filesystem which does not contain support for notifying the host of changes to files, so this manual unmount/eject and then remount process ensures that the PC can see the latest version of the generated files.
When the snowflake maker screen is showing, the mouse will be restricted to the top left corner of the snowflake. Clicking the mouse will drop a point highlight at the location clicked. After clicking a few more points and then clicking back on the first point again, the polygon will be closed and then drawn and filled in. The polygon shapes automatically get duplicated and mirrored using 3 more TileGrids with their flip_x and flip_y properties to handle the mirroring.
A Label on the right acts as an info pane showing a few keyboard keys shortcuts and basic instructions for drawing a snowflake.
Page last edited December 22, 2025
Text editor powered by tinymce.