SVG Generative Art – CSG1 [Twilight]

SVG Generative Art – Generate by John Woi in Scalable Vector Graphics(SVG).

In HTML:

<?xml version="1.0" encoding="utf-8" ?>
<svg id="canvas" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"></svg>

<button class="btn btn-generate">
  <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#00f" viewBox="0 0 16 16"><path d="M1.161 8a6.84 6.84 0 1 0 6.842-6.84.58.58 0 1 1 0-1.16 8 8 0 1 1-6.556 3.412l-.663-.577a.58.58 0 0 1 .227-.997l2.52-.69a.58.58 0 0 1 .728.633l-.332 2.592a.58.58 0 0 1-.956.364l-.643-.56A6.812 6.812 0 0 0 1.16 8z"/><path d="M6.641 11.671V8.843h1.57l1.498 2.828h1.314L9.377 8.665c.897-.3 1.427-1.106 1.427-2.1 0-1.37-.943-2.246-2.456-2.246H5.5v7.352h1.141zm0-3.75V5.277h1.57c.881 0 1.416.499 1.416 1.32 0 .84-.504 1.324-1.386 1.324h-1.6z"/></svg>
</button>

<button class="btn btn-copy">
  <svg class="clipboard show" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#00f" viewBox="0 0 16 16"><path d="M4 1.5H3a2 2 0 0 0-2 2V14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3.5a2 2 0 0 0-2-2h-1v1h1a1 1 0 0 1 1 1V14a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V3.5a1 1 0 0 1 1-1h1v-1z"/><path d="M9.5 1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-3a.5.5 0 0 1-.5-.5v-1a.5.5 0 0 1 .5-.5h3zm-3-1A1.5 1.5 0 0 0 5 1.5v1A1.5 1.5 0 0 0 6.5 4h3A1.5 1.5 0 0 0 11 2.5v-1A1.5 1.5 0 0 0 9.5 0h-3z"/></svg>
  <svg class="clipboard-done" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#00f" class="bi bi-clipboard-check" viewBox="0 0 16 16"><path d="M10.97 4.97a.75.75 0 0 1 1.07 1.05l-3.99 4.99a.75.75 0 0 1-1.08.02L4.324 8.384a.75.75 0 1 1 1.06-1.06l2.094 2.093 3.473-4.425a.267.267 0 0 1 .02-.022z"/></svg>
</button>

<button class="btn btn-save">
  <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#00f" viewBox="0 0 16 16"><path d="M.5 9.9a.5.5 0 0 1 .5.5v2.5a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-2.5a.5.5 0 0 1 1 0v2.5a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2v-2.5a.5.5 0 0 1 .5-.5z"/><path d="M7.646 11.854a.5.5 0 0 0 .708 0l3-3a.5.5 0 0 0-.708-.708L8.5 10.293V1.5a.5.5 0 0 0-1 0v8.793L5.354 8.146a.5.5 0 1 0-.708.708l3 3z"/></svg>
</button>

<button class="btn btn-save-image">
  <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#00f" viewBox="0 0 16 16"><path d="M6.002 5.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z"/><path d="M1.5 2A1.5 1.5 0 0 0 0 3.5v9A1.5 1.5 0 0 0 1.5 14h13a1.5 1.5 0 0 0 1.5-1.5v-9A1.5 1.5 0 0 0 14.5 2h-13zm13 1a.5.5 0 0 1 .5.5v6l-3.775-1.947a.5.5 0 0 0-.577.093l-3.71 3.71-2.66-1.772a.5.5 0 0 0-.63.062L1.002 12v.54A.505.505 0 0 1 1 12.5v-9a.5.5 0 0 1 .5-.5h13z"/></svg>
</button>

<div class="stamp"></div>

In CSS:

body {
  margin: 60px 20px;
  height: calc(100vh - 120px);
  background: #111;
}

svg#canvas {
  width: 100%;
  height: 100%;
}

.btn {
  display: flex;
  border: none;
  position: absolute;
  right: 10px;
  background: #fff;
  padding: 8px;
  border-radius: 4px;
  box-shadow: 1px 1px 2px 0px rgb(0 0 0 / 5%);
}

.btn:hover {
  cursor: pointer;
  background: #00f;
}

.btn:hover svg {
  fill: #fff;
}

.btn:focus {
  outline: none;
}

.btn-generate {
  top: 10px;
}

.btn-copy {
  top: 50px;
}

.btn-save {
  top: 90px;
}

.btn-save-image {
  top: 130px;
}

.btn-generate svg,
.btn-copy svg,
.btn-save svg,
.btn-image svg{
  display: block;
}

.btn-copy svg {
  display: none;
}

.btn-copy svg.show {
  display: block;
}

@media only screen and (max-width: 767px) {
  .btn {
    top: 10px;
  }
  .btn-generate {
    right: 10px;
  }

  .btn-copy {
    right: 50px;
  }

  .btn-save {
    right: 90px;
  }
  
  .btn-save-image {
    right: 130px;
  }
}

.stamp {
  text-align: center;
  font-family: Helvetica;
  font-size: 14px;
  color: #fff;
  letter-spacing: 2px;
  display: block;
  position: absolute;
  bottom: 20px;
  left: 0;
  width: 100%;
}

And In Javascript:

import copy from "https://cdn.skypack.dev/[email protected]";

//Set up Canvas
var w = 1000;
var h = 1414;
var canvas = SVG('#canvas').css('background', 'transparent');
canvas.viewbox(0, 0, w, h);

//Set up random factors
var artworkID;
var layer0_gw, layer0_gh, layer0_gc,
    layer1_gc, layer1_gc2,
    layer2_gw, layer2_gh, layer2_gc,
    app_cs, app_csSeed;

//Set up colour scheme
var cscheme = new Array;
//cscheme[0] = ["#FC0243","#DB7C8E","#D0A7A8","#C6CBBE","#BFE4CD"];
//cscheme[1] = ["#69D2E7","#A7DBD8","#E0E4CC","#F38630","#FA6900"];
//cscheme[2] = ["#AB15BD","#2EB4C4","#0DDD9D","#B3F064","#ECEFCE"];
//cscheme[3] = ["#393463","#7CA667","#9BCC08","#BFE632","#FBF714"];
//cscheme[4] = ["#AAFF00","#FFAA00","#FF00AA","#AA00FF","#00AAFF"];

//Neon set
cscheme[0] = ["#FF5200","#D43E40","#A92980","#7D15BF","#5200FF"];
cscheme[1] = ["#FF0066","#FFB300","#B0FF05","#00FFC8","#708D91"];
cscheme[2] = ["#FF00FF","#EB00FF","#C200FF","#9900FF","#7A00FF"];
cscheme[3] = ["#C8E801","#D3B500","#FB5E0D","#F91A37","#B40E62"];

//Rendering
generate();

function generate() {
  //Setup
  app_cs = rand(cscheme.length);
  app_csSeed = rand(cscheme[app_cs].length);
  layer0_gw = rand(58) + 2;
  layer0_gh = rand(58) + 2;
  layer0_gc = rand(58) + 2;
  layer1_gc = rand(5);
  layer1_gc2 = rand(5);
  layer1_gc2 = (layer1_gc2 == layer1_gc) ? 0 : layer1_gc2;
  layer2_gw = rand(2) + 2;
  layer2_gh = rand(2) + 1;
  layer2_gc = rand(layer2_gw * layer2_gh);
  //getArt(3,2,3,18,12,50,2,1,1,4);
  
  //Start
  canvas.clear();
  canvas.rect(w, h).fill("#000");
  drawLayer1(layer1_gc);
  drawLayer1(layer1_gc2);
  drawLayer0(layer0_gw, layer0_gh, layer0_gc);
  drawLayer2(layer2_gw, layer2_gh, layer2_gc);
  drawStamp(layer1_gc2, layer1_gc, layer2_gw, layer2_gh, layer2_gc, layer0_gw, layer0_gh, layer0_gc, app_cs, app_csSeed);
}

function getArt(a, b, c, d, e, f, g, h, i, j) {
  layer2_gw = a;
  layer2_gh = b;
  layer2_gc = c;
  layer0_gw = d;
  layer0_gh = e;
  layer0_gc = f;
  layer1_gc2 = g;
  layer1_gc = h;
  app_cs = i;
  app_csSeed = j;
}

//Display artwork stamp
function drawStamp(rf9, rf8, rf7, rf6, rf5, rf4, rf3, rf2, rf1, rf0) {
  artworkID = num(rf7)+num(rf6)+num(rf5)+"-"+num(rf4)+num(rf3)+num(rf2)+"-"+num(rf9, true)+num(rf8, true)+num(rf1, true)+num(rf0, true);
  document.querySelector(".stamp").innerHTML = "Ref: "+artworkID;
}

//Set up Layer0 - grid pattern
function drawLayer0(gw, gh, gc) {
  var gridW = gw;
  var gridH = gh;
  var shapesID = 0;
  var shapesTotal = gridW * gridH;
  var shapes = new Array(shapesTotal);
  var shapeW = w / gridW;
  var shapeH = h / gridH;
  var seedCount = app_csSeed;
  
  for (var i = 1; i <= gridH; i++) {
    for (var j = 1; j <= gridW; j++) {
      shapes[shapesID] = canvas.rect(shapeW, shapeH)
        .fill("none")
        .stroke({color: cscheme[app_cs][app_csSeed], opacity: 0.2, width: 0.25})
        .cx(shapeW * j - shapeW / 2)
        .cy(shapeH * i - shapeH / 2);

      if(shapesID % gc < 1){
        shapes[shapesID].fill({color: cscheme[app_cs][seedCount], opacity: 1});
        seedCount = (seedCount + 1) % cscheme[app_cs].length;
      }
      
      shapesID++;
    }
  }
}

//Set up Layer1 - projection triangle
function drawLayer1(gc) {
  var gcPoly = new Array;
  gcPoly[0] = [0,0, 0,0, 0,0];
  gcPoly[1] = [0,0, w,0, w/2,h];
  gcPoly[2] = [0,h/2, w,0, w,h];
  gcPoly[3] = [0,h, w/2,0, w,h];
  gcPoly[4] = [0,0, w,h/2, 0,h];
  
  var linear = canvas.gradient('linear', function(add) {
    add.stop({offset: 0, color: cscheme[app_cs][rand(cscheme[app_cs].length)], opacity: 1})
    add.stop({offset: 1, color: cscheme[app_cs][app_csSeed], opacity: 0})
  })
  
  if(gc == 1) {
    linear.from(0, 1).to(0, 0);
  }
  if(gc == 3) {
    linear.from(0, 0).to(0, 1);
  }
  if(gc == 4) {
    linear.from(1, 0).to(0, 0);
  }
  
  var shape = canvas.polyline(gcPoly[gc])
    .fill({color: linear, opacity: 1})
    .cx(w/2)
    .cy(h/2);
}

//Set up Layer2 - Circular
function drawLayer2(gw, gh, gc) {
  var gridW = gw;
  var gridH = gh;
  var shapesID = 0;
  var shapesTotal = gridW * gridH;
  var shapes = new Array(shapesTotal);
  var shapeW = w / gridW;
  var shapeH = h / gridH;
  
  for (var i = 1; i <= gridH; i++) {
    for (var j = 1; j <= gridW; j++) {
      if(shapesID == gc) {
        shapes[shapesID] = canvas.circle(shapeW)
          .fill({color: "#fff", opacity: 0.6})
          .cx(shapeW * j - shapeW / 2)
          .cy(shapeH * i - shapeH / 2);
        shapes[shapesID] = canvas.circle(shapeW)
          .fill({color: cscheme[app_cs][app_csSeed], opacity: 1})
          .cx(shapeW * j - shapeW / 2)
          .cy(shapeH * i - shapeH / 2)
          .css('mix-blend-mode', 'color-burn');
      }
      
      shapesID++;
    }
  }
}

function rand(num) {
  return Math.floor(Math.random() * num);
}

function num(int, isSingle) {
  if(int.toString().length == 1 && !isSingle) {
    return '0'+int.toString();
  }else {
    return int.toString();
  }
}

//Action - Generate
document.querySelector(".btn-generate").addEventListener("click", generate);

//Action - Copy to clipboard
//Credit to @georgedoescode https://codepen.io/georgedoescode/pen/dyNVNjG
document.querySelector(".btn-copy").addEventListener("click", function() {
  copy(canvas.node.outerHTML);
  document.querySelector("svg.clipboard").classList.remove("show");
  document.querySelector("svg.clipboard-done").classList.add("show");
  
  setTimeout(function () {
    document.querySelector("svg.clipboard").classList.add("show");
    document.querySelector("svg.clipboard-done").classList.remove("show");
  }, 1500);
});

//Action - Save as svg
//Credit to @terabaud https://codepen.io/terabaud/pen/mdJqeYz
function save() {
  var anchor = document.createElement('a');
  anchor.setAttribute('download', 'twilight-'+artworkID+'.svg');
  var code = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"".concat(canvas.viewbox(), "\">").concat(canvas.node.innerHTML, "</svg>");
  anchor.setAttribute("href", "data:application/octet-stream;base64," + btoa(code));
  anchor.setAttribute('target', '_blank');
  return anchor;
}

document.querySelector(".btn-save").addEventListener('click', function() {
  save()['click']();
});

//Action - Save as png
//Credit to https://github.com/exupero/saveSvgAsPng
document.querySelector(".btn-save-image").addEventListener('click', function() {
  saveSvgAsPng(document.getElementById("canvas"), 'twilight-'+artworkID+".png", {encoderOptions: 1, scale: 1});
});

In Codepen:

See the Pen SVG Generative Art – CSG1 [Twilight] by John Wai (@johnwai_) on CodePen.

Please comment and share this article and wants to add more value to this article WhatsApp us.

Share Your Love
Default image
Lingaraj Senapati
Hey There! I am Lingaraj Senapati, the Co-founder of lingarajtechhub.com My skills are Freelance, Web Developer & Designer, Corporate Trainer, Digital Marketer & Youtuber.
Articles: 136

Newsletter Updates

Enter your email address below to subscribe to our newsletter

Leave a Reply