Drawing on a Canvas

[Screenshot] [XML] [Smart Pascal] [Adding Code]

This type of Blockly program is not for beginners. It requires a knowledge of some JavaScript such as that shown here. The generated Smart Pascal from this demonstration of a sine wave should be copied into the lightweight project file. The output HTML file is only 8KB and we show it below. Notice how we create a single string for writing to the document and include within it the creation of a canvas and a JavaScript script to draw onto the canvas.

Demonstration

If the demo does not work in your current browser, try another such as Chrome. If you see no display at school, the security system might have blocked it. You can try instead this direct link to the program running on its own page.

BlocklyCanvas.html

Screenshot of Blocks

The blocks

The blocks

XML Code of Blocks

<xml xmlns="http://www.w3.org/1999/xhtml">
  <block type="variables_set" id=")?4nV7u3TAR#F13@LMDt" x="29" y="67">
    <field name="VAR">strDoc</field>
    <value name="VALUE">
      <block type="text" id="Z-NG%9frz[tA@Mxg`az%">
        <field name="TEXT">&lt;canvas id="canv" width="400" height="400"&gt;&lt;/canvas&gt;</field>
      </block>
    </value>
    <next>
      <block type="text_append" id="rZ?n@63baJ9x4?|z^(b#">
        <field name="VAR">strDoc</field>
        <value name="TEXT">
          <shadow type="text" id="lul1uE(OyheWQa%Ix.oe">
            <field name="TEXT">&lt;script&gt;var c=document.getElementById("canv");var context=c.getContext("2d");</field>
          </shadow>
        </value>
        <next>
          <block type="text_append" id="L#VVD+V.F7}BzP%,Q=l6">
            <field name="VAR">strDoc</field>
            <value name="TEXT">
              <shadow type="text" id="{vF.D-^r@w${r.iuq4@_">
                <field name="TEXT">context.beginPath();context.moveTo(0,0);context.lineTo(0,400);</field>
              </shadow>
            </value>
            <next>
              <block type="text_append" id="gC[^36CfXT]n53q=_]Ao">
                <field name="VAR">strDoc</field>
                <value name="TEXT">
                  <shadow type="text" id="b9w6^o.aFQ/n5GrWd$Xu">
                    <field name="TEXT">context.moveTo(360,200);context.lineTo(0,200);context.stroke();</field>
                  </shadow>
                </value>
                <next>
                  <block type="text_append" id="M{{F)hpj=e%J|`@E_blJ">
                    <field name="VAR">strDoc</field>
                    <value name="TEXT">
                      <shadow type="text" id="e?tE^tHnr89QO7Yql4pQ">
                        <field name="TEXT">context.strokeStyle="red";context.beginPath();</field>
                      </shadow>
                    </value>
                    <next>
                      <block type="controls_for" id="G-nVsX!Qx*Fvw4HCQF`K">
                        <field name="VAR">i</field>
                        <value name="FROM">
                          <shadow type="math_number" id="#wcdDua%/kz3NdlJdg|W">
                            <field name="NUM">1</field>
                          </shadow>
                        </value>
                        <value name="TO">
                          <shadow type="math_number" id="dTFqT[QF,MS?8uPO~8:;">
                            <field name="NUM">360</field>
                          </shadow>
                        </value>
                        <value name="BY">
                          <shadow type="math_number" id="wty!LI_p$,--SC~~F;~X">
                            <field name="NUM">1</field>
                          </shadow>
                        </value>
                        <statement name="DO">
                          <block type="text_append" id="f7pEtSzcG(3_#D+CTpVn">
                            <field name="VAR">strPath</field>
                            <value name="TEXT">
                              <shadow type="text" id="sFY$p5lm8Bexz.t%6+/a">
                                <field name="TEXT"></field>
                              </shadow>
                              <block type="text_join" id=",TORZ~V148`xJ7SD+ZbX">
                                <mutation items="5"></mutation>
                                <value name="ADD0">
                                  <block type="text" id="f##c$?y4^|XDsRNtdqgG">
                                    <field name="TEXT">context.lineTo(</field>
                                  </block>
                                </value>
                                <value name="ADD1">
                                  <block type="variables_get" id="U_L5@BDR,7RX*k/ym]Z1">
                                    <field name="VAR">i</field>
                                  </block>
                                </value>
                                <value name="ADD2">
                                  <block type="text" id="p4#:I0IHtr6x%)nF;X0j">
                                    <field name="TEXT">, 200 - </field>
                                  </block>
                                </value>
                                <value name="ADD3">
                                  <block type="math_arithmetic" id="{:K3,uI2AP,j[Np9/G$k">
                                    <field name="OP">MULTIPLY</field>
                                    <value name="A">
                                      <shadow type="math_number" id="s/MP#bXkx)O+RFKS+X/H">
                                        <field name="NUM">1</field>
                                      </shadow>
                                      <block type="math_trig" id="-VG)DWQyxoKH?K%6Q-mB">
                                        <field name="OP">SIN</field>
                                        <value name="NUM">
                                          <shadow type="math_number" id="}igW$k!lEBl7.$xMX}s)">
                                            <field name="NUM">45</field>
                                          </shadow>
                                          <block type="variables_get" id="=Ni3qLjN!)^$.!R`.C3{">
                                            <field name="VAR">i</field>
                                          </block>
                                        </value>
                                      </block>
                                    </value>
                                    <value name="B">
                                      <shadow type="math_number" id=")}}Oh#Qzn=*%PKsU8FL9">
                                        <field name="NUM">200</field>
                                      </shadow>
                                    </value>
                                  </block>
                                </value>
                                <value name="ADD4">
                                  <block type="text" id="Mq~l;{v(/}B:9Ge*r{?t">
                                    <field name="TEXT">);</field>
                                  </block>
                                </value>
                              </block>
                            </value>
                          </block>
                        </statement>
                        <next>
                          <block type="text_append" id="?q1hQ*Wk:,0GxSH3sj8n">
                            <field name="VAR">strDoc</field>
                            <value name="TEXT">
                              <shadow type="text" id="P8dQcoWX9fR2e(!#!VbQ">
                                <field name="TEXT">context.stroke();&lt;/script&gt;</field>
                              </shadow>
                              <block type="variables_get" id="soZJ^GFhI/jGPdQ4)f}0">
                                <field name="VAR">strPath</field>
                              </block>
                            </value>
                            <next>
                              <block type="text_append" id="Ya%|P!MKY{S_@V;{lRD%">
                                <field name="VAR">strDoc</field>
                                <value name="TEXT">
                                  <shadow type="text" id="`=o3PBWc5+^7N#N4;K|Z">
                                    <field name="TEXT">context.stroke();&lt;/script&gt;</field>
                                  </shadow>
                                </value>
                                <next>
                                  <block type="text_print" id="SgnY},4i^#-IIhJy!$B]">
                                    <value name="TEXT">
                                      <shadow type="text" id=".3tszZsMh=)_p.g,$UyJ">
                                        <field name="TEXT">abc</field>
                                      </shadow>
                                      <block type="variables_get" id="{fCb4N=g@i.:J$chMryr">
                                        <field name="VAR">strDoc</field>
                                      </block>
                                    </value>
                                  </block>
                                </next>
                              </block>
                            </next>
                          </block>
                        </next>
                      </block>
                    </next>
                  </block>
                </next>
              </block>
            </next>
          </block>
        </next>
      </block>
    </next>
  </block>
</xml>

Generated Smart Pascal Code

var strDoc: String;
var strPath: String;


function Str(v: Variant) : string;
begin
  asm
    if (@v === 0) {
      @Result = '0';
    }
    else if (@v === '') {
      @Result = '';
    }
    else if (isNaN(@v)) {
      @Result = @v;
    }
    else {
      @Result = (@v).toString();
    }
  end;
end;



strDoc := '<canvas id="canv" width="400" height="400"></canvas>';
strDoc += '<script>var c=document.getElementById("canv");var context=c.getContext("2d");';
strDoc += 'context.beginPath();context.moveTo(0,0);context.lineTo(0,400);';
strDoc += 'context.moveTo(360,200);context.lineTo(0,200);context.stroke();';
strDoc += 'context.strokeStyle="red";context.beginPath();';

for var i := 1 to 360 do
begin
  strPath += StrJoin([Str('context.lineTo('), Str(i), Str(', 200 - '), Str(Sin(i / 180 * Pi) * 200), Str(');')],'');
end;
strDoc += strPath;
strDoc += 'context.stroke();</script>';
Console.writeln(strDoc);    

Extending the Smart Pascal Code

If you are studying this example you will be an experienced programmer and possibly wondering how you could add some Smart Pascal code to enhance the graphic. You could add W3C.Canvas2DContext to the uses clause and append these lines to the generated code to add text to the graph axes:
var cv := JHTMLCanvasElement(document.getElementById("canv"));
var ctx := JCanvasRenderingContext2D(cv.getContext('2d'));
ctx.FillText('1', 10, 10);
ctx.FillText('360', 360, 210);
ctx.FillText('-1', 10, 400);    

Programming - a skill for life!

XML, images and generated Smart Pascal code of examples including loops, arrays, validation and recursion