ScriptUi自定义形状按钮与OnDraw



我写了一个带有自定义圆形按钮的对话框的脚本(有点像官方的土坯按钮)。
由于不懂数学,我用直线画了这个按钮,像这样:

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);
}
}
}
}
}
}
}

然而,我在这个网站上看到,可以用几何公式绘制各种形状。
有谁知道按钮边上的半圆是怎么用"几何计算"画出来的吗?


更新

在与stib的代码和链接站点的代码混淆之后,我想出了这个最后的脚本:
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);
}
}
}
}
}
}
}

你知道循环是一个东西,对吧?

您链接到的网站只是使用直线,但使用各种曲线的公式生成每个部分。圆周长上一点的公式给定x轴与该点的夹角θ,半径r[ cos(θ), sin(θ) ] * r。您可以决定在半圆中需要多少段,并创建一个循环来调用该公式数次。

function halfCircle(
radius, //radius of the half circle
segStart, //coordinates of the start of the segment
angleStart, // angle of the start of the segment from the positive x axis
numSegments //how many segments to draw
){
var circle = {
x: function(i, r){ return Math.cos(i) * r},
y: function(i, r){ return Math.cos(i) * r}
}
var g = this.graphics;
g.newPath();
g.moveTo(segStart);
var increment = Math.pi / numSegments; //Pi in radians is 180°
var offset = angleStart * Math.pi / 180;
for (var i = 0; i < numSegments; i++){
g.lineTo(
circle.x(i * increment + offset, radius) + segStart, 
circle.y(i * increment + offset, radius) + segStart
);
}
}
halfCircle(340, [123,456], 123, 45);

如果你看看size[0]的值是170,size[1]的值是25,你可以用确切的值重写半圆代码:

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 (8.865, 0.53);
graphics.lineTo (5.99, 1.825);
graphics.lineTo (3.66, 3.66);
graphics.lineTo (1.825, 5.99);
graphics.lineTo (0.53, 8.865);
graphics.lineTo (0, 12.5);
graphics.lineTo (0.53, 8.865);
graphics.lineTo (1.825, 5.99);
graphics.lineTo (3.66, 3.66);
graphics.lineTo (5.99, 1.825);
graphics.lineTo (8.865, 0.53);

所以现在只是用[ cos(θ), sin(θ) ] * r代替x和y值的问题,因为stib已经在他更好(更快)的答案中向您展示了。

最新更新