START DOCUMENTATION

Introduction With Blockly

Make your own 3D website With Blockly

Making your own 3D websites and configurators can be challenging, we're trying to make that simple and cost effective with our low-code solutions. In this tutorial Matas Ubarevicius builds visual program by using Blockly editor on our web cad platform and then integrates it to run on third party StackBlitz editor.

We will code a simple visual program that will create a 3D cube. The result of the script will be exactly the same as in the example of the Rete. We will use the very simple website on StackBlitz that we set up in previoust tutorial.

Simple geometry of OCCT cube is used on purpose. Main goal is to learn how you can integrate visual programming into your JavaScript web development workflows.

Final result

You can either visit StackBlitz project page or copy these code snippets into your website to make the result from this tutorial appear on your website.

Blockly script

In the following Blockly script you will find the final code that was exported to JavaScript via "Export to Runner" popover.

Blockly

Simple Cube

Comlete Code

You can also download this static index.html file and open it in your browser to see the result. It contains all of the styling, html and script inside it.

<!DOCTYPE html> <html lang="en"> <head> <title>Home</title> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width" /> <link rel="stylesheet" href="styles.css" /> <script src="https://cdn.jsdelivr.net/gh/bitbybit-dev/bitbybit-assets@0.19.1/runner/bitbybit-runner-babylonjs.js"></script> <script> const runner = window.bitbybitRunner.getRunnerInstance(); setTimeout(async () => { const runnerOptions = { canvasId: 'myCanvas', canvasZoneClass: 'myCanvasZone', enablePhysics: false, enableOCCT: true, enableJSCAD: false, enableKeyEventListeners: false, backgroundColor: '#0000ff', loadFonts: [], }; await runner.run(runnerOptions); changeSize(1); }, 0); let previousMesh; async function changeSize(size) { const res = await runner.executeScript(getInlineScript(), { size }); if (previousMesh) { previousMesh.dispose(); } previousMesh = res.cubeMesh; } window.changeSize = changeSize; function getInlineScript() { return '{\"type\":\"blockly\",\"version\":\"0.19.1\",\"script\":\"async function(e,r,t,n,s){var c,o;(c=(()=>{const r={property:\\"size\\"};e.HS.handleBlock(e.blocklyWorkspace,\\"T}wb0d1H1WU4~rHqU6Z8\\",r);try{return s.getBitbybitRunnerInputs()[r.property]}catch(e){errorHandle(e,\\"T}wb0d1H1WU4~rHqU6Z8\\")}})())||(c=1),o=await(()=>{let t={promise:(()=>{const t={entity:(()=>{const t={shape:(()=>{const t={size:c,center:(()=>{const t={x:0,y:0,z:0};e.HS.handleBlock(e.blocklyWorkspace,\\"..HOv-y|X^q[[1Ktwe5h\\",t);try{return r.point.pointXYZ(t)}catch(e){errorHandle(e,\\"..HOv-y|X^q[[1Ktwe5h\\")}})()};return async function(){return await e.HS.inputAwaiter(t,e.blocklyWorkspace,\\"NjKMI;:*GYJ2).3M?yj6\\"),e.HS.handleBlock(e.blocklyWorkspace,\\"NjKMI;:*GYJ2).3M?yj6\\",t),e.HS.startedAsyncTask(e.blocklyWorkspace,\\"NjKMI;:*GYJ2).3M?yj6\\",\\"#ddddff\\"),r.occt.shapes.solid.createCube(t).then((r=>(e.HS.finishedAsyncTask(e.blocklyWorkspace,\\"NjKMI;:*GYJ2).3M?yj6\\"),r)),(e=>{errorHandle(e.substring?e.substring(0,1e3):e,\\"NjKMI;:*GYJ2).3M?yj6\\")}))}()})(),radius:.4};return async function(){return await e.HS.inputAwaiter(t,e.blocklyWorkspace,\\"6-?FxF/TH`00-Uh|_T12\\"),e.HS.handleBlock(e.blocklyWorkspace,\\"6-?FxF/TH`00-Uh|_T12\\",t),e.HS.startedAsyncTask(e.blocklyWorkspace,\\"6-?FxF/TH`00-Uh|_T12\\",\\"#ddddff\\"),r.occt.fillets.filletEdges(t).then((r=>(e.HS.finishedAsyncTask(e.blocklyWorkspace,\\"6-?FxF/TH`00-Uh|_T12\\"),r)),(e=>{errorHandle(e.substring?e.substring(0,1e3):e,\\"6-?FxF/TH`00-Uh|_T12\\")}))}()})(),options:(()=>{const t={precision:.005,drawFaces:!0,faceColour:\\"#000099\\",drawEdges:!0,edgeColour:\\"#ffffff\\",edgeWidth:1};e.HS.handleBlock(e.blocklyWorkspace,\\"D6NqR%pIp.xzBt?@?tV4\\",t);try{return r.draw.optionsOcctShapeSimple(t)}catch(e){errorHandle(e,\\"D6NqR%pIp.xzBt?@?tV4\\")}})()};return async function(){return await e.HS.inputAwaiter(t,e.blocklyWorkspace,\\"3n^@/8zZXkRWbQFt?[(m\\"),e.HS.handleBlock(e.blocklyWorkspace,\\"3n^@/8zZXkRWbQFt?[(m\\",t),e.HS.startedAsyncTask(e.blocklyWorkspace,\\"3n^@/8zZXkRWbQFt?[(m\\",\\"#ddddff\\"),r.draw.drawAnyAsync(t).then((r=>(e.HS.finishedAsyncTask(e.blocklyWorkspace,\\"3n^@/8zZXkRWbQFt?[(m\\"),r)),(e=>{errorHandle(e.substring?e.substring(0,1e3):e,\\"3n^@/8zZXkRWbQFt?[(m\\")}))}()})()}.promise;return Array.isArray(t)&&(t=Promise.all(t)),t})(),(()=>{const r={property:\\"cubeMesh\\",value:o};e.HS.handleBlock(e.blocklyWorkspace,\\"#sP(;i?@t;x-M0rw:m)B\\",r);try{s.setBitbybitRunnerResultValue(r.property,r.value)}catch(e){errorHandle(e,\\"#sP(;i?@t;x-M0rw:m)B\\")}})()}(BitByBit,bitbybit,bitbybitRunnerResult,bitbybitRunnerInputs,Bit);\"}'; } </script> <style> body { background-color: #1a1c1f; color: white; font-weight: 400; font-family: 'IBM Plex Sans', sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; padding: 20px; } #myCanvas { outline: none; border: 1px solid white; border-radius: 5px; width: 100%; } </style> </head> <body> <div class="myCanvasZone"> <canvas id="myCanvas"></canvas> </div> <label for="size">Size</label> <input id="size" type="number" value="1" min="1" max="10" step="1" onchange="changeSize(event.target.value)" /> </body> </html>