svg
filters
commune
Me, Commune, Etc.

Me, Commune, Etc.

written by Ty Vek

12 Oct 2022100 EDITIONS
4 TEZ

Where to begin.

That's always the hardest part.

Fine, the name. We'll start there. Ty Vek.

Is it short for Tyler? No, that's too easy and we have enough amazing Tylers in generative art.

It's long for Tyvek, which is either a synthetic flash-spun high-density polyethylene fiber or a punk band from Detroit. Check out their song Frustration Rock. It's good if you're like me and enjoy noisy atonal music that threatens to fall apart at any moment.

In construction, though, they use the synth-fiber to wrap around houses to protect them while they are being built. You can also make clothing out of it. It's tear/water resistant and again, protects the wearer.

So, it's a bit of a metaphorical name in my case. Protection and anonymity are useful on the blockchain, especially when starting out. So for now, I'm going to continue with this pseudonym, stay off social media and focus on just making art and experimenting.

I understand you may be worried about copy-minters trying to fool you into minting for a quick buck, just to have the project flagged and your heart broken. That's not my goal and hopefully that will be clear in time. I've been burned by copy-minters too, and it hurts in a distinct way.

It's crazy out there, though, so if you don't trust this effectively anon account, I totally get it. We have all the time in the world to get there. We'll be best friends in no time, I can feel it.


A very minimal Commune.
A very minimal Commune.

So, why Commune(s)?

I'm going to outline building the project in the meandering paragraphs that follow, but the name came to me when I was just playing with the composition and it started to feel a bit like floor plans, so I leaned into that a bit... which inevitably made me think of communal living because I'm low-key always thinking about communal living and plotting with my friends to move into a mountain compound and live off the land and blah blah blah here we are, naming a collection after this fantasy that should never happen because I have no idea how to farm.

Before I landed on this as a subject, though, this was just an exercise to create a project from scratch in vanilla javascript. I liked the idea of art on the blockchain having less dependencies so this seemed like the way to go, which isn't to say I'm anti-library or anything like that. I love them. I've used p5 a lot. Maybe I'll use it or another library in an upcoming project, or not. I make no promises except that there will be more after this, even if there is no Twitter account.

This Commune is pretty Bauhaus-y.
This Commune is pretty Bauhaus-y.

Constraints are a good thing, and I wanted to keep this project pretty minimal... so I limited myself to just using rectangles as elements, and put the real work into coercing the logic to ensure compositional diversity between outputs while still enjoying aesthetic consistencies.

I take these rectangles and lightly shape them with SVG filters to give them a slightly more organic, fluid feel. I didn't want perfect angles or lines that felt too rigid or cold. I wanted it to look closer to painting freehand with a wide brush or even a roller, with inevitable drift that give it a "feel," so the feTurbulence & feDisplacementMap filters were mixed in. Not too much, though, it can get wild in a hurry with those two. Alternatively, I could've used a shader here, but I wanted to limit the moving pieces and stuck to what's available via SVG.

The SVG is then loaded into an Image object which is then drawn to a canvas. I grab the raw pixels from that canvas and manipulate them to add some texture. The default texture resembles film grain but if you add "&g=w" to the url in the live view, you get a more wood-like texture. If you want it without the texture, you can use "&g=n" instead and this step is skipped.

A Commune with "&g=w" added to the url to get that wood-like texture
A Commune with "&g=w" added to the url to get that wood-like texture

The resulting minified code for Commune is less than 3000 bytes and has no dependencies. For those interested, here's some boilerplate code to set up a Vanilla JS project that creates an SVG and writes it to a canvas. This is the simplest version I could come up with but there's always a better way. Feel free to use it if you like.

// boilerplate: this kicks of setting up the canvas and grabbing the svg to draw there
// it also handles the keystrokes. 

// some terse function defs to make the webpacked code even smaller.

// create element
const cEl = (elName, ns) => {
  let el = document.createElementNS(ns, elName);
  if (ns) {
    el.setAttribute("xmlns", ns);
  }
  return el;
}

// add attribute to element
const aAtt = (p, n, v) => {
  p.setAttributeNS(null, n, v);
}

// append child element
const aEl = (p, c) => {
  p.appendChild(c);
}

// the canvas we draw the svg to
let canvas = null;

// the fake download link we use for key commands
const aDownload = document.createElement('a');

// callback to start rendering after the page loads.
window.addEventListener('load', function () {

  // create the canvas to draw to later
  canvas = document.createElement("canvas");
  aAtt(canvas, wString, CANVAS_WIDTH);
  aAtt(canvas, hString, CANVAS_HEIGHT);

  // attach canvas to your div with the id="cw"
  let canvasWrapper = document.getElementById("cw");
  aEl(canvasWrapper, canvas);

  // makeSvg() is the function that creates the SVG elements.
  // you can also just assign a svg string if you don't want to use the DOM to build it
  let outerHTML = makeSvg().outerHTML;

  // create a blob of the svg so you an assign it to an image to load it
  // (the last line of this snippet triggers the load, don't miss it)
  let blob = new Blob([outerHTML], { type: 'image/svg+xml' });
  let URL = window.URL || window.webkitURL || window;
  let blobURL = URL.createObjectURL(blob);

  // create an image to render the SVG
  let image = new Image();
  
  // and a callback for after the image loads/renders
  image.onload = () => {
  
    // draw the svg to the canvas after image loads
    let context = canvas.getContext('2d');
    context.drawImage(image, 0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);
  
    // let the svg render and then add noise (optional)
    // we do a timeout so the art can display before adding texture/grain
    // setTimeout(function () { afterDraw(context) }, 1);
  
    // add keystroke listener to save the images as svg or png.
    document.body.addEventListener('keypress', function (e) {
      if (e.key == "s") {
        aDownload.download = `${fxhash}.svg`
        aDownload.href = blobURL;
        aDownload.click();
      }
      if (e.key == "p") {
        var pngUrl = canvas.toDataURL('image/png');
        aDownload.download = `${fxhash}.png`
        aDownload.href = pngUrl;
        aDownload.click();
      }
    });
  };

  // start rendering the svg into this image
  image.src = blobURL;

While I'm not going to include the makeSvg() function that Commune uses because I don't want to make it too easy for copy-minters, here's a simple one that creates an empty SVG element with a background that you can use as a starting point:

// make a simple svg
const makeSvg = () => {

  var svg = cEl('svg', 'http://www.w3.org/2000/svg');

  // create the root svg node
  aAtt(svg, 'version', '1.1');
  aAtt(svg, 'viewBox', `0 0 ${WIDTH} ${HEIGHT}`);
  aAtt(svg, 'width', WIDTH);
  aAtt(svg, 'height', HEIGHT);

  // add a red rect for the background
  var background = cEl('rect');
  aAtt(background, 'width', '100%');
  aAtt(background, 'height', '100%');
  aAtt(background, 'fill', '#f00');
  aEl(svg, background);
  
  // add more elements here to make art

  // return the svg element
  return svg;
}

This will make a SVG that is all red. Wild. Waiting to be Signed is gonna gush and shout you out on their next episode. Ok maybe not, but it's an easy blank canvas to play with.

While I didn't intend to write a little SVG tutorial, here we are. It's not all that complicated but hopefully this can provide a bit of help if you were interested to trying this approach.


I know this didn't explicitly reveal my identity, but hopefully its enough to convince you I'm not a copy-minter or some other type of bad actor. I know projects from accounts without attached socials and no previous projects can be a little suspect, so I hope this eases your worries. If not, wait for the next project, or the one after that. Or, worry forever, it's your life.

Thank you so much for reading. You're great.

Commune comes out Wednesday, October 12 at 17:00 UTC.

project name project name project name

*Note: If you try to share this article on Twitter or Discord, the links will probably fail because the "." wasn't stripped from the title when fxhash creates the slug and Twitter and Discord don't treat those as part of the url, but as simple punctuation. So, just tell people to add a period at the end of the url in their browser if they are having problems or use this url: https://www.fxhash.xyz/article/me-commune-etc%2E

stay ahead with our newsletter

receive news on exclusive drops, releases, product updates, and more

feedback