Motion Graphics in a Small Output File

The file size of the output from a canvas project in Smart Mobile Studio is rather large. We generally choose to include the JavaScript output from Smart Mobile Studio within the HTML5 file and, if there is no input from the keyboard, compress and obfuscate the code. You might want to produce a small motion graphics file to act as a splash screen or when you need to include several motion graphics as objects in a single page on a website. The example below is based on Alex Karet's BlendingEllipses and is shorter than the supplied demo Projects\Featured Demos\API\HTML5 DOM\Splash Screen. See also other lightweight applications.

Follow the numbered steps to create a motion graphic in a small HTML5 file using Version 2.2 of Smart Mobile Studio. (You can compile the resultant project file using Version 3 of Smart Mobile Studio, but in that case the HTML file size is much larger at 42 KB).

  1. Create a new canvas project, make Unit1 internal and save the project as BlendingEllipses.
  2. Replace the code of Unit1 with the following.
    unit Unit1;
    
    interface
    
    uses
      SmartCL.System, W3C.HTML5, W3C.DOM, W3C.Canvas2DContext;
    
    type
      TAnimation = class
      private
        FCanvas: JHTMLCanvasElement;
        FContext: JCanvasRenderingContext2D;
        first: Boolean := True;
      public
        constructor Create(ACanvas: JHTMLCanvasElement); virtual;
        procedure PaintCanvas;
        property Canvas: JHTMLCanvasElement read FCanvas;
        property Context: JCanvasRenderingContext2D read FContext;
    end;
    
    var RequestAnimFrame: function(const Meth: procedure): Variant;
    
    implementation
    
    procedure InitAnimationFrameShim;
    begin
      asm
        @RequestAnimFrame = (function(){
          return  window.requestAnimationFrame       ||
                  window.webkitRequestAnimationFrame ||
                  window.mozRequestAnimationFrame    ||
                  window.msRequestAnimationFrame     ||
                  function( callback ){
                    return window.setTimeout(callback, 1);
                  };
        })();
       end;
    end;
    
    function RequestAnimationFrame(const AMethod: procedure): Variant;
    begin
      if not Assigned(RequestAnimFrame) then
        InitAnimationFrameShim;
      Result := RequestAnimFrame(AMethod);
    end;
    
    constructor TAnimation.Create(ACanvas: JHTMLCanvasElement);
    begin
      // Assign the canvas and context
      FCanvas := ACanvas;
      FContext := JCanvasRenderingContext2D(ACanvas.getContext('2d'));
    
      RequestAnimationFrame(PaintCanvas); // Starts the animation
    end;
    
    procedure TAnimation.PaintCanvas;
    // Based on BlendingEllipses, Copyright 2014 Alex Karet (Apache License)
    var
      Draw: array [1..4] of integer;
      color: integer;
    begin
      if first then
        begin
          // Clear the background
          FCanvas.width := Round(Window.innerWidth);
          FCanvas.height := Round(Window.innerHeight);
          Context.FillStyle := 'black';
          Context.FillRect(0, 0, FCanvas.width, FCanvas.height);
          first := False;
          randomize;
        end;
    
      draw[1] := RandomInt(FCanvas.width);
      draw[2] := RandomInt(FCanvas.height);
      draw[3] := RandomInt(50);
      draw[4] := RandomInt(50);
      color := RandomInt(5);
      Context.FillStyle := 'rgba(' + inttostr(randomint(255)) + ',' + inttostr(randomint(255)) +
                                ',' + inttostr(randomint(255)) + ',' + floattostr(random / 2) + ')';
      Context.BeginPath;
      Context.Ellipse(draw[1], draw[2], draw[3], draw[4], 0, 0, 360);
      Context.Fill;
    
      RequestAnimationFrame(PaintCanvas);
    end;
    
    end.
        
    

    You will notice that some of the JavaScript drawing routines are slightly different from their Smart Pascal counterparts.

  3. Click on BlendingEllipses in the Project Manager and copy and paste this code to replace the default application code.
    uses
      W3C.HTML5, W3C.DOM, W3C.Canvas2DContext, W3C.CSS, W3C.CSSOM, Unit1;
    
      // Style the body
      var BodyStyle := JHTMLBodyElement(Document.body).style;
      BodyStyle.setProperty('border', '0');
      BodyStyle.setProperty('margin', '0');
      BodyStyle.setProperty('padding', '0');
      BodyStyle.setProperty('overflow', 'hidden');
    
      // Create canvas element and give it a fullscreen canvas
      var CanvasElement := JHTMLCanvasElement(Document.createElement('canvas'));
      CanvasElement.style.setProperty('display', 'block');
      // Append canvas element to document body
      Document.body.appendChild(CanvasElement);
      // Create the animation
      TAnimation.Create(CanvasElement);    
    
  4. In the Code generation page of Project options, select Code obfuscation and Code packing and in the Linker page change the filename to BlendingEllipses.html.
  5. Compile the project.
  6. Open www\BlendingEllipses.html in a text editor and delete this redundant line:
    <link rel="stylesheet" type="text/css" href="res/app.css"/>
  7. Open www\BlendingEllipses.html in a browser such as Chrome, Microsoft Edge or Opera to confirm that the motion graphic works.
You should produce BlendingEllipses.html with a file size of 8 KB instead of the 97 KB file from the original canvas project.
Programming - a skill for life!

Useful for games, with drawing routines (including transforms and text fonts), images, sprites and WebGL 3D graphics. Now includes Box2D physics and rendering by Pixi.js.