Recent

Author Topic: Ring Type Animation (cannot get correct animation happening)  (Read 863 times)

Boleeman

  • Hero Member
  • *****
  • Posts: 924
I tried recreating an animated Hue Ring made in JavaScript.
The animation sort of looks like a ring being spun on a flat plane surface (where it sort of rotates and rolls endlessly).

I think the curve is Lissajous? The JavaScript uses an arc, but I used an ellipse. Not sure if that is the problem?

Here is the JavaScript where x = w / 2 + w / 3 * Math.sin( t ) and y=h / 2 + h / 3 * Math.sin( 2 * t )

I also tried doing a phase shift to try to achieve the effect, but with no luck.

Code: Pascal  [Select][+][-]
  1. var w = c.width = window.innerWidth,
  2.                 h = c.height = window.innerHeight,
  3.                 ctx = c.getContext( '2d' ),
  4.                
  5.                 fx = function( t ){
  6.                        
  7.                         return w / 2 + w / 3 * Math.sin( t )
  8.                 },
  9.                 fy = function( t ){
  10.                        
  11.                         return h / 2 + h / 3 * Math.sin( 2 * t );
  12.                 },
  13.                
  14.                 count = 100,
  15.                 tick = 0;
  16.  
  17. function anim(){
  18.        
  19.         window.requestAnimationFrame( anim );
  20.        
  21.         tick += .02;
  22.        
  23.         ctx.fillStyle = 'rgba(0,0,0,.1)';
  24.         ctx.fillRect( 0, 0, w, h );
  25.        
  26.         for( var i = 0; i < count; ++i ){
  27.                
  28.                 var rapport = i / count;
  29.                 ctx.fillStyle = 'hsl(hue,80%,50%)'.replace( 'hue', rapport * 360 );
  30.                 ctx.beginPath();
  31.                 ctx.arc( fx( tick + rapport * Math.PI * 2 ), fy( tick + rapport * Math.PI ), 2, 0, Math.PI * 2 );
  32.                 ctx.fill();
  33.         }
  34. }
  35. ctx.fillStyle = '#111'
  36. ctx.fillRect( 0, 0, w, h );
  37. anim();
  38.  
  39. window.addEventListener( 'resize', function(){
  40.         w = c.width = window.innerWidth;
  41.         h = c.height = window.innerHeight;
  42.         ctx.fillStyle = '#111'
  43.         ctx.fillRect( 0, 0, w, h );
  44. })

and here is my 1st try at a Lazarus conversion ( the zipped version is a bit different with a phase shift):

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls,
  9.   BGRABitmap, BGRABitmapTypes;
  10.  
  11. type
  12.  
  13.   { TForm1 }
  14.  
  15.   TForm1 = class(TForm)
  16.     PaintBox1: TPaintBox;
  17.     Panel1: TPanel;
  18.     Timer1: TTimer;
  19.     procedure FormCreate(Sender: TObject);
  20.     procedure FormResize(Sender: TObject);
  21.     procedure Timer1Timer(Sender: TObject);
  22.   private
  23.     bmp: TBGRABitmap;
  24.     tick: Double;
  25.     count: Integer;
  26.     procedure DrawFrame;
  27.   public
  28.  
  29.   end;
  30.  
  31. var
  32.   Form1: TForm1;
  33.  
  34. implementation
  35.  
  36. {$R *.lfm}
  37.  
  38. { Helper function to convert HSL to TColor }
  39. function HSLToColor(H: integer; S, L: Single): TBGRAPixel;
  40. var
  41.   hsla: THSLAPixel;
  42. begin
  43.   hsla.hue := Round((H mod 360) / 360 * 65535);
  44.   hsla.saturation := Round(S * 65535);
  45.   hsla.lightness := Round(L * 65535);
  46.   hsla.alpha := 65535;
  47.   Result := HSLAToBGRA(hsla);
  48. end;
  49.  
  50. { TForm1 }
  51.  
  52. procedure TForm1.FormCreate(Sender: TObject);
  53. begin
  54.   bmp := TBGRABitmap.Create(PaintBox1.Width, PaintBox1.Height, BGRABlack);
  55.   tick := 0;
  56.   count := 100;
  57.   Timer1.Enabled := True;
  58. end;
  59.  
  60. procedure TForm1.FormResize(Sender: TObject);
  61. begin
  62.   bmp.SetSize(PaintBox1.Width, PaintBox1.Height);
  63.   bmp.Fill(BGRABlack);
  64. end;
  65.  
  66. procedure TForm1.Timer1Timer(Sender: TObject);
  67. begin
  68.   tick += 0.02;
  69.   DrawFrame;
  70. end;
  71.  
  72. procedure TForm1.DrawFrame;
  73. var
  74.   i: Integer;
  75.   rapport, t: Double;
  76.   cx, cy, x, y: Single;
  77.   hueColor: TBGRAPixel;
  78. begin
  79.   bmp.FillRect(0, 0, bmp.Width, bmp.Height, BGRA(0, 0, 0, 25), dmDrawWithTransparency);
  80.  
  81.   cx := bmp.Width / 2;
  82.   cy := bmp.Height / 2;
  83.  
  84.   for i := 0 to count - 1 do
  85.   begin
  86.     rapport := i / count;
  87.  
  88.     x := cx + (bmp.Width / 3) * sin(tick + rapport * Pi * 2);
  89.     y := cy + (bmp.Height / 3) * sin(tick + rapport * Pi );
  90.  
  91.     hueColor := HSLToColor(Round(rapport * 360), 0.8, 0.5);
  92.     bmp.FillEllipseAntialias(x, y, 2, 2, hueColor);
  93.   end;
  94.  
  95.   bmp.Draw(PaintBox1.Canvas, 0, 0, True);
  96. end;
  97.  
  98.  
  99. end.
  100.  
« Last Edit: May 22, 2025, 02:16:36 pm by Boleeman »

Dzandaa

  • Sr. Member
  • ****
  • Posts: 452
  • From C# to Lazarus
Re: Ring Type Animation (cannot get correct animation happening)
« Reply #1 on: May 23, 2025, 04:19:05 pm »
Hi Eddie,

Some minor changes for the fun :)

B->
Regards,
Dzandaa

Boleeman

  • Hero Member
  • *****
  • Posts: 924
Re: Ring Type Animation (cannot get correct animation happening)
« Reply #2 on: May 24, 2025, 07:45:50 am »
Thanks DZandaa.

Attached is the original JavaScript (just to see what the animation looks like).
I think that using arc may make it animate that way (instead of using ellipse).

 

TinyPortal © 2005-2018