- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
尝试在 firemonkey 中实现类似于此的环形颜色选择器:http://dph.am/iDropper/
我认为可以使用在笔划上具有多点渐变的 TCircle 来完成。根据我的实验和研究,渐变只能从上到下或从中心向外。
有没有办法让TGradient跟随描边的路径?
最佳答案
它的边缘可能有点粗糙,但这里有一个基于 Firemonkey 环的颜色选择器,适合任何寻找的人......
必须归功于我用作此基础的 MX Software 的 mbColor Lib - http://mxs.bergsoft.net/ .
unit uRingColorPicker;
interface
uses
System.SysUtils, System.Classes, System.Types, FMX.Types, FMX.Controls,
FMX.Objects, FMX.Graphics, System.UITypes, Math, System.UIConsts,
FMX.Colors;
type
TRingColorPicker = class(TPaintBox)
private
{ Private declarations }
bm: TBitmap;
FOnChange: TNotifyEvent;
mdx, mdy: double;
FSat: integer;
FHue: integer;
FValue: integer;
FManual: boolean;
FChange: boolean;
FRadius: integer;
FHueLineColor: TAlphaColor;
FSelectedColor: TAlphaColor;
Quad: TColorQuad;
procedure PaintHSVCircle;
procedure UpdateCoords;
procedure SetHue(Value: integer);
procedure SetSat(Value: integer);
procedure SetValue(Value: integer);
procedure SetHueLineColor(const Value: TAlphaColor);
procedure SetSelectedColor(const Value: TAlphaColor);
procedure SetQuadPosSize;
procedure SelectionChanged(x, y: single);
function GetSelectedColor: TAlphaColor;
protected
{ Protected declarations }
procedure Paint; override;
procedure Resize; override;
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Single); override;
procedure MouseMove(Shift: TShiftState; X, Y: Single); override;
public
{ Public declarations }
property SelectedColor: TAlphaColor read GetSelectedColor write SetSelectedColor;
function PointInObject(X, Y: Single): Boolean; override;
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
{ Published declarations }
property Hue: integer read FHue write SetHue default 0;
property Saturation: integer read FSat write SetSat default 0;
property Value: integer read FValue write SetValue default 255;
property OnChange: TNotifyEvent read FOnChange write FOnChange;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('LightFactoryFMX', [TRingColorPicker]);
end;
function PointInCirc(p: TPointF; size : integer): boolean;
var
r: integer;
begin
r := size div 2;
Result := (SQR(p.x - r) + SQR(p.y - r) <= SQR(r));
end;
function MathRound(AValue: Extended): Int64; inline;
begin
if AValue >= 0 then
Result := Trunc(AValue + 0.5)
else
Result := Trunc(AValue - 0.5);
end;
function MulDiv(nNumber, nNumerator, nDenominator: Integer): Integer;
begin
if nDenominator = 0 then
Result := -1
else
Result := MathRound(Int64(nNumber) * Int64(nNumerator) / nDenominator);
end;
{ TRingColorPicker }
constructor TRingColorPicker.Create(AOwner: TComponent);
begin
inherited;
bm := TBitmap.Create;
bm.Resize(204, 204);
Width := 204;
Height := 204;
FManual := false;
FChange := true;
FRadius := Round(Width * 0.35);
Quad := TColorQuad.Create(Self);
Quad.Parent := self;
Quad.Visible := true;
Quad.Stored := false;
Quad.Locked := true;
Quad.Sat := 1;
Quad.Lum := 0.5;
end;
destructor TRingColorPicker.Destroy;
begin
bm.Free;
Quad.Free;
inherited;
end;
procedure TRingColorPicker.PaintHSVCircle;
var
i, j, size: integer;
vBitMapData : TBitmapData;
tc: TAlphaColor;
H, x, y, Radius, RadiusSquared, dSquared: Single;
begin
size := Round(Min(Width, Height));
Radius := size / 2;
RadiusSquared := Radius*Radius;
bm.Clear($00ffffff);
if bm.Map(TMapAccess.Write, vBitMapData) then
begin
for j := 0 to size - 1 do
begin
Y := Size - 1 - j - Radius;
for i := 0 to size - 1 do
begin
X := i - Radius;
dSquared := X*X + Y*Y;
if (dSquared>(RadiusSquared - (FRadius*FRadius))) and (dSquared <= RadiusSquared) then
begin
H := 180 * (1 + ArcTan2(X, Y) / PI);
H := H + 90;
if H > 360 then H := H - 360;
tc := HSLtoRGB(H/360, 1, 0.5); //S/255
vBitmapData.SetPixel(i, Size - 1 - j, tc); // set the pixel colour at x:10, y:20
end
end;
end;
bm.Unmap(vBitMapData); // unlock the bitmap
end;
end;
function TRingColorPicker.GetSelectedColor: TAlphaColor;
begin
result := Quad.ColorBox.Color;
end;
procedure TRingColorPicker.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Single);
begin
inherited;
if (Button = TMouseButton.mbLeft) and PointInCirc(PointF(x, y), Round(Min(Width, Height))) then
begin
SelectionChanged(X, Y);
FManual := true;
if Fchange then
if Assigned(FOnChange) then FOnChange(Self);
end;
SetFocus;
end;
procedure TRingColorPicker.SelectionChanged(x, y: Single);
var
Angle, Distance: integer;
xDelta, yDelta, Radius: Double;
begin
if PointInCirc(PointF(x, y), Round(Min(Width, Height))) then
begin
FSelectedColor := TAlphaColorRec.White;
Radius := Min(Width, Height) / 2;
xDelta := x - Radius;
yDelta := y - Radius;
Angle := ROUND(360 + 180*ArcTan2(-yDelta,xDelta)/PI);
if Angle < 0 then Inc(Angle, 360)
else if Angle > 360 then
Dec(Angle, 360);
Fchange := false;
SetHue(Angle);
Distance := ROUND(SQRT(SQR(xDelta) + SQR(yDelta)));
if Distance >= Radius then SetSat(255)
else SetSat(MulDiv(Distance, 255, Round(Radius)));
Fchange := true;
end;
end;
procedure TRingColorPicker.MouseMove(Shift: TShiftState; X, Y: Single);
begin
inherited;
if (ssLeft in Shift) and PointInCirc(PointF(x, y), Round(Min(Width, Height))) then
begin
SelectionChanged(X, Y);
FManual := true;
if Fchange then
if Assigned(FOnChange) then FOnChange(Self);
end;
end;
procedure TRingColorPicker.UpdateCoords;
var
r, angle: real;
radius: double;
begin
radius := Min(Width, Height) / 2;
r := -MulDiv(Round(radius), FSat, 255);
angle := -FHue*PI/180 - PI;
mdx := (COS(angle)*ROUND(r)) + radius;
mdy := (SIN(angle)*ROUND(r)) + radius;
end;
procedure TRingColorPicker.Paint;
begin
inherited;
PaintHSVCircle;
Canvas.BeginScene;
Canvas.DrawBitmap(bm, bm.BoundsF, bm.BoundsF, 1);
Canvas.EndScene;
SetQuadPosSize;
end;
function TRingColorPicker.PointInObject(X, Y: Single): Boolean;
var
size: integer;
Radius, RadiusSquared, dSquared: Single;
begin
X := X - Position.X;
Y := Y - Position.Y;
size := Round(Min(Width, Height));
Radius := size / 2;
RadiusSquared := Radius*Radius;
Y := Size - 1 - Y - Radius;
X := X - Radius;
dSquared := X*X + Y*Y;
result := (dSquared>(RadiusSquared - (FRadius*FRadius))) and (dSquared <= RadiusSquared);
end;
procedure TRingColorPicker.Resize;
begin
inherited;
bm.Resize(Round(Width), Round(Height));
FRadius := Round(Width * 0.35);
UpdateCoords;
SetQuadPosSize;
end;
procedure TRingColorPicker.SetQuadPosSize;
var
size: integer;
Radius, a, d: Single;
begin
size := Round(Min(Width, Height));
Radius := Round(FRadius * 0.9);
a := SQRT((Radius*Radius) / 2);
d := (size / 2) - a;
if assigned(Quad) then
begin
if Quad.Position.X <> d then
Quad.Position.X := d;
if Quad.Position.Y <> d then
Quad.Position.Y := d;
if Quad.Width <> a * 2 then
Quad.Width := a * 2;
if Quad.Height <> a * 2 then
Quad.Height := a * 2;
end;
end;
procedure TRingColorPicker.SetHue(Value: integer);
begin
if Value > 360 then Value := 360;
if Value < 0 then Value := 0;
if FHue <> Value then
begin
FHue := Value;
FManual := false;
UpdateCoords;
InvalidateRect(RectF(0,0,width,height));
Quad.Hue := Value/360;
Quad.RotationAngle := 360-FHue;
if Fchange then
if Assigned(FOnChange) then FOnChange(Self);
end;
end;
procedure TRingColorPicker.SetHueLineColor(const Value: TAlphaColor);
begin
if FHueLineColor <> Value then
begin
FHueLineColor := Value;
InvalidateRect(RectF(0,0,width,height));
end;
end;
procedure TRingColorPicker.SetSat(Value: integer);
begin
if Value > 255 then Value := 255;
if Value < 0 then Value := 0;
if FSat <> Value then
begin
FSat := Value;
FManual := false;
UpdateCoords;
InvalidateRect(RectF(0,0,width,height));
if Fchange then
if Assigned(FOnChange) then FOnChange(Self);
end;
end;
procedure TRingColorPicker.SetSelectedColor(const Value: TAlphaColor);
var
H, S, L: Single;
begin
FSelectedColor := Value;
RGBtoHSL(FSelectedColor, H, S, L);
Fchange := false;
SetHue(Round(H*360));
Quad.Sat := S;
Quad.Lum := L;
Fchange := true;
end;
procedure TRingColorPicker.SetValue(Value: integer);
begin
if Value > 255 then Value := 255;
if Value < 0 then Value := 0;
if FValue <> Value then
begin
FValue := Value;
FManual := false;
InvalidateRect(RectF(0,0,width,height));
if Fchange then
if Assigned(FOnChange) then FOnChange(Self);
end;
end;
end.
关于delphi - firemonkey中的圆形颜色渐变(色调),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39629686/
如何使用 Firemonkey (XE6) 绘制贝塞尔曲线? XE6 wiki 中的文档目前有点稀疏。 最佳答案 以下代码可用于使用 Firemonkey XE6 绘制简单的贝塞尔曲线。创建一个新的
创建自定义 FireMonkey 样式时,您经常会遇到样式对象,例如 TButtonStyleObject,其中包含一个或多个属性(例如 TButtonStyleObject.NormalLink),
我正在努力让 FireMonkey TEdit 嵌套在 FireMonkey TPopup 中来接收键盘输入。桌面和移动项目都会发生这种情况,尽管我对后者感兴趣: 创建一个新的 FMX 项目。 向表单
我使用以下方法向 Treeviewitem 的复选框添加功能。 function TForm.CreateTVObj:TTreeviewItem; var MyCheckbox:TCheckbox
我有个问题。 我用这个简单的代码添加了一个按钮,但它没有编译任何解决方案? unit Unit1; interface uses System.SysUtils, System.Types, Syst
似乎我需要一个项目的帮助。 我有一个例程,该例程将运行时多个TabItem构造到firemonkey中的页面控件上,并且我想在该标签上有一个关闭按钮。 新选项卡上有一个复选框,用于从选项卡的样式器中加
这个问题在这里已经有了答案: How to free a component in Android / iOS (2 个回答) 7年前关闭。 为了灵 active ,不同的框架(如可见的“模块”,可以
我正在使用 Canvas 绘制函数drawrect和filltext在Tbitmap上绘制,但我不希望结果抗锯齿。有人知道该怎么做吗? 使用 OSX 和 Delphi XE3(但如果需要,可以使用 X
FireMonkey 中是否可以有可停靠的表单,因为我已经检查了表单属性,但没有这样的属性可以做到这一点。有什么解决方法可以实现这一点吗? 最佳答案 据我所知,没有内置任何内容,但您自己添加应该不会太
如果您希望 FireMonkey 中网格的同一列中存在不同的单元格控件,该怎么办?单元格控件似乎属于列,但在某些情况下(如属性编辑器),某些行需要复选框,而其他行需要组合框或编辑控件。 提前致谢。 最
我已将 ......\RAD Studio\9.0\Styles 中的几个示例样式作为资源加载到我的项目中,并且“简单地”尝试在运行时加载其中一个。 我正在使用以下代码来尝试执行此操作: var
在我的应用程序中,有一个文本字段,用户可以在其中输入他们的帐户电子邮件。 使用Java,我可以轻松地让 Android 键盘以小写字母开头 EditText text = new EditText(c
我目前正在尝试 Firemonkey 并遇到了这个问题。当我的申请中有多个表格时,我会得到相同数量的项目在我的 Windows 菜单栏中的一个应用程序(参见屏幕截图)。 在常规 VCL 应用程序中,只
我在 Delphi 中有一个程序,可以将图像组件从一个面板拖放到另一个面板,但在这里我对每个图像组件使用“TWincontrol”和“OnStartDrag”事件,并且效果很好,示例代码如下。当我在
我正在寻找一种在 firemonkey 应用程序中缓存全局热键的方法(仅限 Windows,至少目前如此)。经过一番挫折和谷歌搜索后,这应该可以工作:使用 winapi 调用注册热键 Register
Classic VCL question ...但是如何在 FireMonkey 中执行相同的操作? 我有几个标准的TControl,他们可以集中精力... 例如,在某些TEdit中,如果按返回键,我
我们从版本 1 开始就使用 Firemonkey,但仍然发现更新当前在屏幕上可见的组件很困难。在 Firemonkey 中请求重画的“方式”有很多,也许太多了: 应用样式(ApplyStyle 事件)
在 firemonkey 中,我尝试使用圆角矩形制作进度条。最简单的情况是一个矩形(进度条)和其中的第二个矩形(到目前为止的进度)。附上一个简单的例子。 带角的进度条(油漆): 我尝试过以下操作: 让
我正在使用 Delphi Seattle,我的应用程序适用于 Windows 桌面。 我正在尝试更改 TEdit 的字体大小。因此高度也被修改。在设计时一切正常,但当我运行应用程序时,TEdit 会忽
我目前正在尝试开发一个基于 Firemonkey 的项目。我使用 Firemonkey 是因为它的 UI 功能,因为该项目由许多较小的应用程序组成,每个应用程序都有 3D 方面。我目前仅使用 FMX
我是一名优秀的程序员,十分优秀!