Jump to content

TUniCanvas - How to get DataURL ?


andyhill

Recommended Posts

Using a TUniCanvas (cArea), how can I get the toDataURL data (required for image of canvas later)?

    UniSession.AddJS('var context = fMain.cArea._cc_; '+ // CONTEXT WORKS FINE

                                   'var dataURL = fMain.cArea.toDataURL(); '+ // FAILS

                                   'var dataURL = fMain.cArea._cc_.toDataURL(); '+ // FAILS

                                   'var dataURL = fMain.cArea.BitmapCanvas.toDataURL(); '+ // FAILS

                                   'var dataURL = context.toDataURL(); '+ // FAILS 

Please advise how - thanks in advance

Link to comment
Share on other sites

Great, I am trying to save and retrieve canvas with the following code which executes but fails to go back to (paint) the original canvas contents after drawing the circle ?

    UniSession.AddJS('var context = fMain.cArea._cc_; '+

                                   ' // Save Canvas to img '+ 
                                   'var dataURL = fMain.cArea._c_.toDataURL(); '+
                                   'var img = new Image; img.onload = () => '+
                                   '{ '+
                                   '  context.drawImage(img, 0, 0, '+IntToStr(cArea.width)+', '+IntToStr(cArea.height)+'); '+
                                   '  img.src = dataURL; '+
                                   '}; '+

                                   ' // Draw Circle On Top Of Canvas contents '+ 
                                   '{ '+
                                   '  context.beginPath(); '+
                                   '  context.arc(150, 150, 105, 0, Math.PI * 2, false); '+
                                   '  context.stroke(); '+

                                   ' // Retrieve Original Canvas after 2 seconds '+ 
                                   '  setTimeout(() => { context.drawImage(img, 0, 0, '+IntToStr(cArea.width)+', '+IntToStr(cArea.height)+'); }, 2000); '+ 
                                  '}; ');

Please advise ?

Logic would dictate img -> context but not possible
img.drawImage(context, 0, 0, '+IntToStr(cArea.width)+', '+IntToStr(cArea.height)) ???

Link to comment
Share on other sites

And use such comments /* ... */, instead of //

procedure TMainForm.UniButton15Click(Sender: TObject);
begin
  UniSession.AddJS('var context = '+ UniCanvas1.JSName +'._cc_; '+

     ' /*Save Canvas to img */'+
     'var dataURL = '+ UniCanvas1.JSName +'._c_.toDataURL(); '+
     'var img = new Image(); img.onload = () => '+
     '{ '+
     '  context.drawImage(img, 0, 0, '+IntToStr(UniCanvas1.width)+', '+IntToStr(UniCanvas1.height)+'); '+
     '  img.src = dataURL; '+
     '}; '+

     //' // Draw Circle On Top Of Canvas contents '+
     '  context.beginPath(); '+
     '  context.arc(150, 150, 105, 0, Math.PI * 2, false); '+
     '  context.stroke(); '+

     //' // Retrieve Original Canvas after 2 seconds '+
     '  setTimeout(() => { context.drawImage(img, 0, 0, '+IntToStr(UniCanvas1.width)+', '+IntToStr(UniCanvas1.height)+'); }, 2000); '
  );
end;

 

Link to comment
Share on other sites

2 hours ago, andyhill said:

I appreciate the pointers HOWEVER same issue, canvas does not return to the state before the circle ???

Hello,

The canvas does not have a method that stores state. But you can use the techniques shown here.

 

Link to comment
Share on other sites

Sherzod, this is what I understood but obviously have failed in my understanding to implement, please help (my canvas object is cArea) - thanks:-

FORM CREATE

...

  s:= 'eventOnDraw=function eventOnDraw(ctx, eventName) '+
      '{ '+

      '  var fireEvent = function() '+
      '  { '+
      '    var evt = document.createEvent("Events"); '+
      '    evt.initEvent(''_completed_'', true, true); '+ // was eventName
      '    ctx.canvas.dispatchEvent(evt); '+
      '  } '+

      '  var stroke = ctx.stroke; '+
      '  ctx.stroke = function() '+
      '  { '+
      '    stroke.call(this); '+
      '    fireEvent(); '+
      '  }; '+

      '  var fillRect = ctx.fillRect; '+
      '  ctx.fillRect = function(x, y, w, h) '+
      '  { '+
      '    fillRect.call(this, x, y, w, h); '+
      '    fireEvent(); '+
      '  }; '+

      '  var fill = ctx.fill; '+
      '  ctx.fill = function() '+
      '  { '+
      '    fill.call(this); '+
      '    fireEvent(); '+
      '  }; '+

      '} ';
  cArea.ClientEvents.ExtEvents.Add(s); // here ???

  UniSession.AddJS(cArea.JSName +'.addEventListener(''_completed_'', completedHandler, false); '); // ???

...

CANVAS AJAXEVENT
  //////////////////////////////////////////////////////////////////////////////
  if EventName = 'completedHandler' then begin
    ShowMessage('Done');
  end;

...

BUTTON CLICK
    UniSession.AddJS('var context = ' + cArea.JSName + '._cc_; '+
                                    '{ '+
                                   '  context.beginPath(); '+
                                   '  context.arc(150, 150, 105, 0, Math.PI * 2, false); '+
                                   '  eventOnDraw(context, ''stroke''); '+ // ??? also how do I do a fill with params x, y etc.
                                   '} ');

 

Link to comment
Share on other sites

7 minutes ago, andyhill said:

Asking for your help on this Sherzod - please

Hello,

Sorry, this takes some extra time.
Please specify again what you want.

1. Save - please specify in more detail.
2. An event when changing the canvas?
3. Restore states - please specify in more detail.

Link to comment
Share on other sites

I want to preserve the current canvas with all of it's images and lines in JavaScript, then add new lines etc. in JavaScript, now much later (separate action) revert back to the preserved canvas in JavaScript (view it as a type of UnDo).

Delphi, Server-Side and ajax-requests are to time intensive, we need to do all of this at the JavaScript/Local Browser level.

My code some post back clearly showed:-

Make a Copy of the current canvas

Add More Drawings to the canvas

Retrieve Copy at a later date and restore the canvas to it's previous condition

 

Link to comment
Share on other sites

14 minutes ago, andyhill said:

I want to preserve the current canvas with all of it's images and lines in JavaScript, then add new lines etc. in JavaScript, now much later (separate action) revert back to the preserved canvas in JavaScript (view it as a type of UnDo).

Delphi, Server-Side and ajax-requests are to time intensive, we need to do all of this at the JavaScript/Local Browser level.

My code some post back clearly showed:-

Make a Copy of the current canvas

Add More Drawings to the canvas

Retrieve Copy at a later date and restore the canvas to it's previous condition

You'd better use this library:

http://fabricjs.com/

Link to comment
Share on other sites

Here is a minimal example of fabric, is this how you would implement ?

  //(function() {
  //var canvas = this.__canvas = new fabric.StaticCanvas('c');

  UniSession.AddJS('var canvas = ' + cArea.JSName + '._c_ = new fabric.StaticCanvas('c'); // ???

  canvas.add(
    new fabric.Rect({ top: 100, left: 100, width: 50, height: 50, fill: '#f55' }),
    new fabric.Circle({ top: 140, left: 230, radius: 75, fill: 'green' }),
    new fabric.Triangle({ top: 300, left: 210, width: 100, height: 100, fill: 'blue' })
  );

  fabric.Image.fromURL('../lib/pug.jpg', function(img) {
    canvas.add(img.set({ left: 400, top: 350, angle: 30 }).scale(0.25));
  });

  function animate() {
    canvas.item(0).animate('top', canvas.item(0).get('top') === 500 ? '100' : '500', {
      duration: 1000,
      onChange: canvas.renderAll.bind(canvas),
      onComplete: animate
    });
  }
  animate();
//})();
);


 

Link to comment
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.

×
×
  • Create New...