Jump to content
Sign in to follow this  
warleyalex

SmartMS intro with ThreeJS and p5.js

Recommended Posts

Hi there. Andre has been playing with ThreeJS and created a nice wrapper unit (using an experimental internal typescript to pascal converter) ;) See at: https://github.com/andremussche/AndrewsDelphiStuff/tree/master/Smart/ThreeJS

 

Unfortunately, my graphics card is in the blacklist - I cannot play with WebGL.

 

This example intentionally deviates as little as possible of Andre's sample. So, I would like to bind Three JS animation to some SmartMS specific component. Canvas animation would be displayed inside to an already existing element, which is necessary in some cases.

 

I was having in mind something like:  you add a button click event that allow me to easily manipulate animation location with CSS. If you are curious to see how I created this sample, see at:

 

You can view the source of the sample at: https://www.dropbox.com/s/jg9qzwin34ibnpt/MySmartMS_ThreeJS.rar

Share this post


Link to post
Share on other sites

Demo1 and Demo2

P5.js There are different ways of doing this

- mapping all p5.js functions and variables to pascal so they can be accessed from Smart by name
- take a bit of a shortcut

The latter approach looks like this :

- let P5 construct its canvas. This requires a minimum sketch.js file with its setup and draw functions. (The draw function can be empty. See project zipfile demo1)
- copy the constructed canvas to a Smart component (W3Panel);
- use p5 functions in code

Demo1 uses this approach, Demo2 is a copy of one of the p5 examples

Both projects in this zipfile

 

 

 

Share this post


Link to post
Share on other sites

Edited

The other approach is to gain access to the internal j5 functions in a more readable way, as in 

function createElement(a,b:string): Variant; external 'createElement';
function ellipse(a,b,c,d:integer): Variant; external 'ellipse';

implementation

{ TForm1 }

procedure TForm1.W3Button1Click(Sender: TObject);
begin
  var txt := createElement('p', 'move your mouse over the canvas');
  txt.position(50, 70);

  W3DivHtmlElement1.onMouseMove := procedure(Sender: TObject; Shift: TShiftState; X: Integer; Y: Integer)
  begin
    ellipse(X,Y,80,80);
end;

which eliminates the asm blocks

(code relates to Demo1 project)

 

and to top it all off :
here is a version which does away with all of the above and previous, does not need a separate sketch.js file, custom template etc. and does everything in code

unit Form1;

interface

uses 
  System.Types, System.Types.Convert, System.Objects, System.Time,
  System.IOUtils, System.Device.Storage,
  SmartCL.System, SmartCL.Time, SmartCL.Graphics, SmartCL.Components,
  SmartCL.FileUtils, SmartCL.Device.Storage, SmartCL.Forms, SmartCL.Fonts,
  SmartCL.Theme, SmartCL.Borders, SmartCL.Application, SmartCL.Controls.Button,
  SmartCL.Controls.Elements;

type
  TForm1 = class(TW3Form)
    procedure W3Button1Click(Sender: TObject);
  private
    {$I 'Form1:intf'}
  protected
    procedure InitializeForm; override;
    procedure InitializeObject; override;
    procedure Resize; override;
  end;

var myp5 : variant;

implementation

{ TForm1 }

procedure TForm1.W3Button1Click(Sender: TObject);
begin
//
  var Script := browserapi.document.createElement('script');
  Script.src := 'https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.0.0/p5.min.js';
  browserapi.document.head.appendChild(Script);
  Script.onload := procedure
  begin
    writeln('p5.js loaded');

    var s      : variant := new(JObject);
    var sketch : variant := new(JObject);
    
    //set up the sketch object and create its canvas
    s := procedure(sketch:variant)
    begin
      sketch.setup := procedure()
      begin
        sketch.createCanvas(W3DivHtmlElement1.width, W3DivHtmlElement1.height);
      end;
      sketch.draw := procedure()
      begin
        //any initial draw activities
        //sketch.rect(10,10,50,50);
      end;
    end;

    // create the p5 instance and link it to the panel
    var x := W3DivHtmlElement1.handle.id;
    asm @myp5 = new p5(@s, @x); end;

    //use the p5 instance
    W3DivHtmlElement1.onMouseMove := procedure(Sender: TObject; Shift: TShiftState; X: Integer; Y: Integer)
    begin
      myp5.fill('pink');
      myp5.ellipse(X,Y,80,80);
    end;

    myp5.rect(100,100,50,50);
  end;
end;

procedure TForm1.InitializeForm;
begin
  inherited;
  // this is a good place to initialize components

  W3DivHtmlElement1.handle.style.border := '1px solid red';

end;

procedure TForm1.InitializeObject;
begin
  inherited;
  {$I 'Form1:impl'}

end;
 
procedure TForm1.Resize;
begin
  inherited;
end;
 
initialization
  Forms.RegisterForm({$I %FILE%}, TForm1);
end.

this way you could even have multiple canvasses on the same form

Edited by lynkfs

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...