CSS Doodle provides a declarative syntax for generating polgyon shapes with clip-path property. To create a regular polygon, simply set the number of vertices or points:
clip-path: @shape(
points: 5;
)
You may want to rotate, scale, or move it.
clip-path: @shape(
points: 5;
rotate: -18;
scale: .8;
move: 0 .45;
)
The shape can also be made into a hollow frame.
clip-path: @shape(
points: 5;
frame: 5;
)
Or something like straight line paths.
clip-path: @shape(
points: 5;
frame: 5;
turn: 2;
)
If there are enough points, it will look like a circle.
clip-path: @shape(
points: 360;
)
By default the shape is defined with trigonometric functions of x
and y
.
That is, x = cos(t)
and y = sin(t)
, where t
represents the symbol theta
for the equally divided angle.
clip-path: @shape(
points: 360;
x: cos(t);
y: sin(t);
)
You can change the equations to form different shapes you like.
clip-path: @shape(
points: 360;
scale: .32 .4;
x: sin(t) + sin(5t) - sin(7t);
y: cos(t) + cos(5t) - cos(3t);
)
It supports custom variables, so you can put parameters to one place.
clip-path: @shape(
points: 200;
scale: .12;
k: 9;
x: k*cos(t) + cos(k*t);
y: k*sin(t) - sin(k*t);
)
When multiple paths are crossed it's useful to set the fill-rule to be evenodd.
clip-path: @shape(
points: 360;
scale: .5;
x: cos(2t) + cos(7t);
y: sin(2t) + sin(7t);
fill: evenodd;
)
This shape requires evenodd
to show as well.
clip-path: @shape(
points: 360;
scale: .5;
x: cos(4t) + cos(5t);
y: sin(4t) + sin(5t);
fill: evenodd;
)
Another similar way to define the shape is to use the formula of Polar equation.
clip-path: @shape(
points: 360;
r: cos(4t);
)
Sometimes you may get interesting shapes with just a few vertices.
clip-path: @shape(
points: 30;
r: cos(4t) * sin(2t) * 1.35;
)
Even if there are only 9 vertices.
clip-path: @shape(
points: 9;
rotate: -40;
move: .15 -.5;
r: 1.5 * sin(-10.278t);
)
Let's draw a shape with Superformula.
clip-path: @shape(
points: 360;
m: 5;
n: .4;
p1: abs.cos(t*m/4)^n;
p2: abs.sin(t*m/4)^n;
r: 1/(p1 + p2)^(1/n);
)
It's very straightforward to draw the squircle shape in this way.
clip-path: @shape(
points: 100;
r: (1-.5*sin(2t)^2)^-.25;
)
The value of r
doesn't have to be Math equations. It can be a constant value.
clip-path: @shape(
points: 180;
r: .4;
)
Use the built-in seq()
function to
pass in a sequence of values for each point.
clip-path: @shape(
points: 12;
r: seq(.6, 1);
)
In most cases, it's useful when there aren't many points.
clip-path: @shape(
points: 36;
frame: 10;
r: seq(.8, 1, .618);
)
That's all the rules.
Despite its simplicity, it's worth exploring further to find more interesting shapes. For example, this vase shape that I like very much.
clip-path: @shape(
points: 200;
scale: .3;
x: sin(4t) + sin(t) * 1.3;
y: cos(t) + cos(t) * 4.9 + .3;
)
The shape will be symmetrical if the given equations are symmetrical. In this case, x has two cos
's and one sin
, y is the opposite.
clip-path: @shape(
points: 360;
fill: evenodd;
x: cos(2t) * cos(5t) * sin(t);
y: sin(2t) * sin(4t) * cos(5t);
)
So follow this rule it's likely to get some symmetrical shapes, like masks.
clip-path: @shape(
points: 360;
scale: .49;
x: sin(5t) + sin(4t);
-y: cos(4t) + cos(10t);
)
There are so many variants of mask shape.
clip-path: @shape(
points: 360;
scale: .31 .28;
x: sin(6t) + sin(4t) + tan.sin(t);
-y: cos(t) + cos(4t) + tan.cos(7t);
)
I can get an opera face that is symmetrical.
clip-path: @shape(
points: 360;
scale: .42 .5;
x: sin(t) + sin(8t);
-y: cos(3t) + cos(9t);
)
Or even a dog face.
clip-path: @shape(
points: 360;
scale: .3;
-y: cos(7t) + cos(3t) + cos(7t);
x: sin(8t) + sin(2t) + sin(t);
)
The fish shape is symmetrical too.
clip-path: @shape(
points: 360;
scale: .28;
move: 0 .5;
x: sin(4t) + sin(4t) + tan.sin(t);
y: cos(5t) + cos(t) + tan.cos(8t);
)
The process of discovering new shapes is as exciting as imagining discovering new life on another planet.
clip-path: @shape(
points: 480;
scale: .3;
move: 0 .35;
x: sin(t) + sin(6t) + tan.sin(2t);
y: cos(t) + cos(5t) + tan.cos(8t);
)
Not all shapes are symmetrical. Using parameters with large or fractional numbers you will get distinct ones.
clip-path: @shape(
points: 180;
scale: .08;
x: 2 * sin(112t) + 11 * sin(t);
y: sin(47t) + 20 * sin(5t);
)
The landscape clip is a good example of asymmetrical shapes.
clip-path: @shape(
points: 90;
rotate: 90;
scale: .8;
x: (.99 + cos(9t)) * 2.3;
y: x^9*sin(x^8 * 3t) +
sin(13.6x-9.01t)/cos(t);
)
This is one of my favorites :)
clip-path: @shape(
points: 1000;
scale: .8;
move: .5 .64;
x: cos(t^t) + cos(1.8^t);
y: sin(t) + sin(2.305t)*sin(t);
)
Shapes can also be some abstract forms. Does this look like five people dancing?
clip-path: @shape(
points: 1000;
scale: .061 .06;
x: (11*cos(.6t) + cos(55t) - 2.8) * -1.81;
-y: (11*sin(9.03t) - sin(77t)) * 2.5 + 17;
)
I can't describe what exactly the shape is but it looks like somewhere by the sea.
clip-path: @shape(
points: 360;
scale: .42;
move: -.5 -.78;
x: sin(3t) + sin(2/t) + sin(4t);
-y: cos(3t) + cos(t) + cos(2t);
)
So is this shape.
clip-path: @shape(
points: 720;
scale: .4 .3;
move: -.5 0;
-y: cos(5t) + cos(3t) + cos(5t);
x: sin(3t) + sin(3/t) + sin(2t);
)
Creating shapes using mathematical functions is very different from other methods. It's helpful to build some kind of intuition yourself by practicing.
clip-path: @shape(
points: 1000;
a: 2931;
scale: .9;
frame: 400;
fill: evenodd;
x: cos(t) + cos(17t) + sin(a*t)/9;
y: sin(t) + sin(17t) + cos(a*t)/9;
)
Several other shapes I find quite interesting and elegant. Look this plant:
clip-path: @shape(
points: 1800;
scale: .8;
move: 0 1.2;
x: sin(t) + sin(t)/2 + cos(140t)/9;
y: cos(5t) + cos(14t)/2 + sin(121t)/9;
)
Rocks.
clip-path: @shape(
points: 1000;
scale: 1.5 1;
x: cos(9t) + cos(9t)/9 + sin(139t)/2;
y: sin(t) + sin(t)/.5 + cos(29t)/3;
)
Strings.
clip-path: @shape(
split: 360;
frame: 24;
turn: .5;
scale: .1;
x: 9 * cos(10t) + cos(44t);
y: 9 * sin(10t) + sin(44t);
)
Dried fish.
clip-path: @shape(
points: 360;
scale: .22;
x: sin(t) + tan.sin(4t) + tan.sin(t);
y: cos(8t) + tan.cos(3t) + tan.cos(8t);
)
Alien spaceship.
clip-path: @shape(
points: 360;
scale: .35;
move: 0 1;
x: sin(7t) + sin(6t) + tan.sin(t);
y: cos(3t) + cos(6t) + tan.cos(3t);
)
And a person practicing Zen.
clip-path: @shape(
points: 360;
scale: .33;
x: sin(3t) + sin(6t) + sin(7t);
-y: 2*cos(t) + cos(7t);
)
Hope these examples can explain the @shape()
function well.
Below are the links of a live editor and all the other shapes I created for the divtober challenge this month.