I wrote a script with a dialog with custom round buttons (something like the official adobe ones).
Being ignorant of mathematics, I drew the button with straight lines, like this:
ButtonPanel ();
function ButtonPanel () {
var Panel = new Window ("dialog");
Panel.text = "Panel";
var Button = Panel.add ("button");
Button.text = "Exit";
Button.preferredSize.width = 170;
Button.onClick = function () {
Panel.close ();
}
Draw (Button);
Panel.show ();
function Draw (Obj) {
if (Obj.type == "button") {
Obj.graphics.foregroundColor = Obj.graphics.newPen (Obj.graphics.PenType.SOLID_COLOR, [1, 1, 1], 1);
Obj.graphics.font = ScriptUI.newFont (Obj.graphics.font.name, "Bold", Obj.graphics.font.size);
Obj.onDraw = function (Event) {
with (Obj) {
graphics.drawOSControl ();
graphics.newPath ();
graphics.moveTo ((size[0] / 340) * 25, (size[1] / 50) * 0);
graphics.lineTo ((size[0] / 340) * 17.73, (size[1] / 50) * 1.06);
graphics.lineTo ((size[0] / 340) * 11.98, (size[1] / 50) * 3.65);
graphics.lineTo ((size[0] / 340) * 7.32, (size[1] / 50) * 7.32);
graphics.lineTo ((size[0] / 340) * 3.65, (size[1] / 50) * 11.98);
graphics.lineTo ((size[0] / 340) * 1.06, (size[1] / 50) * 17.73);
graphics.lineTo ((size[0] / 340) * 0, (size[1] / 50) * 25);
graphics.lineTo ((size[0] / 340) * 1.06, (size[1] / 50) * 32.26);
graphics.lineTo ((size[0] / 340) * 3.65, (size[1] / 50) * 38.02);
graphics.lineTo ((size[0] / 340) * 7.32, (size[1] / 50) * 42.68);
graphics.lineTo ((size[0] / 340) * 11.98, (size[1] / 50) * 46.35);
graphics.lineTo ((size[0] / 340) * 17.73, (size[1] / 50) * 48.93);
graphics.lineTo ((size[0] / 340) * 25, (size[1] / 50) * 50);
graphics.lineTo ((size[0] / 340) * 315, (size[1] / 50) * 50);
graphics.lineTo ((size[0] / 340) * 322.25, (size[1] / 50) * 48.93);
graphics.lineTo ((size[0] / 340) * 328, (size[1] / 50) * 46.35);
graphics.lineTo ((size[0] / 340) * 332.66, (size[1] / 50) * 42.68);
graphics.lineTo ((size[0] / 340) * 336.34, (size[1] / 50) * 38.02);
graphics.lineTo ((size[0] / 340) * 338.92, (size[1] / 50) * 32.26);
graphics.lineTo ((size[0] / 340) * 340, (size[1] / 50) * 25);
graphics.lineTo ((size[0] / 340) * 338.92, (size[1] / 50) * 17.73);
graphics.lineTo ((size[0] / 340) * 336.34, (size[1] / 50) * 11.98);
graphics.lineTo ((size[0] / 340) * 332.66, (size[1] / 50) * 7.32);
graphics.lineTo ((size[0] / 340) * 328, (size[1] / 50) * 3.65);
graphics.lineTo ((size[0] / 340) * 322.25, (size[1] / 50) * 1.06);
graphics.lineTo ((size[0] / 340) * 315, (size[1] / 50) * 0);
graphics.lineTo ((size[0] / 340) * 25, (size[1] / 50) * 0);
graphics.closePath ();
graphics.fillPath (graphics.newBrush (graphics.BrushType.SOLID_COLOR, [1, 0, 0]));
graphics.closePath ();
if (text) {
graphics.drawString (text, (graphics.newPen (graphics.PenType.SOLID_COLOR, [1, 1, 1], 1)), (size[0] - graphics.measureString (text, graphics.font, size[0])[0]) / 2, (size[1] - graphics.measureString (text, graphics.font, size[1])[1]) / 2, graphics.font);
}
if (Event.mouseOver) {
graphics.fillPath (graphics.newBrush (graphics.BrushType.SOLID_COLOR, [1, 1, 1]));
if (text) {
graphics.drawString (text, (graphics.newPen (graphics.PenType.SOLID_COLOR, [1, 0, 0], 1)), (size[0] - graphics.measureString (text, graphics.font, size[0])[0]) / 2, (size[1] - graphics.measureString (text, graphics.font, size[1])[1]) / 2, graphics.font);
}
}
}
}
}
}
}
However I have seen on this site that it is possible to draw the various shapes with a geometric formulas.
Does anyone know how the half circles on the sides of the button could be drawn with "geometric calculations"?
UPDATE
After messing with the stib’s code and the linked site’s one, I came up with this final script:
ButtonPanel ();
function ButtonPanel () {
var Panel = new Window ("dialog");
Panel.text = "Panel";
var Button = Panel.add ("button");
Button.text = "Exit";
Button.preferredSize.width = 170;
Button.onClick = function () {
Panel.close ();
}
Draw (Button);
Panel.show ();
function Draw (Obj) {
if (Obj.type == "button") {
Obj.graphics.foregroundColor = Obj.graphics.newPen (Obj.graphics.PenType.SOLID_COLOR, [1, 1, 1], 1);
Obj.graphics.font = ScriptUI.newFont (Obj.graphics.font.name, "Bold", Obj.graphics.font.size);
Obj.onDraw = function (Event) {
with (Obj) {
graphics.drawOSControl ();
graphics.newPath ();
graphics.moveTo (12.5, 0);
for (var i = 0; i < Math.PI; i += Math.PI / 100) {
graphics.lineTo ((-12.5 * Math.sin (i)) + 12.5, (-12.5 * Math.cos (i)) + 12.5);
}
graphics.lineTo (157.5, 25);
for (var i = 0; i < Math.PI; i += Math.PI / 100) {
graphics.lineTo ((12.5 * Math.sin (i)) + 157.5, (12.5 * Math.cos (i)) + 12.5);
}
graphics.lineTo (12.5, 0);
graphics.closePath ();
graphics.fillPath (graphics.newBrush (graphics.BrushType.SOLID_COLOR, [1, 0, 0]));
if (text) {
graphics.drawString (text, (graphics.newPen (graphics.PenType.SOLID_COLOR, [1, 1, 1], 1)), (size[0] - graphics.measureString (text, graphics.font, size[0])[0]) / 2, (size[1] - graphics.measureString (text, graphics.font, size[1])[1]) / 2, graphics.font);
}
if (Event.mouseOver) {
graphics.fillPath (graphics.newBrush (graphics.BrushType.SOLID_COLOR, [1, 1, 1]));
if (text) {
graphics.drawString (text, (graphics.newPen (graphics.PenType.SOLID_COLOR, [1, 0, 0], 1)), (size[0] - graphics.measureString (text, graphics.font, size[0])[0]) / 2, (size[1] - graphics.measureString (text, graphics.font, size[1])[1]) / 2, graphics.font);
}
}
}
}
}
}
}
2
Answers
Oof. You know that loops are a thing right?
The site you link to is just using straight lines but is generating each segment using the formula for the various curves. The formula for a point on the circumference of a circle given the angle
θ
from the x axis to the point, and the radiusr
is[ cos(θ), sin(θ) ] * r
. You can decide how many segments you want in the half circle and make a loop to call that formula that many times.If you look at the values of size[0] which is 170 and size[1], which is 25 you can rewrite the semi circle code with the exact values:
or simply
So it’s now simply a matter of substituting the x an y values with
[ cos(θ), sin(θ) ] * r
as stib has shown you in his much better (and quicker) answer.