unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, Spin,
ExtCtrls, StdCtrls, BGRAVirtualScreen, BGRABitmap, BGRABitmapTypes,
BGRACanvas2D;
const
timeGrain = 15/1000/60/60/24;
type
{ TForm1 }
TForm1 = class(TForm)
Button_toDataURL: TButton;
CheckBox_Antialiasing: TCheckBox;
CheckBox_PixelCentered: TCheckBox;
Panel1: TPanel;
SaveDialog1: TSaveDialog;
SpinEdit1: TSpinEdit;
VirtualScreen: TBGRAVirtualScreen;
Timer1: TTimer;
procedure Button_toDataURLClick(Sender: TObject);
procedure CheckBox_AntialiasingChange(Sender: TObject);
procedure CheckBox_PixelCenteredChange(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormMouseLeave(Sender: TObject);
procedure FormMouseMove(Sender: TObject; {%H-}Shift: TShiftState; {%H-}X, {%H-}Y: Integer);
procedure FormPaint(Sender: TObject);
procedure SpinEdit1Change(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure VirtualScreenMouseLeave(Sender: TObject);
procedure VirtualScreenMouseMove(Sender: TObject; {%H-}Shift: TShiftState; X,
Y: Integer);
procedure VirtualScreenRedraw(Sender: TObject; Bitmap: TBGRABitmap);
private
{ private declarations }
mx,my: integer;
lastTime: TDateTime;
timeGrainAcc: double;
test4pos, test5pos, Test13pos, test16pos, test17pos, test18pos, test19pos, test23pos: integer;
img,abelias: TBGRABitmap;
procedure UpdateIn(ms: integer);
procedure UseVectorizedFont(ctx: TBGRACanvas2D; AUse: boolean);
public
{ public declarations }
procedure Test1(ctx: TBGRACanvas2D);
procedure Test2(ctx: TBGRACanvas2D);
procedure Test3(ctx: TBGRACanvas2D);
procedure Test4(ctx: TBGRACanvas2D; grainElapse: integer);
procedure Test5(ctx: TBGRACanvas2D; grainElapse: integer);
procedure Test6(ctx: TBGRACanvas2D);
procedure Test7(ctx: TBGRACanvas2D);
procedure Test8(ctx: TBGRACanvas2D);
procedure Test9(ctx: TBGRACanvas2D);
procedure Test10(ctx: TBGRACanvas2D);
procedure Test11(ctx: TBGRACanvas2D);
procedure Test12(ctx: TBGRACanvas2D);
procedure Test13(ctx: TBGRACanvas2D);
procedure Test14(ctx: TBGRACanvas2D);
procedure Test15(ctx: TBGRACanvas2D);
procedure Test16(ctx: TBGRACanvas2D; grainElapse: integer);
procedure Test17(ctx: TBGRACanvas2D; grainElapse: integer);
procedure Test18(ctx: TBGRACanvas2D; grainElapse: integer);
procedure Test19(ctx: TBGRACanvas2D; grainElapse: integer);
procedure Test20(ctx: TBGRACanvas2D; AVectorizedFont: boolean);
procedure Test22(ctx: TBGRACanvas2D);
procedure Test23(ctx: TBGRACanvas2D; grainElapse: integer);
end;
var
Form1: TForm1;
implementation
uses BGRAGradientScanner, Math, BGRASVG, BGRAVectorize;
{$R *.lfm}
{ TForm1 }
procedure TForm1.FormPaint(Sender: TObject);
begin
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
img := TBGRABitmap.Create(ExtractFilePath(Application.ExeName)+'pteRaz.jpg');
abelias := TBGRABitmap.Create(ExtractFilePath(Application.ExeName)+'abelias.png');
mx := -1000;
my := -1000;
lastTime := Now;
VirtualScreen.Color := $d0d0d0;
end;
procedure TForm1.CheckBox_PixelCenteredChange(Sender: TObject);
begin
VirtualScreen.DiscardBitmap;
end;
procedure TForm1.Button_toDataURLClick(Sender: TObject);
var html: string;
t: textfile;
begin
if SaveDialog1.Execute then
begin
html := '
';
assignfile(t,SaveDialog1.FileName);
rewrite(t);
write(t,html);
closefile(t);
MessageDlg('toDataURL','Output: '+ SaveDialog1.FileName,mtInformation,[mbOK],0);
end;
end;
procedure TForm1.CheckBox_AntialiasingChange(Sender: TObject);
begin
VirtualScreen.DiscardBitmap;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
img.Free;
abelias.free;
end;
procedure TForm1.FormMouseLeave(Sender: TObject);
begin
end;
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
end;
procedure TForm1.SpinEdit1Change(Sender: TObject);
begin
VirtualScreen.DiscardBitmap;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
Timer1.Enabled := false;
VirtualScreen.DiscardBitmap;
end;
procedure TForm1.VirtualScreenMouseLeave(Sender: TObject);
begin
mx := -1000;
my := -1000;
end;
procedure TForm1.VirtualScreenMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
mx := X;
my := Y;
if (SpinEdit1.Value = 1) and not Timer1.Enabled then UpdateIn(10);
end;
procedure TForm1.VirtualScreenRedraw(Sender: TObject; Bitmap: TBGRABitmap);
var ctx: TBGRACanvas2D;
grainElapse: integer;
newTime: TDateTime;
begin
newTime := Now;
timeGrainAcc += (newTime - lastTime)/timeGrain;
lastTime := newTime;
if timeGrainAcc < 1 then timeGrainAcc := 1;
if timeGrainAcc > 50 then timeGrainAcc := 50;
grainElapse := trunc(timeGrainAcc);
timeGrainAcc -= grainElapse;
ctx := Bitmap.Canvas2D;
ctx.antialiasing := CheckBox_Antialiasing.Checked;
ctx.pixelCenteredCoordinates := CheckBox_PixelCentered.Checked;
ctx.save;
case SpinEdit1.Value of
1: Test1(ctx);
2: Test2(ctx);
3: Test3(ctx);
4: Test4(ctx, grainElapse);
5: Test5(ctx, grainElapse);
6: Test6(ctx);
7: Test7(ctx);
8: Test8(ctx);
9: Test9(ctx);
10: Test10(ctx);
11: Test11(ctx);
12: Test12(ctx);
13: Test13(ctx);
14: Test14(ctx);
15: Test15(ctx);
16: Test16(ctx, grainElapse);
17: Test17(ctx, grainElapse);
18: Test18(ctx, grainElapse);
19: Test19(ctx, grainElapse);
20: Test20(ctx,false);
21: Test20(ctx,true);
22: Test22(ctx);
23: Test23(ctx,grainElapse);
end;
ctx.restore;
end;
procedure TForm1.UpdateIn(ms: integer);
begin
Timer1.Interval := ms;
Timer1.Enabled := false;
Timer1.Enabled := true;
end;
procedure TForm1.UseVectorizedFont(ctx: TBGRACanvas2D; AUse: boolean);
begin
if AUse and not (ctx.fontRenderer is TBGRAVectorizedFontRenderer) then
ctx.fontRenderer := TBGRAVectorizedFontRenderer.Create;
if not AUse and (ctx.fontRenderer is TBGRAVectorizedFontRenderer) then
ctx.fontRenderer := nil;
end;
procedure TForm1.Test1(ctx: TBGRACanvas2D);
procedure DrawShape(colors: TBGRACustomGradient);
begin
ctx.fillStyle('rgb(1000,1000,1000)'); //out of bounds so it is saturated to 255,255,255
ctx.fillRect (0, 0, ctx.Width, ctx.Height);
ctx.fillStyle(ctx.createLinearGradient(0,0,20,0,colors));
ctx.shadowOffset := PointF(10,10);
ctx.shadowColor('rgba(0,0,0,0.5)');
ctx.shadowBlur := 4;
ctx.fillRect (mx-100, my-100, 200, 200);
end;
var
colors: TBGRACustomGradient;
begin
if (mx < 0) or (my < 0) then
begin
mx := ctx.Width div 2;
my := ctx.height div 2;
end;
ctx.save;
ctx.beginPath;
ctx.moveTo(0,0);
ctx.lineTo(ctx.Width,0);
ctx.lineTo(0,ctx.Height);
ctx.clip;
colors := TBGRAMultiGradient.Create([BGRA(0,255,0),BGRA(0,192,128),BGRA(0,255,0)],[0,0.5,1],True,True);
DrawShape(colors);
colors.Free;
ctx.restore;
ctx.save;
ctx.beginPath;
ctx.moveTo(ctx.Width,ctx.Height);
ctx.lineTo(0,ctx.Height);
ctx.lineTo(ctx.Width,0);
ctx.clip;
colors := TBGRAMultiGradient.Create([BGRA(0,255,255),BGRA(0,192,128),BGRA(0,255,255)],[0,0.5,1],True,True);
DrawShape(colors);
colors.Free;
ctx.restore;
end;
procedure TForm1.Test2(ctx: TBGRACanvas2D);
var layer: TBGRABitmap;
begin
layer := TBGRABitmap.Create(ctx.width,ctx.height);
with layer.Canvas2D do
begin
pixelCenteredCoordinates:= ctx.pixelCenteredCoordinates;
antialiasing:= ctx.antialiasing;
fillStyle('rgb(1000,0,0)'); // fond de couleur rouge
beginPath;
roundRect(25,25,Width-50,Height-50,25); // remplissage d un carré 250x250
fill;
clearRect(Width-mx-25,Height-my-25,50,50); // effacement d un carré
beginPath;
arc(mx,my,30,0,2*Pi);
clearPath;
strokeStyle ('rgb(0,0,1000)'); // contour de couleur bleue
strokeRect(100,100,20,20); // contour d un carré
shadowOffset := PointF(3,3);
shadowColor('rgba(0,0,0,0.5)');
shadowBlur := 4;
beginPath;
lineWidth := 3;
moveTo(20,160);
lineTo(200,160);
lineStyle([3,1]);
stroke;
beginPath;
moveTo(20,180);
lineTo(220,180);
lineTo(240,160);
lineStyle([1,1,2,2]);
stroke;
end;
ctx.surface.PutImage(0,0,layer,dmDrawWithTransparency);
layer.Free;
UpdateIn(10);
end;
procedure TForm1.Test3(ctx: TBGRACanvas2D);
begin
ctx.fillStyle ('rgb(1000,1000,1000)');
ctx.fillRect (0, 0, ctx.width, ctx.height);
// Triangle plein sans bordure
ctx.beginPath();
ctx.moveTo(100,100);
ctx.lineTo(150,30);
ctx.lineTo(230,150);
ctx.closePath();
if ctx.isPointInPath(mx+0.5,my+0.5) then
ctx.fillStyle ('rgb(1000,192,192)')
else
ctx.fillStyle ('rgb(1000,0,0)');
ctx.fill();
// Triangle plein avec bordure
ctx.fillStyle ('rgb(0,1000,0)');
ctx.strokeStyle ('rgb(0,0,1000)');
ctx.lineWidth := 8;
ctx.beginPath();
ctx.moveTo(50,100);
ctx.lineTo(50,220);
ctx.lineTo(210,200);
ctx.closePath();
if ctx.isPointInPath(mx+0.5,my+0.5) then
ctx.fillStyle ('rgb(192,1000,192)')
else
ctx.fillStyle ('rgb(0,1000,0)');
ctx.fill();
ctx.stroke();
// Triangle plein avec bordure
UpdateIn(50);
end;
procedure TForm1.Test4(ctx: TBGRACanvas2D; grainElapse: integer);
var angle: single;
p0,p1,p2: TPointF;
begin
inc(test4pos, grainElapse);
angle := test4pos*2*Pi/400;
ctx.translate((ctx.Width-300)/2,(ctx.height-300)/2);
ctx.skewx( sin(angle) );
ctx.beginPath;
ctx.rect (0, 0, 300, 300);
ctx.fillStyle (CSSYellow);
ctx.strokeStyle(CSSRed);
ctx.lineWidth := 5;
ctx.strokeOverFill;
ctx.beginPath();
// coord. centre 150,150 rayon : 50 angle départ 0 fin 2Pi, sens
ctx.arc(150,150,50,0,PI*2,true); // Cercle
ctx.moveTo(100,150); // aller au pt de départ de l arc
ctx.arc(100,100,50,PI/2,PI,false); // Arc sens aig. montre
ctx.moveTo(150,150); // aller au pt de départ de l arc
ctx.arc(200,150,50,2*PI/2,0,false); // Autre cercle
ctx.lineWidth := 1;
ctx.strokeStyle(BGRABlack);
ctx.stroke();
ctx.lineJoin := 'round';
angle := test4pos*2*Pi/180;
p0 := PointF(150,50);
p1 := pointF(150+50,50);
p2 := pointF(150+50+cos(sin(angle)*Pi/2)*40,50+sin(sin(angle)*Pi/2)*40);
ctx.beginPath;
ctx.moveTo(p0);
ctx.arcTo(p1, p2, 30);
ctx.lineTo(p2);
ctx.lineWidth := 5;
ctx.strokeStyle( BGRA(240,170,0) );
ctx.stroke();
ctx.beginPath;
ctx.moveTo(p0);
ctx.lineTo(p1);
ctx.lineTo(p2);
ctx.strokeStyle( BGRA(0,0,255) );
ctx.lineWidth := 2;
ctx.stroke();
UpdateIn(10);
end;
procedure TForm1.Test5(ctx: TBGRACanvas2D; grainElapse: integer);
var svg: TBGRASVG;
begin
inc(test5pos, grainElapse);
svg := TBGRASVG.Create;
svg.LoadFromFile(ExtractFilePath(Application.ExeName)+'Amsterdammertje-icoon.svg');
svg.StretchDraw(ctx, taCenter,tlCenter, 0,0,ctx.Width/3,ctx.Height);
svg.LoadFromFile(ExtractFilePath(Application.ExeName)+'BespectacledMaleUser.svg');
svg.StretchDraw(ctx, ctx.Width/3,0,ctx.Width*2/3,ctx.Height/2);
ctx.save;
ctx.beginPath;
ctx.rect(ctx.Width/3,ctx.Height/2,ctx.Width*2/3,ctx.Height/2);
ctx.clip;
svg.LoadFromFile(ExtractFilePath(Application.ExeName)+'Blue_gyroelongated_pentagonal_pyramid.svg');
svg.Draw(ctx, taCenter,tlCenter, ctx.Width*2/3,ctx.Height*3/4);
ctx.restore;
svg.Free;
ctx.beginPath;
ctx.lineWidth:= 1;
ctx.strokeStyle(BGRABlack);
ctx.moveTo(ctx.Width/3,0);
ctx.lineTo(ctx.Width/3,ctx.Height);
ctx.moveTo(ctx.Width/3,ctx.Height/2);
ctx.lineTo(ctx.Width,ctx.Height/2);
ctx.stroke;
UpdateIn(20);
end;
procedure TForm1.Test6(ctx: TBGRACanvas2D);
begin
ctx.fillStyle ('rgb(1000,1000,1000)');
ctx.fillRect (0, 0, 300, 300);
// Exemple de courbes de Bézier
ctx.fillStyle ( 'yellow');
ctx.lineWidth := 15;
ctx.lineCap := 'round'; // round butt square
ctx.lineJoin := 'miter'; // round miter bevel
ctx.strokeStyle ('rgb(200,200,1000)');
ctx.beginPath();
ctx.moveTo(50,150);
ctx.bezierCurveTo(50,80,100,60,130,60);
ctx.bezierCurveTo(180,60,250,50,260,130);
ctx.bezierCurveTo(150,150,150,150,120,280);
ctx.bezierCurveTo(50,250,100,200,50,150);
ctx.fill();
ctx.stroke();
end;
procedure TForm1.Test7(ctx: TBGRACanvas2D);
var
i: Integer;
begin
ctx.fillStyle('black');
ctx.fillRect(0, 0, 300, 300);
// Dessin du fond
ctx.fillStyle ('red');
ctx.fillRect(0, 0, 150, 150);
ctx.fillStyle ('blue');
ctx.fillRect(150, 0, 150, 150);
ctx.fillStyle ('yellow');
ctx.fillRect(0, 150, 150, 150);
ctx.fillStyle ('green');
ctx.fillRect(150, 150, 150, 150);
ctx.fillStyle ('#FFF');
// Définition de la valeur de transparence
ctx.globalAlpha := 0.1;
// Dessin de carrés semi transparents
for i := 0 to 9 do
begin
ctx.beginPath();
ctx.fillRect(10*i, 10*i, 300-20*i, 300-20*i);
ctx.fill();
end;
end;
procedure TForm1.Test8(ctx: TBGRACanvas2D);
begin
ctx.drawImage(img, 0, 0);
ctx.globalAlpha:= 0.5;
ctx.drawImage(img, 100, 100);
ctx.globalAlpha := 0.9;
ctx.translate(100,100);
ctx.beginPath;
ctx.moveTo(50,50);
ctx.lineTo(300,50);
ctx.lineTo(500,200);
ctx.lineTo(50,200);
ctx.fillStyle(img);
ctx.fill;
end;
procedure TForm1.Test9(ctx: TBGRACanvas2D);
var
i: Integer;
j: Integer;
begin
ctx.translate(ctx.Width/2 -15*10, ctx.Height/2 -15*10);
ctx.strokeStyle ('#000');
ctx.lineWidth :=4;
for i := 0 to 14 do
for j := 0 to 14 do
begin
ctx.fillStyle (BGRA ( 255-18*i, 255-18*j, 0) );
ctx.strokeStyle (BGRA( 20+10*j, 20+8*i, 0) );
ctx.fillRect(j*20, i*20, 20, 20);
ctx.strokeRect(j*20, i*20, 20, 20)
end;
end;
procedure TForm1.Test10(ctx: TBGRACanvas2D);
var
i: Integer;
j: Integer;
begin
ctx.translate(ctx.Width/2, ctx.Height/2); // centre 0 0 maintenant en position centrale
for i := 1 to 9 do
begin
ctx.save(); // contrebalancé par un restore
ctx.fillStyle ( BGRA(25*i,255-25*i,255) );
for j := 0 to i*5 do
begin
ctx.rotate(PI*2/(1+i*5)); //
ctx.beginPath();
ctx.arc(0, i*16, 6, 0, PI*2, true);
ctx.fill();
end;
ctx.restore();
end;
end;
procedure TForm1.Test11(ctx: TBGRACanvas2D);
const sc=20; // nb de pixels pour une unité
var
H: LongInt;
W: LongInt;
i: Integer;
x,u: Single;
function f(x: single): single; // fonction à tracer
begin
result := 3*sin(x)*(cos(x)+1/2*cos(x/2)+1/3*cos(x/3)+1/4*cos(x/4));
end;
begin
H := ctx.height;
W := ctx.width;
// tracé du quadrillage
ctx.strokeStyle ('#666');
ctx.beginPath();
ctx.lineWidth:=0.5;
// lignes horizontales
for i := -trunc(H/2/sc) to trunc(H/2/sc) do
begin
ctx.moveTo(0, H/2-sc*i);
ctx.lineTo(W, H/2-sc*i);
end;
// lignes verticales
for i := 0 to trunc(W/sc) do
begin
ctx.moveTo(sc*i,H-0);
ctx.lineTo(sc*i, H-H);
end;
ctx.stroke();
// tracé de la fonction
ctx.strokeStyle ('#ff0000');
ctx.lineWidth:=1.5;
ctx.beginPath();
x:=0;
u:=f(x);
ctx.moveTo(0, H/2-u*sc);
while x < W/sc do
begin
u := f(x);
ctx.lineTo(x*sc, H/2-u*sc);
x += 1/sc;
end;
ctx.stroke();
end;
procedure TForm1.Test12(ctx: TBGRACanvas2D);
var
W: LongInt;
H: LongInt;
i: Integer;
j: Integer;
function color(): TBGRAPixel;
begin
result := BGRA(random(256),random(256),random(256));
end;
procedure drawSpirograph(R2: single; r: single; O: single);
var
x0,x1,x2: single;
y0,y1,y2: single;
i: integer;
begin
x0 := R2-O;
y0 := 0;
i := 1;
ctx.beginPath();
x1 := x0;
y1 := y0;
ctx.moveTo(x1, y1);
repeat
if (i > 1000) then break;
x2 := (R2+r)*cos(i*PI/72) - (r+O)*cos(((R2+r)/r)*(i*PI/72));
y2 := (R2+r)*sin(i*PI/72) - (r+O)*sin(((R2+r)/r)*(i*PI/72));
ctx.lineTo(x2, y2);
x1 := x2;
y1 := y2;
inc(i);
until (abs(x2-x0) < 1e-6) and (abs(y2-y0) < 1e-6);
ctx.stroke();
end;
begin
W := ctx.width;
H := ctx.height;
ctx.fillRect(0, 0, W, H);
for i := 0 to 1 do
for j := 0 to 2 do
begin
ctx.save();
ctx.strokeStyle ( color() );
ctx.translate(110+j*200, 100+i*160);
drawSpirograph(40*(j+2)/(j+1), -(3+random(11))*(i+3)/(i+1), 35);
ctx.restore();
end;
UpdateIn(3000);
end;
procedure TForm1.Test13(ctx: TBGRACanvas2D);
const vitesse = 1;
begin
ctx.fillStyle ('#000');
ctx.fillRect (0, 0, 800, 400);
ctx.clearRect(0, 0, 800, 400);
ctx.fillRect (0, 0, 800, 400);
ctx.setTransform(-0.55, 0.85, -1, 0.10, 100, 50+img.width*0.5);
ctx.rotate(PI*2*(Test13pos/360)*vitesse );
ctx.drawImage(img, img.width*(-0.5)-200, img.height*(-0.8));
inc(Test13pos);
if (Test13pos=360) then Test13pos := 0;
UpdateIn(10);
end;
procedure TForm1.Test14(ctx: TBGRACanvas2D);
procedure pave();
begin
ctx.save();
ctx.fillStyle ('rgb(130,100,800)');
ctx.strokeStyle ('rgb(0,0,300)');
ctx.beginPath();
ctx.lineWidth:=2;
ctx.moveTo(5,5);ctx.lineTo(20,10);ctx.lineTo(55,5);ctx.lineTo(45,18);ctx.lineTo(30,50);
ctx.closePath();
ctx.stroke();
ctx.fill();
ctx.fillStyle ('rgb(300,300,100)');
ctx.lineWidth:=5;
ctx.strokeStyle ('rgb(0,300,0)');
ctx.beginPath();
ctx.moveTo(20,18);ctx.lineTo(40,16);ctx.lineTo(35,26); ctx.lineTo(25,30);
ctx.closePath();
ctx.stroke();
ctx.fill();
ctx.restore();
end;
// dessins d un hexagone à partir de six pavés par rotation
procedure six();
var
i: Integer;
begin
ctx.save();
for i := 0 to 5 do
begin
ctx.rotate(2*PI/6);
pave();
end;
ctx.restore();
end;
// pavage utilisant des translations selon deux vecteurs non colinéaires
// 0,60*Math.sqrt(3) et 60*3/2, 60*Math.sqrt(3)/2
procedure draw();
var
i: Integer;
j: Integer;
begin
ctx.fillStyle ('rgb(800,100,50)');
ctx.fillRect (0, 0, ctx.Width, ctx.Height);
for j := 0 to (ctx.Width+60) div 90 do
begin
ctx.save();
ctx.translate(0,(-j div 2)*60*sqrt(3));
for i := 0 to round(ctx.Height / (60*sqrt(3))) do
begin
six();
ctx.translate(0,60*sqrt(3));
end;
ctx.restore();
ctx.translate(90, sqrt(3)*60/2);
end;
end;
begin
draw();
end;
procedure TForm1.Test15(ctx: TBGRACanvas2D);
const cote = 190;
procedure pave();
begin
ctx.drawImage(abelias,0,0);
end;
procedure refl();
begin
ctx.save();
pave();
ctx.transform(1,0,0,-1, 0, 0);
pave();
ctx.restore();
end;
// dessins d un hexagone à partir de six pavés par rotation
procedure trois();
var
i: Integer;
begin
ctx.save();
for i := 0 to 2 do
begin
ctx.rotate(4*PI/6);
refl();
end;
ctx.restore();
end;
// pavage utilisant des translations selon deux vecteurs non colinéaires
// 0,cote*Math.sqrt(3) et cote*3/2, cote*Math.sqrt(3)/2
procedure draw();
var
i: Integer;
j: Integer;
begin
ctx.fillStyle ('#330055');
ctx.fillRect (0, 0, ctx.width, ctx.height);
ctx.translate(140,140);
for j := 0 to trunc(ctx.Width /(cote*3/2)) do
begin
ctx.save();
ctx.translate(0,-(1/2 + j div 2)*cote*sqrt(3));
for i := 0 to trunc(ctx.Height / (cote*sqrt(3)))+1 do
begin
trois();
ctx.translate(0,cote*sqrt(3));
end;
ctx.restore();
ctx.translate(cote*3/2, sqrt(3)*cote/2);
end;
end;
begin
draw();
end;
procedure TForm1.Test16(ctx: TBGRACanvas2D; grainElapse: integer);
var center: TPointF;
angle,zoom: single;
begin
inc(test16pos, grainElapse);
center := pointf(ctx.width/2,ctx.height/2);
angle := test16pos*2*Pi/300;
zoom := (sin(test16pos*2*Pi/400)+1.1)*min(ctx.width,ctx.height)/300;
with ctx do
begin
translate(center.X,center.Y);
scale(zoom,zoom);
rotate(angle);
translate(-93,-83);
beginPath();
moveTo(89.724698,11.312043);
bezierCurveTo(95.526308,14.494575,100.52322000000001,18.838808,102.75144,24.966412);
bezierCurveTo(114.24578,26.586847,123.07072,43.010127999999995,118.71826,54.504664);
bezierCurveTo(114.77805000000001,64.910473,93.426098,68.10145299999999,89.00143800000001,59.252123);
bezierCurveTo(86.231818,53.712894999999996,90.877898,48.213108999999996,88.853498,42.139906999999994);
bezierCurveTo(87.401408,37.78364299999999,82.208048,33.87411899999999,85.595888,27.098436999999993);
bezierCurveTo(87.071858,24.146481999999992,94.76621800000001,25.279547999999995,94.863658,23.444067999999994);
bezierCurveTo(95.066728,19.618834999999994,92.648878,18.165403999999995,90.221828,15.326465999999995);
closePath();
moveTo(53.024288,20.876975);
bezierCurveTo(50.128958,26.827119000000003,48.561707999999996,33.260252,50.284608,39.548662);
bezierCurveTo(41.840728,47.513997,44.130318,66.017003,54.325338,72.88213300000001);
bezierCurveTo(63.554708000000005,79.09700300000002,82.823918,69.36119300000001,81.320528,59.58223300000001);
bezierCurveTo(80.379498,53.461101000000006,73.409408,51.65791100000001,71.551608,45.53168800000001);
bezierCurveTo(70.219018,41.13739400000001,72.197818,34.94548700000001,65.517188,31.373877000000007);
bezierCurveTo(62.606638000000004,29.817833000000007,56.98220800000001,35.18931200000001,55.841908000000004,33.74771500000001);
bezierCurveTo(53.465478000000004,30.743354000000007,54.598668,28.159881000000006,54.938648,24.44039800000001);
closePath();
moveTo(16.284108,78.650993);
bezierCurveTo(16.615938,85.259863,18.344168,91.651623,22.885208,96.330453);
bezierCurveTo(19.327327999999998,107.37975,30.253377999999998,122.48687000000001,42.495058,123.58667);
bezierCurveTo(53.577238,124.58229,65.765908,106.76307,59.734438,98.920263);
bezierCurveTo(55.959047999999996,94.01106300000001,48.983098,95.791453,44.402058,91.319753);
bezierCurveTo(41.116108,88.112233,39.864737999999996,81.73340300000001,32.289848,81.824883);
bezierCurveTo(28.989708,81.864783,26.651538,89.282293,24.957518,88.569003);
bezierCurveTo(21.427108,87.08246299999999,21.174458,84.272723,19.679208,80.85010299999999);
closePath();
moveTo(152.77652,37.616125);
bezierCurveTo(156.68534,42.955439,159.37334,49.006564,158.79801,55.501293);
bezierCurveTo(168.5256,61.835313,169.5682,80.450283,160.75895,89.021463);
bezierCurveTo(152.78409,96.780823,132.08894,90.63274299999999,131.82654,80.742363);
bezierCurveTo(131.6623,74.551503,138.19976,71.535693,138.93671,65.17653299999999);
bezierCurveTo(139.46532,60.615162999999995,136.41531,54.87470199999999,142.35299,50.170306999999994);
bezierCurveTo(144.93985,48.12074299999999,151.43107,52.404562999999996,152.29636,50.78291599999999);
bezierCurveTo(154.09968999999998,47.403324999999995,152.52446999999998,45.062994999999994,151.52745,41.463536999999995);
closePath();
moveTo(139.65359,109.38478);
bezierCurveTo(179.13505,123.79982000000001,142.51298,146.31478,119.19800000000001,151.55864);
bezierCurveTo(95.883018,156.8025,41.93790800000001,157.82316,75.508908,123.02183);
bezierCurveTo(78.980078,119.42344999999999,79.61785800000001,104.19731999999999,82.074898,99.283253);
bezierCurveTo(86.361158,93.329663,106.23528,86.908083,113.13709,88.929193);
bezierCurveTo(128.23085,93.960443,125.96716,106.89633,139.65359,109.38478);
closePath();
if isPointInPath(mx+0.5,my+0.5) then
fillStyle ('#6faed9')
else
fillStyle ('#3f5e99');
fill();
end;
UpdateIn(10);
end;
procedure TForm1.Test17(ctx: TBGRACanvas2D; grainElapse: integer);
var
grad: IBGRACanvasGradient2D;
angle: single;
begin
inc(test17pos, grainElapse);
angle := test17pos*2*Pi/1000;
ctx.translate(ctx.Width/2,ctx.Height/2);
ctx.scale(min(ctx.Width,ctx.Height)/2-10);
ctx.rotate(angle);
grad := ctx.createLinearGradient(-1,-1,1,1);
grad.addColorStop(0.3, '#ff0000');
grad.addColorStop(0.6, '#0000ff');
ctx.fillStyle(grad);
grad := ctx.createLinearGradient(-1,-1,1,1);
grad.addColorStop(0.3, '#ffffff');
grad.addColorStop(0.6, '#000000');
ctx.strokeStyle(grad);
ctx.lineWidth := 5;
ctx.beginPath;
ctx.moveto(0,0);
ctx.arc(0,0,1,Pi/6,-Pi/6,false);
ctx.fill();
ctx.stroke();
UpdateIn(10);
end;
procedure TForm1.Test18(ctx: TBGRACanvas2D; grainElapse: integer);
var pat: TBGRABitmap;
begin
inc(test18pos, grainElapse);
ctx.translate(ctx.width div 2, ctx.height div 2);
ctx.rotate(test18pos*2*Pi/360);
ctx.scale(3,3);
pat := TBGRABitmap.Create(8,8);
pat.GradientFill(0,0,8,8,BGRABlack,BGRAWhite,gtLinear,PointF(0,0),PointF(8,8),dmSet);
// ctx.surface.CreateBrushTexture(bsDiagCross,BGRA(255,255,0),BGRA(255,0,0)) as TBGRABitmap;
ctx.fillStyle(ctx.createPattern(pat,'repeat-x'));
ctx.fillRect(pat.width,0,ctx.width,pat.height);
ctx.fillStyle(ctx.createPattern(pat,'repeat-y'));
ctx.fillRect(0,0,pat.width,ctx.height);
ctx.rotate(Pi);
ctx.globalAlpha:= 0.25;
ctx.fillStyle(ctx.createPattern(pat,'repeat-x'));
ctx.fillRect(0,0,ctx.width,ctx.height);
ctx.fillStyle(ctx.createPattern(pat,'repeat-y'));
ctx.fillRect(0,0,ctx.width,ctx.height);
pat.free;
UpdateIn(10);
end;
procedure TForm1.Test19(ctx: TBGRACanvas2D; grainElapse: integer);
var i: integer;
tx,ty: single;
begin
inc(test19pos, grainElapse);
ctx.save;
ctx.translate(ctx.width div 2, ctx.height div 2);
ctx.rotate(test19pos*2*Pi/500);
ctx.scale(ctx.height / 2,ctx.height / 2);
ctx.beginPath;
ctx.moveto(1,0);
for i := 1 to 8 do
begin
ctx.rotate(2*Pi/8);
ctx.lineto(1,0);
end;
ctx.restore;
ctx.clip;
tx := ctx.width div 2;
ty := ctx.height div 2;
ctx.fillStyle ('red');
ctx.fillRect(0, 0, tx, ty);
ctx.fillStyle ('blue');
ctx.fillRect(tx, 0, tx, ty);
ctx.globalAlpha := 0.75;
ctx.fillStyle ('yellow');
ctx.fillRect(0, ty, tx, ty);
ctx.fillStyle ('green');
ctx.fillRect(tx, ty, tx, ty);
test18(ctx, grainElapse);
end;
procedure TForm1.Test20(ctx: TBGRACanvas2D; AVectorizedFont: boolean);
var
i: Integer;
grad: IBGRACanvasGradient2D;
begin
UseVectorizedFont(ctx,AVectorizedFont);
ctx.save;
ctx.fontName:= 'default';
ctx.fontEmHeight:= ctx.height/10;
ctx.textBaseline:= 'alphabetic';
ctx.shadowBlur:= 5;
ctx.shadowOffset := PointF(5,5);
ctx.shadowColor(BGRABlack);
ctx.beginPath;
if AVectorizedFont then
ctx.text('Vectorized font',ctx.fontEmHeight*0.2,ctx.fontEmHeight)
else
ctx.text('Raster font',ctx.fontEmHeight*0.2,ctx.fontEmHeight);
ctx.lineWidth := 5;
ctx.lineJoin:= 'round';
ctx.strokeStyle(BGRA(0,192,0));
ctx.fillStyle(clBlack);
ctx.fillOverStroke;
ctx.shadowNone;
grad := ctx.createLinearGradient(0,0,ctx.width,ctx.height);
grad.addColorStop(0.3, '#000080');
grad.addColorStop(0.7, '#00a0a0');
ctx.fillStyle(grad);
ctx.translate(ctx.width/2, ctx.height/2);
for i := 0 to 11 do
begin
ctx.beginPath;
ctx.moveTo(0,0);
ctx.lineTo(ctx.width+ctx.height,0);
ctx.strokeStyle(clRed);
ctx.lineWidth := 1;
ctx.stroke;
ctx.beginPath;
ctx.text('hello',ctx.width/10,0);
ctx.fill;
ctx.rotate(Pi/6);
end;
ctx.restore;
ctx.fontRenderer := nil;
end;
procedure TForm1.Test22(ctx: TBGRACanvas2D);
var layer: TBGRABitmap;
begin
layer := TBGRABitmap.Create(ctx.width,ctx.height, CSSRed);
UseVectorizedFont(layer.Canvas2D,true);
with layer.Canvas2D do
begin
pixelCenteredCoordinates:= ctx.pixelCenteredCoordinates;
antialiasing:= ctx.antialiasing;
fontName:= 'default';
fontStyle := [fsBold];
fontEmHeight:= min(ctx.height/2, ctx.width/4);
textBaseline:= 'middle';
textAlign := 'center';
beginPath;
text('hole', width/2,height/2);
clearPath;
end;
ctx.surface.DrawCheckers(rect(0,0,ctx.width,ctx.height), CSSWhite,CSSSilver);
ctx.surface.PutImage(0,0,layer,dmDrawWithTransparency);
end;
procedure TForm1.Test23(ctx: TBGRACanvas2D; grainElapse: integer);
begin
UseVectorizedFont(ctx,true);
with ctx do
begin
save;
fontName:= 'default';
fontStyle := [fsBold];
fontEmHeight:= min(height/2, width/6);
textBaseline:= 'middle';
textAlign := 'center';
translate(width/2,height/2);
transform(cos(test23pos*Pi/60),sin(test23pos*Pi/60),0,1,0,0);
beginPath;
text('distort', 0,0);
fillStyle(clBlack);
fill;
restore;
end;
inc(test23pos, grainElapse);
UpdateIn(10);
end;
end.