Petal Spectrum
to generate a new and unique variation
Every variart piece is open source, you can see exactly how it is drawn from the code.
// background
s.rect(0, 0, width, height).attr({fill: "#04011F"});
var petals = intVariable("Petals", 6, 48);
var cycles = intVariable("Colour Cycles", 1, 6);
var density = intVariable("Density", 20, 48);
var zoom = intVariable("Zoom", 100, 210);
// How far each petal is pushed out along its own axis. At 0 they all cross the
// middle and pile up into a flat wash; opening them up leaves a hole and lets
// the individual shapes read.
var opening = intVariable("Opening", 25, 130);
var shapeX = 253;
var shapeY = 168.5;
var cx = width / 2;
var cy = height / 2;
var hueOffset = getRandomArbitary(0, 1);
var saturation = getRandomArbitary(0.65, 0.95);
var lightness = getRandomArbitary(0.42, 0.68);
var lean = getRandomArbitary(0, 360 / petals);
// Where the crop is aimed. Every petal crosses the middle, so the middle is a
// flat wash of overlapping colour -- the interesting part is out where the
// tips fan apart. Look at a point on that band rather than at the centre.
var lookAngle = getRandomArbitary(0, 360) * Math.PI / 180;
var lookRadius = getRandomArbitary(55, 150);
var lookX = cx + Math.cos(lookAngle) * lookRadius;
var lookY = cy + Math.sin(lookAngle) * lookRadius;
var rosette = s.g();
var petal = s.path("M253,22.6872036 C202.773134,51.8570633 169,106.234463 169,168.5 C169,230.765537 202.773134,285.142937 253,314.312796 C303.226851,285.142961 337,230.765551 337,168.5 C337,106.234449 303.226851,51.8570389 252.999966,22.687184 Z");
for (var i = 0; i < petals; i++){
var angle = lean + (i * 360 / petals);
var hue = (hueOffset + (i / petals) * cycles) % 1;
rosette.add(
petal.clone()
.attr({fill: Snap.hsl2rgb(hue, saturation, lightness), fillOpacity: density / 100})
// Rightmost first: centre the petal, push it out, then swing it round.
.transform('r' + angle + ',' + cx + ',' + cy +
't0,' + (-opening) +
't' + (cx - shapeX) + ',' + (cy - shapeY))
);
}
petal.remove();
// Pull the look point to the middle of the canvas, then scale about it.
rosette.transform('s' + (zoom / 100) + ',' + cx + ',' + cy +
't' + (cx - lookX) + ',' + (cy - lookY));
Copyright © 2014–2026 Kevin Marsh. All rights reserved. Questions? Comments? hello@variart.io