I Built An NFT Whose Design Is Revealed On Mint

I Built An NFT Whose Design Is Revealed On Mint

HTML Canvas animations on the frontend convert to SVG data which is then stored on the Polygon blockchain.

I had this (amazing) science teacher in 7th grade named Mr. Wheeler who kept us all entertained with a steady stream of dad jokes. When he saw us making progress on something he'd say "hmmm ... moving left along", instead of "moving right along". Somehow that's stuck with me for 30+ years. And it's probably too much backstory to make it funny at this point ... BUT ... I've been hard at work on my NFT project and it's moving left along.

If you're new here, check out this overview first.

Interdimensional One is an interactive generative music player powered by NFTs. Each NFT is a unique instance of sound design and color, the NFTs combine together in a special web dApp. This blog post is about how the NFTs work, next post will dig deeper into the sound creation.

When I was planning out how I'd build generative ambient music, I was very much inspired by the (amazing) NDLR, a hardware sequencer I'd gotten lost in many-a-time.

I decided I'd break NFTs into 3 different sound categories. I'm going to detail it much more next time, but for now just try to get the basics.

1.jpg

  1. Drones: long drawn out notes that slowly evolve and mutate. Drones add bass and give the music a foundation upon which we we can build.
  2. Pads: Evolving chords played an octave higher than the drone. Pads give the music character.
  3. Rhythms: Shorter notes played in a repetitive pattern.

With sounds broken into three categories, I decided to break my NFTs into the same categories. When interacting with the web dApp, a user can have 1 drone, 1 pad and 2 rhythm NFTs that all play and interact with each other. In the case where users own more than one NFT in a given category, the dApp will crossfade between different pieces of sound design every so often.

In order to implement this structure in my smart contract, I decided to use three Structs.

2.jpg

  1. Collection: Basically an NFT drop. I imagined a situation where each Collection had its own unique look and feel. The bouncing dots UI I've been showing is the first UI, future collections will have their own (totally unique) version. To gain access to newer UIs, people will have to mint from that Collection. A Collection also contains a group of 30-50 instances of sound design that all work together. This way people can mint whatever they want from the Collection and it will sound good when played.
  2. Prototype: As I wanted to limit a Collection to only have sounds that work well together, I decided to allow for one color / sound profile to be minted more than once, basically an edition. A Prototype contains a color, a sound design profile, an edition size and a creator (so we can pay them).
  3. NFT: As each prototype can be minted more than once, I wanted to add something on mint to make sure no two items from the same Prototype are exactly the same ... so I decided to generatively create a design for that NFT at mint-time. That's the topic of this blog post.

Screen Shot 2565-08-11 at 17.07.11.png

I started out on the client side and built a JavaScript class called called GenerativeSpaceRenderer. The code uses HTML Canvas animations to generate an imaginary solar system.

The code starts with the main color defined by the Prototype, then picks a new (totally random) color and uses choma.js to generate a color palette from those 2 colors. I generate a palette larger than what I actually need so I can ignore the first few and last few colors, basically throwing away colors that are too close to my mains, thus giving me more variety.

The next step is to come up with a random number of orbits and planet distribution. I played around with some different techniques here, and then finally ended up using the same euclidean rhythm algorithm I use to generate rhythms in the music part of the project. The algorithm helps to spread out a series of notes and rests over a period of time, what's really cool is that in addition to creating something that sounds nice, it can also create something that looks nice. Since I'm randomizing color and orbital information at mint, I can be assured that no two NFTs will look the same. They will all reference the same sound design and master color, but will look unique.

drone (1).jpg

My last bit of client-side work was to create a reveal. In the animation loop of GenerativeSpaceRenderer, I finish each frame by writing over it with a solid color block. When the user clicks mint, I start to slowly lower the opacity of the top color block, which reveals the animation underneath.

Now that I've got a an HTML Canvas animation happening, I needed a way to freeze that animation and save it on the blockchain when a user mints an NFT. I decided to go back to my GenerativeSpaceRenderer class and add a new function that takes current positions of everything and converts to SVG data and then just pass that SVG data to my smart contract where it's stored in a Struct with other user data ... and since I'm building on Polygon, I'm able to store all that data for the low, low price of 0.12693155685 Matic / $0.12.

Now you may be saying to yourself "HEY LUKE! What happens if someone writes their own UI and just mints an NFT with whatever random SVG data they come up with". To which, I'd reply "ummm, yeah, I'm working on that":_)

I'm actually not totally sure that storing SVG data is the most efficient way to do this, I know it's cheap on Polygon, but it might actually be more efficient to re-do things using HTML Canvas NFTs, but I'm just learning about them now. Regardless of how I go forward with this, I thought it was a good experiment to implement things both ways and then talk about which way is best here.

With SVG data stored in the smart contract, I'm able to pull that data out in my dApp, and show it all on the Mixer page. Giving people access to the sounds created by their NFTs ... and since it's all this magical format on a magical blockchain, all those NFTs show up over on OpenSea too. Really cool, huh?

OK, more next week ... I'll be back with loads of sound design.

Screen Shot 2565-08-11 at 17.42.47.png