Fillinger Script for Adobe Illustrator
Author: A Jongware Script (Circle fill)
Program Version: Adobe Illustrator CC+
Script Name: fillinger.jsx
Modified and Refactored By: Alexander Ladygin
Website: www.ladyginpro.ru
Copyright: 2018
Description
The fillinger.jsx
script for Adobe Illustrator is a powerful tool designed to fill a selected path with multiple objects. It allows users to customize the size, rotation, and positioning of the objects within the selected path, providing a great degree of control over the final design.
Features
- Size Customization: Allows setting the maximum and minimum size of the objects as a percentage of the total size.
- Distance Control: Enables setting the minimum distance between objects.
- Resize Value: Allows setting a resize value for the objects.
- Rotation Options: Offers random rotation or rotation by a specific value.
- Positioning: Provides options to place the filling objects on top, below, or according to the layers.
- Grouping: Option to group all items after executing the script.
- Random Selection: Option to randomly select items from a group for filling.
- Remove Top Element: Option to remove the item used for filling after execution.


Note : Make sure you convert your filling object into a compound path. The filling object must be on top.

Usage Instructions
- Selection:
- Open Adobe Illustrator and select 2 or more objects.
- If less than 2 objects are selected, an alert will prompt you to select more objects.
- Script Execution:
- Run the
fillinger.jsx
script. - A dialog window will appear with various customization options.
- Customization:
- Items Size: Set the maximum and minimum size of the items as a percentage of the total size.
- Min Distance: Set the minimum distance between objects.
- Resize Value: Enter the resize value.
- Rotate Items: Choose between random rotation or rotation by a specific value.
- Item Position: Choose whether the item to fill is on top, below, or according to layers.
- Additional Options: Check the options to group all items after execution, randomly select items from a group, or remove the item used for filling after execution.
- Execution:
- Click the “OK” button to start the action.
- The script will process the selected objects and fill the path according to the specified settings.
- A progress bar will indicate the progress of the operation.
- Settings:
- The script saves the settings to a JSON file in your documents folder.
- The settings will be loaded automatically the next time you run the script.
Dialog Window Options
- Max: Maximum size of items as a percentage.
- Min: Minimum size of items as a percentage.
- Min Distance: Minimum distance between items.
- Resize Value: Resize value for objects.
- Rotate Items: Options for random rotation or rotation by a specific value.
- The item to fill is: Options for placing the item on top, below, or according to layers.
- Group all items after executing: Option to group all items after execution.
- Random items (if items in the group): Option to randomly select items from a group.
- Remove the item to fill after executing: Option to remove the item used for filling after execution.
Additional Information
- The script checks if the setting folder exists and creates it if necessary.
- Settings are saved and loaded automatically for convenience.
- The script includes robust error handling and user prompts to ensure a smooth experience.
For more information and updates, visit ladyginpro.ru.
/*
Author: A Jongware Script (Circle fill)
Program version: Adobe Illustrator CC+
Name: fillinger.jsx;
Modify and refactoring: Alexander Ladygin
www.ladyginpro.ru
Copyright (c) 2018
*/
if (app.documents.length && app.selection.length < 2) {
alert('Please select 2 or more objects');
}
else {
var scriptName = 'Fillinger',
settingFile = {
name: scriptName + '__setting.json',
folder: Folder.myDocuments + '/LA_AI_Scripts/'
};
function inputNumberEvents (ev, _input, min, max, callback){
var step,
_dir = ev.keyName.toLowerCase().slice(0,1),
_value = parseFloat(_input.text),
units = (',px,pt,mm,cm,in,'.indexOf(_input.text.length > 2 ? (',' + _input.text.replace(/ /g, '').slice(-2) + ',') : ',!,') > -1 ? _input.text.replace(/ /g, '').slice(-2) : '');
min = (min === undefined ? 0 : min);
max = (max === undefined ? Infinity : max);
step = (ev.shiftKey ? 10 : (ev.ctrlKey ? .1 : 1));
if (isNaN(_value)) {
_input.text = min;
}
else {
_value = ( ((_dir === 'u') || (_dir === 'r')) ? _value + step : (((_dir === 'd') || (_dir === 'l')) ? _value - step : false) );
if (_value !== false) {
_value = (_value <= min ? min : (_value >= max ? max : _value))
_input.text = _value;
if (callback instanceof Function) callback(_value, _input, min, max, units);
}
}
}
var win = new Window('dialog', 'Fillinger \u00A9 www.ladyginpro.ru');
win.orientation = 'column';
win.alignChildren = ['fill', 'fill'];
var globalGroup = win.add('group');
globalGroup.orientation = 'column';
globalGroup.alignChildren = ['fill', 'fill'];
var sizePanel = globalGroup.add('panel', undefined, 'Items size in % of total size'),
sizeGroup = sizePanel.add('group');
sizePanel.alignChildren = 'fill';
sizeGroup.orientation = 'row';
sizeGroup.alignChildren = ['fill', 'fill'];
var maxValueGroup = sizeGroup.add('group');
maxValueGroup.orientation = 'row';
maxValueGroup.alignChildren = 'fill';
var maxValueLabel = maxValueGroup.add('statictext', undefined, 'Max:'),
maxValue = maxValueGroup.add('edittext', [0, 0, 50, 25], '10');
maxValueLabel.justify = 'center';
var minValueGroup = sizeGroup.add('group');
minValueGroup.orientation = 'row';
minValueGroup.alignChildren = 'fill';
var minValueLabel = minValueGroup.add('statictext', undefined, 'Min:'),
minValue = minValueGroup.add('edittext', [0, 0, 50, 25], '4');
minValueLabel.justify = 'center';
function checkMnMaxSize (val, item, min, max) {
if (item === minValue) {
if (val > parseFloat(maxValue.text)) { maxValue.text = (val >= max ? max : val); }
}
else if (item === maxValue) {
if (val < parseFloat(minValue.text)) { minValue.text = (val < min ? min : val); }
}
}
maxValue.addEventListener('keydown', function (e) {
if (e.ctrlKey && e.keyName === 'Right') minValue.text = this.text;
else inputNumberEvents(e, maxValue, 1, Infinity, checkMnMaxSize);
});
minValue.addEventListener('keydown', function (e) {
if (e.ctrlKey && e.keyName === 'Left') maxValue.text = this.text;
else inputNumberEvents(e, minValue, 1, Infinity, checkMnMaxSize);
});
var guttersResizeGroup = sizePanel.add('group');
guttersResizeGroup.orientation = 'row';
guttersResizeGroup.alignChildren = ['fill', 'fill'];
var guttersGroup = guttersResizeGroup.add('group');
guttersGroup.orientation = 'column';
guttersGroup.alignChildren = 'fill';
var guttersLabel = guttersGroup.add('statictext', undefined, 'Min distance')
guttersValue = guttersGroup.add('edittext', undefined, '0');
guttersValue.addEventListener('keydown', function (e) { inputNumberEvents(e, this, 0, Infinity); });
var resizeGroup = guttersResizeGroup.add('group');
resizeGroup.orientation = 'column';
resizeGroup.alignChildren = 'fill';
var resizeLabel = resizeGroup.add('statictext', undefined, 'Resize value')
resizeValue = resizeGroup.add('edittext', undefined, '70');
resizeValue.addEventListener('keydown', function (e) { inputNumberEvents(e, this, 10, Infinity); });
var rotatePositionGroup = globalGroup.add('group');
rotatePositionGroup.orientation = 'row';
rotatePositionGroup.alignChildren = ['fill', 'fill'];
var rotatePanel = rotatePositionGroup.add('panel', undefined, 'Rotate items:');
rotatePanel.alignChildren = 'fill';
var randomRadioGroup = rotatePanel.add('group');
randomRadioGroup.orientation = 'column';
var randomRotate = randomRadioGroup.add('radiobutton', undefined, 'Random'),
rotateByValue = randomRadioGroup.add('radiobutton', undefined, 'By value'),
rotateValue = rotatePanel.add('edittext', undefined, '0');
randomRotate.value = true;
rotateValue.enabled = false;
randomRotate.onClick = function() { rotateValue.enabled = false; }
rotateByValue.onClick = function() { rotateValue.enabled = true; }
var objectPositionPanel = rotatePositionGroup.add('panel', undefined, 'The item to fill is:'),
objectPositionGroup = objectPositionPanel.add('group');
objectPositionGroup.orientation = 'column';
objectPositionGroup.alignChildren = ['fill', 'fill'];
var objectPosTop = objectPositionGroup.add('radiobutton', undefined, 'On top'),
objectPosBottom = objectPositionGroup.add('radiobutton', undefined, 'Below'),
objectPosLayers = objectPositionGroup.add('checkbox', undefined, 'As in [Layers]');
objectPosTop.value = true;
var groupResult = globalGroup.add('checkbox', undefined, 'Group all items after executing'),
randomItems = globalGroup.add('checkbox', undefined, 'Random items (if items in the group)'),
removeTopElement = globalGroup.add('checkbox', undefined, 'Remove the item to fill after executing');
var winButtons = globalGroup.add('group');
winButtons.orientation = 'row';
winButtons.alignChildren = ['fill', 'fill'];
winButtons.margins = 0;
var cancel = winButtons.add('button', undefined, 'Cancel');
cancel.helpTip = 'Press Esc to Close';
cancel.onClick = function () { win.close(); }
var ok = winButtons.add('button', undefined, 'OK');
ok.helpTip = 'Press Enter to Run';
ok.onClick = function (e) {
startAction();
win.close();
};
ok.active = true;
var progressBar = win.add('progressbar'),
progressBarCounter = 100;
progressBar.value = 0;
progressBar.minvalue = 0;
progressBar.maxvalue = progressBarCounter;
progressBar.maximumSize = [1000, 5];
/*
random rotate
rotate from value
*/
function startAction(){
globalGroup.enabled = false;
var __rotateValue = Number(rotateValue.text);
maxCircleSize = Number(maxValue.text);
if (maxCircleSize < 0.01 || maxCircleSize > 100){maxCircleSize = 20;}
minCircleSize = Number(minValue.text);
if (minCircleSize < 0.01 || minCircleSize > maxCircleSize){minCircleSize = maxCircleSize/2;}
maxCircleSize /= 100;
minCircleSize /= 100;
maxCircleSize /= 2;
minCircleSize /= 2;
minDistanceToOtherCircles = Number(guttersValue.text);
var items = selection.concat();
if (!objectPosLayers.value) items.sort(function (a, b) {
return a.geometricBounds[1] <= b.geometricBounds[1];
});
if (objectPosBottom.value) items.reverse();
var object = items[0];
if (object.typename !== 'PathItem' && object.typename !== 'CompoundPathItem') {
return alert('The filling object must be PathItem or CompoundPathItem! [' + object.typename + ']');
}
items.splice(0,1);
var placeObject = (items.length === 1 ? (items[0].typename === 'GroupItem' ? items[0].pageItems : [items[0]]) : (!items.length ? [] : items));
if (!placeObject.length) {
return alert('No items to fill!');
}
var placeObjectResizeValue = (isNaN(parseFloat(resizeValue.text)) ? parseFloat(resizeValue.text) : 70),
innerpaths = [],
outerPath = null
groupItems = (groupResult.value ? activeDocument.groupItems.add() : false);
if (groupItems) groupItems.move(object, ElementPlacement.PLACEBEFORE);
function getNode() {
return ((!randomItems.value) ? placeObject[0] : placeObject[ Math.floor(Math.random() * placeObject.length) ]);
}
if (object.constructor.name == "CompoundPathItem"){
for (p=0; p<object.pathItems.length; p++){
innerpaths.push(flattenPath(object.pathItems[p]));
}
if (innerpaths.length == 1 && outerPath == null){
outerPath = innerpaths[0];
innerpaths = [];
}
else {
var minx = innerpaths[0][0][0], outer = 0;
for (p=0; p<innerpaths.length; p++){
for (q=0; q<innerpaths[p].length; q++){
if (innerpaths[p][q][0] < minx){
minx = innerpaths[p][q][0];
outer = p;
}
}
}
outerPath = innerpaths[outer];
innerpaths.splice (outer,1);
}
}
else {outerPath = flattenPath(object);}
if (outerPath == null){alert ("Got a bad path. What's going on?");}
else{
minx = object.geometricBounds[0];
miny = object.geometricBounds[1];
maxx = object.geometricBounds[2];
maxy = object.geometricBounds[3];
if (minx > maxx){x = minx;minx = maxx;maxx = x;}
if (miny > maxy){y = miny;miny = maxy;maxy = y;}
maxwide = maxx - minx;
maxhigh = maxy - miny;
totalArea = Math.abs(object.area);
filledArea = 0;
Math_Epsilon = 0.0001;
joinedPath = outerPath;
triangleIndexList = Triangulate (joinedPath, innerpaths);
triangleList = [];
for (p=0; p<triangleIndexList.length; p+=3){
triangleList.push([joinedPath[triangleIndexList[p]],joinedPath[triangleIndexList[p+1]],joinedPath[triangleIndexList[p+2]] ] );
}
edgeList = [ [outerPath[outerPath.length-1], outerPath[0]] ];
for (i=0; i<outerPath.length-1; i++){edgeList.push ( [ outerPath[i], outerPath[i+1] ] );}
for (i=0; i<innerpaths.length; i++){
edgeList.push ( [ innerpaths[i][innerpaths.length-1], innerpaths[i][0] ] );
for (i2=0; i2<innerpaths[i].length-1; i2++){edgeList.push ( [ innerpaths[i][i2], innerpaths[i][i2+1] ] );}
}
areaList = [];
triArea = 0;
for (p=0; p<triangleList.length; p++){
triArea += Math.abs (Area([
triangleList[p][0], triangleList[p][1],
triangleList[p][1], triangleList[p][2],
triangleList[p][2], triangleList[p][0] ] ) );
areaList.push(triArea);
}
pointList = [];
circleList = [];
radiiList = [ ];
maxsize = Math.sqrt(maxwide * maxhigh);
size = maxCircleSize;
while (1){
radiiList.push (size*maxsize);
size *= .667;
if (size < minCircleSize){break;}
}
progressBarCounter = progressBar.maxvalue * 0.25 / radiiList.length;
for (rad=0; rad<radiiList.length; rad++){
for (p=0; p<1000; p++){
a_rnd = Math.random() * triArea;
for (q=0; q<triangleList.length; q++) {
if (areaList[q] > a_rnd) {break;}
}
pt = getRandomPoint (triangleList[q]);
d = distanceToClosestEdge (pt, edgeList);
if (d >= radiiList[rad]){
for (c=0; c<pointList.length; c++){
xd = Math.abs (pt[0]-pointList[c][0]);
yd = Math.abs (pt[1]-pointList[c][1]);
if (xd <= radiiList[rad]+circleList[c]+minDistanceToOtherCircles &&
yd <= radiiList[rad]+circleList[c]+minDistanceToOtherCircles){
d = distanceFromPointToPoint (pt, pointList[c])-minDistanceToOtherCircles;
if (d < radiiList[rad]+circleList[c])
break;
}
}
if (c == pointList.length){
nrad = radiiList[rad];
pointList.push ( pt );
circleList.push (nrad);
}
}
}
progressBar.value += progressBarCounter;
win.update();
}
progressBarCounter = progressBar.maxvalue * 0.75 / pointList.length;
for (p=0; p<pointList.length; p++){
pt = pointList[p];
nrad = distanceToClosestEdge (pt, edgeList);
for (c=0; c<pointList.length; c++){
if (c == p)
continue;
xd = Math.abs (pt[0]-pointList[c][0]);
yd = Math.abs (pt[1]-pointList[c][1]);
if (xd <= nrad+circleList[c]+minDistanceToOtherCircles &&
yd <= nrad+circleList[c]+minDistanceToOtherCircles)
{
nd = distanceFromPointToPoint (pt, pointList[c])-circleList[c]-minDistanceToOtherCircles;
if (nd < nrad)
nrad = nd;
}
}
circleList[p] = nrad;
var __placeObject = getNode().duplicate(),
placeObjectSize = (__placeObject.width >= __placeObject.height ? 'width' : 'height'),
placeObjectSizeReverse = (placeObjectSize === 'width' ? 'height' : 'width'),
__radius = 2 * nrad,
__size = __radius * (placeObjectResizeValue / 100);
__ratio = __size * 100 / __placeObject[placeObjectSize] / 100;
__placeObject.move(groupResult.value ? groupItems : object, ElementPlacement[groupResult.value ? 'INSIDE' : 'PLACEBEFORE']);
__placeObject[placeObjectSize] = __size;
__placeObject[placeObjectSizeReverse] *= __ratio;
__placeObject.position = [pt[0]-nrad + ((__radius - __placeObject.width) / 2), pt[1]+nrad - ((__radius - __placeObject.height) / 2)];
if (randomRotate.value) __placeObject.rotate(Math.floor(Math.random() * 360));
else if (rotateByValue.value && __rotateValue) __placeObject.rotate(__rotateValue);
progressBar.value += progressBarCounter;
win.update();
}
}
if (removeTopElement.value) object.remove();
}
function drawLine (a,b){var p = app.activeDocument.pathItems.add();try {p.setEntirePath ([ a,b ]);p.strokeWidth = 0.1;} catch (e){alert ("Bad line:\ra="+a+"\rb="+b);}return p;}
function distanceFromPointToPoint(A, B){return Math.sqrt ( ((A[0]-B[0]) * (A[0]-B[0])) + ((A[1]-B[1]) * (A[1]-B[1])) );}
function flattenPath(obj){var newpath = new Array(),curveList,pt, nextpt,isFlattened = false;if (!obj.hasOwnProperty ("pathPoints")){return null;}for (pt=0; pt<obj.pathPoints.length; pt++){nextpt = pt+1;if (nextpt == obj.pathPoints.length){nextpt = 0;}if (obj.pathPoints[pt].anchor[0] == obj.pathPoints[pt].rightDirection[0] && obj.pathPoints[pt].anchor[1] == obj.pathPoints[pt].rightDirection[1] &&obj.pathPoints[nextpt].anchor[0] == obj.pathPoints[nextpt].leftDirection[0] && obj.pathPoints[nextpt].anchor[1] == obj.pathPoints[nextpt].leftDirection[1]){newpath.push (obj.pathPoints[pt].anchor);} else{isFlattened = true;curveList = curve4(obj.pathPoints[pt].anchor[0],obj.pathPoints[pt].anchor[1],obj.pathPoints[pt].rightDirection[0],obj.pathPoints[pt].rightDirection[1],obj.pathPoints[nextpt].leftDirection[0],obj.pathPoints[nextpt].leftDirection[1],obj.pathPoints[nextpt].anchor[0],obj.pathPoints[nextpt].anchor[1],4);newpath = newpath.concat(curveList);}}return newpath;}
function pointInsidePoly(pt, poly){for(var c = false, i = -1, l = poly.length, j = l - 1; ++i < l; j = i){((poly[i][1] <= pt[1] && pt[1] < poly[j][1]) || (poly[j][1] <= pt[1] && pt[1] < poly[i][1]))&& (pt[0] < (poly[j][0] - poly[i][0]) * (pt[1] - poly[i][1]) / (poly[j][1] - poly[i][1]) + poly[i][0])&& (c = !c);}return c;}
function getWinding(path){var i,next;var accum = 0;for (i=0; i<path.length-1; i++){next = i+1;accum += path[next][0] * path[i][1] - path[i][0] * path[next][1];}next = 0;accum += path[next][0] * path[i][1] - path[i][0] * path[next][1];return accum / 2;}
function curve4(x1, y1,x2, y2,x3, y3,x4, y4,nSteps){var pointList = new Array(),dx1 = x2 - x1,dy1 = y2 - y1,dx2 = x3 - x2,dy2 = y3 - y2,dx3 = x4 - x3,dy3 = y4 - y3,subdiv_step = 1.0 / (nSteps + 1),subdiv_step2 = subdiv_step*subdiv_step,subdiv_step3 = subdiv_step*subdiv_step*subdiv_step,pre1 = 3.0 * subdiv_step,pre2 = 3.0 * subdiv_step2,pre4 = 6.0 * subdiv_step2,pre5 = 6.0 * subdiv_step3,tmp1x = x1 - x2 * 2.0 + x3,tmp1y = y1 - y2 * 2.0 + y3,tmp2x = (x2 - x3)*3.0 - x1 + x4,tmp2y = (y2 - y3)*3.0 - y1 + y4,fx = x1,fy = y1,dfx = (x2 - x1)*pre1 + tmp1x*pre2 + tmp2x*subdiv_step3,dfy = (y2 - y1)*pre1 + tmp1y*pre2 + tmp2y*subdiv_step3,ddfx = tmp1x*pre4 + tmp2x*pre5,ddfy = tmp1y*pre4 + tmp2y*pre5,dddfx = tmp2x*pre5,dddfy = tmp2y*pre5,step = nSteps;pointList.push ([x1, y1]);while(step--){fx += dfx;fy += dfy;dfx += ddfx;dfy += ddfy;ddfx += dddfx;ddfy += dddfy;pointList.push ([fx, fy]);}return pointList;}
function Triangulate(m_points, holes){var indices = new Array();if (holes.length){for (hh=0; hh<holes.length; hh++){var h = holes[hh],miny = 0;for (var i=1; i<h.length; i++)if (h[i][1] < h[miny][1]){miny = i;}var closestpt = 0,closestd = distanceFromPointToPoint (h[miny], m_points[closestpt]);for (var i=1; i<m_points.length; i++){var d= distanceFromPointToPoint (h[miny], m_points[i]);if (d < closestd){closestd = d;closestpt = i;}}m_points.splice (closestpt, 0, [ m_points[closestpt][0],m_points[closestpt][1]+0.05 ]);closestpt++;h.splice (miny, 0, [ h[miny][0],h[miny][1] ]);h[miny][1] += 0.05;for (var i=miny; i >=0; i--){m_points.splice (closestpt, 0, h[i]);}for (var i=h.length-1; i > miny; i--){m_points.splice (closestpt, 0, h[i]);}}}var n = m_points.length;if (n < 3) {return indices;}var V = new Array(n);if (Area(m_points) > 0){for (var v = 0; v < n; v++)V[v] = v;}else{for (var v = 0; v < n; v++){V[v] = (n - 1) - v;}}
var nv = n,count = 2 * nv;for (var m = 0, v = nv - 1; nv > 2;){if ((count--) <= 0){return indices;}var u = v;if (nv <= u){u = 0;}v = u + 1;if (nv <= v){v = 0;}var w = v + 1;if (nv <= w){w = 0;}if (Snip(u, v, w, nv, V, m_points)){var a, b, c, s, t;a = V[u];b = V[v];c = V[w];indices.push(a);indices.push(b);indices.push(c);m++;for (s = v, t = v + 1; t < nv; s++, t++){V[s] = V[t];}nv--;count = 2 * nv;}}indices.reverse();return indices;}
function Area(m_points){var n = m_points.length,A = 0.0;for (var p = n - 1, q = 0; q < n; p = q++){var pval = m_points[p],qval = m_points[q];A += pval[0] * qval[1] - qval[0] * pval[1];}return (A * 0.5);}
function Snip(u, v, w, n, V, m_points){var p,A = m_points[V[u]],B = m_points[V[v]],C = m_points[V[w]];if (Math_Epsilon > (((B[0] - A[0]) * (C[1] - A[1])) - ((B[1] - A[1]) * (C[0] - A[0])))){return false;}for (p = 0; p < n; p++) {if ((p == u) || (p == v) || (p == w)){continue;}var P = m_points[V[p]];if (InsideTriangle(A, B, C, P)){return false;}}return true;}
function InsideTriangle(A, B, C, P){var ax, ay, bx, by, cx, cy, apx, apy, bpx, bpy, cpx, cpy,cCROSSap, bCROSScp, aCROSSbp;ax = C[0] - B[0]; ay = C[1] - B[1];bx = A[0] - C[0]; by = A[1] - C[1];cx = B[0] - A[0]; cy = B[1] - A[1];apx = P[0] - A[0]; apy = P[1] - A[1];bpx = P[0] - B[0]; bpy = P[1] - B[1];cpx = P[0] - C[0]; cpy = P[1] - C[1];aCROSSbp = ax * bpy - ay * bpx;cCROSSap = cx * apy - cy * apx;bCROSScp = bx * cpy - by * cpx;return ((aCROSSbp >= 0.0) && (bCROSScp >= 0.0) && (cCROSSap >= 0.0));}
function plotRandomPoint(triangle){var Ax,Ay,Bx,By,Cx,Cy, a,b,c, Px,Py;Ax = triangle[0][0];Ay = triangle[0][1];Bx = triangle[1][0];By = triangle[1][1];Cx = triangle[2][0];Cy = triangle[2][1];a = Math.random();b = Math.random()*(1-a);c = 1-a-b;Px = a*Ax + b*Bx + c*Cx;Py = a*Ay + b*By + c*Cy;app.activeDocument.pathItems.ellipse (Py+1,Px-1,2,2);}
function getRandomPoint(triangle){var Ax,Ay,Bx,By,Cx,Cy, a,b,c, Px,Py;Ax = triangle[0][0];Ay = triangle[0][1];Bx = triangle[1][0];By = triangle[1][1];Cx = triangle[2][0];Cy = triangle[2][1];do{a = Math.random();b = Math.random();} while (a + b >= 1);c = 1-a-b;Px = a*Ax + b*Bx + c*Cx;Py = a*Ay + b*By + c*Cy;return [Px,Py];}
function getCircleThru(v1, v2, v3){var x1 = v1[0],y1 = v1[1],x2 = v2[0],y2 = v2[1],x3 = v3[0],y3 = v3[1],s = 0.5*((x2 - x3)*(x1 - x3) - (y2 - y3)*(y3 - y1)),sUnder = (x1 - x2)*(y3 - y1) - (y2 - y1)*(x1 - x3);if (Math.abs(sUnder) < 0.001){return null;}s /= sUnder;var xc = 0.5*(x1 + x2) + s*(y2 - y1),yc = 0.5*(y1 + y2) + s*(x1 - x2);var radius = Math.sqrt((xc-x1)*(xc-x1)+(yc-y1)*(yc-y1));return [ xc, yc, radius ];}
function distanceToClosestEdge(pt, edgelist){var d,p, d2;d = ClosestPointOnLine (pt, [ edgelist[0][0], edgelist[0][1] ]);d = d[1];for (p=1; p<edgelist.length; p++){d2 = ClosestPointOnLine (pt, [ edgelist[p][0], edgelist[p][1] ]);if (d2[1] < d){d = d2[1];}}return d;}
function ClosestPointOnLine(pt, line){var X1 = line[0][0], Y1 = line[0][1],X2 = line[1][0], Y2 = line[1][1],px = pt[0], py = pt[1],dx = X2 - X1,dy = Y2 - Y1,nx,ny;if (dx == 0 && dy == 0){nx = X1;ny = Y1;}else{var t = ((px - X1) * dx + (py - Y1) * dy) / (dx * dx + dy * dy);if (t <= 0){nx = X1;ny = Y1;}else if (t >= 1){nx = X2;ny = Y2;} else{nx = X1 + t * dx;ny = Y1 + t * dy;}}dx = px - nx;dy = py - ny;return [ [nx, ny], Math.sqrt (dx * dx + dy * dy) ]}
function point(arr){this.x = arr[0];this.y = arr[1];this.distance = function (pt) { return Math.sqrt ( (this.x-pt.x)*(this.x-pt.x) + (this.y-pt.y)*(this.y-pt.y) ) }}
function saveSettings() {
var $file = new File(settingFile.folder + settingFile.name),
data = [
maxValue.text,
minValue.text,
guttersValue.text,
resizeValue.text,
rotateValue.text,
randomRotate.value,
rotateByValue.value,
objectPosTop.value,
objectPosBottom.value,
objectPosLayers.value,
randomItems.value,
removeTopElement.value,
groupResult.value
].toString();
$file.open('w');
$file.write(data);
$file.close();
}
function loadSettings() {
var $file = File(settingFile.folder + settingFile.name);
if ($file.exists) {
try {
$file.open('r');
var data = $file.read().split('\n'),
$main = data[0].split(',');
maxValue.text = $main[0];
minValue.text = $main[1];
guttersValue.text = $main[2];
resizeValue.text = $main[3];
rotateValue.text = $main[4];
randomRotate.value = ($main[5] === 'true');
rotateByValue.value = ($main[6] === 'true');
objectPosTop.value = ($main[7] === 'true');
objectPosBottom.value = ($main[8] === 'true');
objectPosLayers.value = ($main[9] === 'true');
randomItems.value = ($main[10] === 'true');
removeTopElement.value = ($main[11] === 'true');
groupResult.value = ($main[12] === 'true');
rotateValue.enabled = !randomRotate.value;
} catch (e) {}
$file.close();
}
}
win.onClose = function() {
saveSettings();
return true;
}
function checkSettingFolder() {
var $folder = new Folder(settingFile.folder);
if (!$folder.exists) $folder.create();
}
checkSettingFolder();
loadSettings();
win.center();
win.show();
}
Download it from original source : https://raw.githubusercontent.com/alexander-ladygin/illustrator-scripts/master/fillinger.jsx
Fillinger – Illustrator Script (0 downloads )