node.html 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <title>Equation Editor</title>
  6. </head>
  7. <body style="font-size:30px; font-family: Arial;">
  8. <!-- Page -->
  9. <div style="position:absolute; width:100%; height:100%; top:0px; left:0px; overflow: hidden;">
  10. <!-- Canvas -->
  11. <canvas id="canvas" style="position:absolute; width:100%; height:100%; top:0px; left:0px;"></canvas>
  12. <!-- Buttons -->
  13. <div style="position:absolute; width:60px; height:50px; top:0px; left:10px; text-align:center; z-index:10; cursor: pointer;" onclick="window.addOperatorBlock('+');">+</div>
  14. <div style="position:absolute; width:60px; height:50px; top:50px; left:10px; text-align:center; z-index:10; cursor: pointer;" onclick="window.addOperatorBlock('-');">-</div>
  15. <div style="position:absolute; width:60px; height:50px; top:100px; left:10px; text-align:center; z-index:10; cursor: pointer;" onclick="window.addOperatorBlock('*');">x</div>
  16. <div style="position:absolute; width:60px; height:50px; top:150px; left:10px; text-align:center; z-index:10; cursor: pointer;" onclick="window.addOperatorBlock('/');">/</div>
  17. <div style="position:absolute; width:60px; height:50px; top:200px; left:10px; text-align:center; z-index:10; cursor: pointer;" onclick="window.addInputBlock();">Num</div>
  18. <div style="position:absolute; width:60px; height:50px; bottom:50px; left:10px; text-align:center; z-index:10; cursor: pointer;" onclick="window.loadFile();">Load</div>
  19. <div style="position:absolute; width:60px; height:50px; bottom:0px; left:10px; text-align:center; z-index:10; cursor: pointer;" onclick="window.saveFile();">Save</div>
  20. </div>
  21. <!-- Code -->
  22. <script type="text/javascript" src="../build/escher.js"></script>
  23. <script type="text/javascript">
  24. // Canvas
  25. var canvas = document.getElementById("canvas");
  26. canvas.width = window.innerWidth;
  27. canvas.height = window.innerHeight;
  28. // Prevent context menu events
  29. document.body.oncontextmenu = function(event)
  30. {
  31. event.preventDefault();
  32. return false;
  33. };
  34. // Resize canvas on window resize
  35. window.onresize = function()
  36. {
  37. canvas.width = window.innerWidth;
  38. canvas.height = window.innerHeight;
  39. };
  40. window.addOperatorBlock = function(symbol)
  41. {
  42. graph.addNode(new OperationNode(symbol));
  43. };
  44. window.addInputBlock = function(symbol)
  45. {
  46. graph.addNode(new NumberInputNode());
  47. };
  48. window.loadFile = function()
  49. {
  50. Escher.FileUtils.select(function(files)
  51. {
  52. if(files.length > 0)
  53. {
  54. var reader = new FileReader();
  55. reader.onload = function()
  56. {
  57. var text = reader.result;
  58. var data = JSON.parse(text);
  59. graph = Escher.Object2D.parse(data);
  60. };
  61. reader.readAsText(files[0]);
  62. }
  63. }, ".json");
  64. };
  65. window.saveFile = function()
  66. {
  67. var data = graph.serialize(true);
  68. var text = JSON.stringify(data, null, "\t");
  69. Escher.FileUtils.write("object.json", text);
  70. };
  71. class OperationNode extends Escher.Node
  72. {
  73. constructor(operation)
  74. {
  75. super();
  76. this.type = "OperationNode";
  77. this.operation = operation;
  78. this.box.set(new Escher.Vector2(-50, -40), new Escher.Vector2(50, 40));
  79. this.text = new Escher.Text();
  80. this.text.serializable = false;
  81. this.text.text = operation;
  82. this.text.font = "25px Arial";
  83. this.text.layer = 2;
  84. this.add(this.text);
  85. }
  86. registerSockets()
  87. {
  88. this.a = this.addInput("string", "a");
  89. this.b = this.addInput("string", "b");
  90. this.r = this.addOutput("string", "r");
  91. this.r.getValue = () =>
  92. {
  93. return "(" + this.a.getValue() + this.operation + this.b.getValue() + ")";
  94. };
  95. }
  96. serialize(recursive)
  97. {
  98. var data = super.serialize(recursive);
  99. data.operation = this.operation;
  100. return data;
  101. }
  102. parse(data, root)
  103. {
  104. super.parse(data, root);
  105. this.operation = data.operation;
  106. this.text.text = data.operation;
  107. }
  108. }
  109. class NumberInputNode extends Escher.Node
  110. {
  111. constructor()
  112. {
  113. super();
  114. this.type = "NumberInputNode";
  115. this.box.set(new Escher.Vector2(-50, -30), new Escher.Vector2(50, 30));
  116. this.div = new Escher.DOM("input");
  117. this.div.serializable = false;
  118. this.div.size.set(70, 20);
  119. this.div.origin.set(35, 10);
  120. this.div.element.style.pointerEvents = "auto";
  121. this.div.element.type = "number";
  122. this.div.element.style.fontFamily = "Arial";
  123. this.div.element.style.textAlign = "center";
  124. this.div.element.style.border = "1px";
  125. this.div.element.style.borderStyle = "solid";
  126. this.div.element.style.borderColor = "#000000";
  127. this.div.element.style.padding = "0px";
  128. this.add(this.div);
  129. }
  130. registerSockets()
  131. {
  132. this.out = this.addOutput("string", "v");
  133. this.out.getValue = () =>
  134. {
  135. return this.div.element.value;
  136. };
  137. }
  138. serialize(recursive)
  139. {
  140. var data = super.serialize(recursive);
  141. data.value = this.div.element.value;
  142. return data;
  143. }
  144. parse(data, root)
  145. {
  146. super.parse(data, root);
  147. this.div.element.value = data.value;
  148. }
  149. }
  150. class ResultNode extends Escher.Node
  151. {
  152. constructor()
  153. {
  154. super();
  155. this.type = "ResultNode";
  156. this.box.set(new Escher.Vector2(-100, -20), new Escher.Vector2(100, 20));
  157. this.text = new Escher.Text();
  158. this.text.serializable = false;
  159. this.text.text = "";
  160. this.text.font = "12px Arial";
  161. this.text.layer = 2;
  162. this.add(this.text);
  163. }
  164. registerSockets()
  165. {
  166. this.r = this.addInput("string", "r");
  167. }
  168. onUpdate()
  169. {
  170. super.onUpdate();
  171. try
  172. {
  173. var value = this.r.getValue();
  174. this.text.text = value + " = " + eval(value);
  175. }
  176. catch(e)
  177. {
  178. this.text.text = "NaN";
  179. }
  180. }
  181. }
  182. Escher.Object2D.register(OperationNode, "OperationNode");
  183. Escher.Object2D.register(NumberInputNode, "NumberInputNode");
  184. Escher.Object2D.register(ResultNode, "ResultNode");
  185. var graph = new Escher.NodeGraph();
  186. var result = new ResultNode();
  187. graph.addNode(result);
  188. // Viewport
  189. var viewport = new Escher.Viewport(canvas);
  190. // Renderer
  191. var renderer = new Escher.Renderer(canvas);
  192. // Render loop
  193. var controls = new Escher.ViewportControls(viewport);
  194. function loop()
  195. {
  196. controls.update(renderer.pointer);
  197. renderer.update(graph, viewport);
  198. requestAnimationFrame(loop);
  199. }
  200. loop();
  201. </script>
  202. </body>
  203. </html>