At first, the idea was to generate something close to Lucas's drawing.
I've tried several approaches to get there, but as the results where interesting I kept them.
20 vertices | 2000 vertices |
---|---|
![]() |
![]() |
20 vertices | 2000 vertices |
---|---|
![]() |
![]() |
20 vertices | 2000 vertices |
---|---|
![]() |
![]() |
Since I couldn't find a way to get there I did research and find out Delaunay triangulation and then this script.
20 vertices | 2000 vertices |
---|---|
![]() |
![]() |
Even if Lucas's drawing wasn't only based on triangles, this is really what I tried to get. And I have its validation ;)
The API can be used in script in Browser or with Node.js.
For Node.js, your project require jsdom
and canvas
.
First, we need to set a canvas:
const canvasSettings = {
width: 2100,
height: 2970,
padding: 100, // padding can be negative
fill: "#ffffff" // background color
};
const mySheet = new LcsCnvs();
mySheet.setCanvas(canvasSettings);
And now we can draw:
mySheet.drawTriangleAfterNewVertex(polygonSettings);
mySheet.drawTriangleForEachVertex(polygonSettings);
mySheet.drawTriangleAround(polygonSettings);
mySheet.drawDelaunay(polygonSettings);
By changing the polygon settings, outputs can be very differents.
Here is a polygon setting example:
{
color: ["#1F90FF", "#1CE867", "#FBFF2C", "#E8941C", "#FF2B31"] // if color is an Array, a color will be randomly used
blendingMode: "multiply",
line: {
color: {
// line color
"0": "#ff0000", // if color is an Object, it will be a gradient
"0.5": "#00ff00",
"1": "#0000ff" // from 0 to 1
},
width: 5, // 0 to remove border
cap: "square",
join: "round"
},
vertex: {
nb: 12000, // number of vertex
distance: 5, // maximum vertex distance from vertice area (only used for the drawTriangleAround method)
onPixel: true // used if you don't wan't vertex on loaded image, need a transparent background
}
}
And then, in your browser, display result:
delay option will create an animation displaying polygons one after one.
mySheet.append("body", 100);
Or export file with Node.js:
By default, exported files will go to output/${timestamp}.png
const exportSettings = {
allFrames: true, // export each frames after adding polygons
fill: "#ffffff", // background color
path: "export", // export folder
filename: "blu" // export filename
};
mySheet.export(exportSettings);
// files will export to 'export/blu-${timestamp}.png'
allFrames option will export all the frames after a new polygon is added.
You can use this option to generate video using FFMpeg:
ffmpeg -framerate 33 -pattern_type glob -i 'output/*.png' -c:v libx264 -pix_fmt yuv420p -filter:v fps=fps=30 output/gif.mp4
Or a gif using Convert from ImageMagick:
convert output/*.png output/polygons.gif
#1 | #2 | #3 | #4 | #5 |
---|---|---|---|---|
![]() |
![]() |
![]() |
![]() |
![]() |
Because I had to use those generative for Daron Crew artworks, I added this extra method:
const imageSettings = {
src: "./img/daron-crew.svg", // path to image
width: 1520 // desired width (height is calculated)
};
mySheet.addImage(imageSettings).then(sheet => {
sheet.append("body");
});
The image will be vertically and horizontally centered.
There is also a dedicated polygon parameter: onPixel
.
If defined, it will condition if vertex must be positionned on used pixel (true
) or not (false
).
Must be used on a canvas without background.
onPixel: undefined | onPixel: false | onPixel: true |
---|---|---|
![]() |
![]() |
![]() |
Here some code examples and Here a demo.
No jealous, I have to take a look at the drawing of the brother...