turtlegraphics.pas 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454
  1. unit turtlegraphics;
  2. {$mode ObjFPC}
  3. interface
  4. uses
  5. Classes, SysUtils;
  6. { Commands & constants taken from the turtle graphics at
  7. https://www.turtle.ox.ac.uk/documentation/reference
  8. }
  9. const
  10. green = $228B22;
  11. red = $FF0000;
  12. blue = $0000FF;
  13. yellow = $FFFF00;
  14. violet = $8A2BE2;
  15. lime = $00FF00;
  16. orange = $FFAA00;
  17. skyblue = $00B0FF;
  18. brown = $964B00;
  19. pink = $EE1289;
  20. darkgreen = $006400;
  21. darkred = $B22222;
  22. darkblue = $000080;
  23. ochre = $C0B030;
  24. indigo = $4B0082;
  25. olive = $808000;
  26. orangered = $FF6600;
  27. teal = $008080;
  28. darkbrown = $5C4033;
  29. magenta = $FF00FF;
  30. lightgreen = $98FB98;
  31. lightred = $CD5C5C;
  32. lightblue = $99BBFF;
  33. cream = $FFFFBB;
  34. lilac = $B093FF;
  35. yellowgreen = $AACC33;
  36. peach = $FFCCB0;
  37. cyan = $00FFFF;
  38. lightbrown = $B08050;
  39. lightpink = $FFB6C0;
  40. seagreen = $3CB371;
  41. maroon = $800000;
  42. royal = $4169E1;
  43. gold = $FFC800;
  44. purple = $800080;
  45. emerald = $00C957;
  46. salmon = $FA8072;
  47. turquoise = $00BEC1;
  48. coffee = $926F3F;
  49. rose = $FF88AA;
  50. greengrey = $709070;
  51. redgrey = $B08080;
  52. bluegrey = $8080A0;
  53. yellowgrey = $909070;
  54. darkgrey = $404040;
  55. midgrey = $808080;
  56. lightgrey = $A0A0A0;
  57. silver = $C0C0C0;
  58. white = $FFFFFF;
  59. black = $000000;
  60. // Relative movement
  61. procedure forward(n : integer);
  62. procedure back(n : integer);
  63. procedure left(n : integer);
  64. procedure right(n : integer);
  65. procedure drawxy(x,y : integer);
  66. procedure movexy(x,y : integer);
  67. // Absolute movement
  68. procedure home;
  69. procedure setx(x : integer);
  70. procedure sety(y : integer);
  71. procedure setxy(x,y : integer);
  72. procedure direction(n : integer);
  73. procedure angles(degrees : integer);
  74. procedure turnxy(x,y : integer);
  75. // Other
  76. procedure point;
  77. procedure setpointsize(aSize : Integer);
  78. procedure penup;
  79. procedure pendown;
  80. procedure colour(aColor : Integer);
  81. procedure color(aColor : Integer);
  82. procedure randcol(n: integer);
  83. function rgb(i : integer) : Integer;
  84. procedure thickness(i : integer);
  85. procedure box(x,y,color : integer; border : Boolean);
  86. procedure circle(radius : integer);
  87. procedure blot(radius : integer);
  88. procedure ellipse(xRadius,yRadius : integer);
  89. procedure ellblot(xRadius,yRadius : integer);
  90. procedure blank(acolor : integer);
  91. // Not part of the API, but needed to set up stuff.
  92. // Maybe it should be moved to another unit ?
  93. procedure _initcanvas(aID : string);
  94. // Variables that can be set directly.
  95. var
  96. turtc, turtd, turtx, turty, turtt : integer;
  97. implementation
  98. uses web;
  99. const
  100. colours : array[1..50] of integer = (
  101. green,
  102. red,
  103. blue,
  104. yellow,
  105. violet,
  106. lime,
  107. orange,
  108. skyblue,
  109. brown,
  110. pink,
  111. darkgreen,
  112. darkred,
  113. darkblue,
  114. ochre,
  115. indigo,
  116. olive,
  117. orangered,
  118. teal,
  119. darkbrown,
  120. magenta,
  121. lightgreen,
  122. lightred,
  123. lightblue,
  124. cream,
  125. lilac,
  126. yellowgreen,
  127. peach,
  128. cyan,
  129. lightbrown,
  130. lightpink,
  131. seagreen,
  132. maroon,
  133. royal,
  134. gold,
  135. purple,
  136. emerald,
  137. salmon,
  138. turquoise,
  139. coffee,
  140. rose,
  141. greengrey,
  142. redgrey,
  143. bluegrey,
  144. yellowgrey,
  145. darkgrey,
  146. midgrey,
  147. lightgrey,
  148. silver,
  149. white,
  150. black
  151. );
  152. var
  153. turtAngles : integer = 360;
  154. drawing : boolean;
  155. pointSize : Integer = 4;
  156. canvas : TJSCanvasRenderingContext2D;
  157. Function ToRad(aDirection : Integer) : Double;
  158. begin
  159. Result:=(aDirection/turtAngles)*2*Pi;
  160. end;
  161. Function ToDegrees(aAngle : Double) : Integer;
  162. begin
  163. Result:=Round((aAngle*turtAngles)/(2*Pi));
  164. end;
  165. procedure forward(n : integer);
  166. var
  167. deltaX,deltaY : integer;
  168. begin
  169. DeltaX:=round(n * cos(ToRad(turtd)));
  170. DeltaY:=round(n * sin(ToRad(turtd)));
  171. DrawXY(DeltaX,DeltaY)
  172. end;
  173. procedure back(n : integer);
  174. var
  175. deltaX,deltaY : integer;
  176. begin
  177. DeltaX:=-round(n * cos(ToRad(turtd)));
  178. DeltaY:=-round(n * sin(ToRad(turtd)));
  179. DrawXY(DeltaX,DeltaY)
  180. end;
  181. procedure left(n : integer);
  182. begin
  183. TurtD:=TurtD-N;
  184. end;
  185. procedure right(n : integer);
  186. begin
  187. TurtD:=TurtD+N;
  188. end;
  189. procedure applycolor(acolor: integer);
  190. var
  191. r,g,b : Integer;
  192. col : string;
  193. begin
  194. col:=format('%.6x',[aColor]);
  195. B:=aColor and $FF;
  196. G:=(aColor shr 8) and $FF;
  197. R:=(aColor shr 16) and $FF;
  198. col:=Format('rgb(%d,%d,%d)',[R,G,B]);
  199. canvas.strokestyle:=col;
  200. canvas.fillstyle:=col;
  201. end;
  202. procedure setcanvasparams;
  203. begin
  204. Canvas.lineWidth:=turtt;
  205. applycolor(turtc);
  206. end;
  207. procedure drawxy(x,y : integer);
  208. begin
  209. if Drawing then
  210. begin
  211. Canvas.BeginPath;
  212. setcanvasparams;
  213. Canvas.MoveTo(TurtX,TurtY);
  214. Canvas.Lineto(TurtX+X,TurtY+Y);
  215. Canvas.Stroke;
  216. end;
  217. MoveXY(X,Y);
  218. end;
  219. procedure movexy(x,y : integer);
  220. begin
  221. TurtX:=TurtX+X;
  222. TurtY:=TurtY+Y;
  223. end;
  224. // Absolute movement
  225. procedure home;
  226. begin
  227. TurtX:=0;
  228. TurtY:=0;
  229. TurtD:=0;
  230. end;
  231. procedure setx(x : integer);
  232. begin
  233. TurtX:=X;
  234. end;
  235. procedure sety(y : integer);
  236. begin
  237. TurtY:=Y;
  238. end;
  239. procedure setxy(x,y : integer);
  240. begin
  241. TurtX:=X;
  242. TurtY:=Y;
  243. end;
  244. procedure direction(n : integer);
  245. begin
  246. TurtD:=N;
  247. end;
  248. procedure angles(degrees : integer);
  249. begin
  250. TurtAngles:=Degrees;
  251. end;
  252. procedure turnxy(x,y : integer);
  253. begin
  254. TurtD:= ToDegrees(ArcTan2(x,y));
  255. end;
  256. procedure point;
  257. begin
  258. blot(pointsize);
  259. end;
  260. procedure setpointsize(aSize: Integer);
  261. begin
  262. pointSize:=aSize;
  263. end;
  264. procedure penup;
  265. begin
  266. Drawing:=False;
  267. end;
  268. procedure pendown;
  269. begin
  270. Drawing:=True;
  271. end;
  272. procedure circle(radius: integer);
  273. begin
  274. setcanvasparams;
  275. Canvas.arc(TurtX,TurtY,radius,0,2*pi);
  276. end;
  277. procedure box(x,y,color : integer; border : Boolean);
  278. var
  279. c : integer;
  280. begin
  281. c:=turtc;
  282. turtc:=color;
  283. setcanvasparams;
  284. Canvas.fillrect(TurtX,TurtY,X,Y);
  285. turtc:=c;
  286. if border then
  287. begin
  288. setcanvasparams;
  289. Canvas.rect(TurtX,TurtY,X,Y);
  290. end;
  291. end;
  292. procedure blot(radius: integer);
  293. var
  294. P : TJSPath2D;
  295. begin
  296. P:=TJSPath2D.new;
  297. P.arc(TurtX,TurtY,radius,0,2*pi);
  298. setcanvasparams;
  299. canvas.beginpath;
  300. canvas.fill(P);
  301. canvas.stroke;
  302. end;
  303. procedure ellipse(xRadius,yRadius: integer);
  304. begin
  305. setcanvasparams;
  306. Canvas.ellipse(TurtX,TurtY,xRadius,yRadius,0,0,2*pi);
  307. end;
  308. procedure ellblot(xRadius,yRadius : integer);
  309. var
  310. P : TJSPath2D;
  311. begin
  312. P:=TJSPath2D.new;
  313. P.ellipse(TurtX,TurtY,xRadius,yRadius,0,0,2*pi);
  314. setcanvasparams;
  315. canvas.beginpath;
  316. canvas.fill(P);
  317. canvas.stroke;
  318. end;
  319. procedure blank(acolor: integer);
  320. var
  321. c : integer;
  322. begin
  323. c:=turtc;
  324. turtc:=acolor;
  325. setcanvasparams;
  326. canvas.FillRect(-500,-500,1000,1000);
  327. turtc:=c;
  328. end;
  329. procedure _initcanvas(aID : string);
  330. var
  331. cEl : TJSHTMLCanvasElement;
  332. D,w,h : double;
  333. begin
  334. cEl:=TJSHTMLCanvasElement(Document.getElementById(aID));
  335. if cEl=Nil then exit;
  336. W := cEl.getBoundingClientRect().width;
  337. H := cEl.getBoundingClientRect().height;
  338. if H<W then
  339. D:=H
  340. else
  341. D:=W;
  342. cEl.width:=Round(D);
  343. cEl.height:=Round(D);
  344. canvas:=TJSCanvasRenderingContext2D(cel.getContext('2d'));
  345. if not assigned(Canvas) then
  346. exit;
  347. // Transform so middle point is 0,0
  348. // Up is zero degrees...
  349. canvas.transform(0,-D/1000,D/1000,0,D/2,D/2);
  350. colour(black);
  351. thickness(2);
  352. drawing:=true;
  353. end;
  354. procedure colour(aColor : Integer);
  355. begin
  356. turtc:=aColor;
  357. end;
  358. procedure color(aColor: Integer);
  359. begin
  360. colour(aColor);
  361. end;
  362. procedure randcol(n : integer);
  363. begin
  364. if n>50 then n:=50;
  365. if n<1 then n:=1;
  366. color(rgb(1+random(n)));
  367. end;
  368. function rgb(i : integer) : integer;
  369. begin
  370. if (I>=1) and (I<=50) then
  371. Result:=colours[i];
  372. end;
  373. procedure thickness(i : integer);
  374. begin
  375. if I<=0 then exit;
  376. turtt:=i;
  377. end;
  378. initialization
  379. _initCanvas('cnvTurtle');
  380. end.