@edadma/logo 0.2.3 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,29 +1,22 @@
1
1
  {
2
2
  "name": "@edadma/logo",
3
- "version": "0.2.3",
4
- "description": "Logo programming language interpreter with React component",
3
+ "version": "0.2.4",
4
+ "description": "Logo programming language interpreter",
5
5
  "main": "dist/main.js",
6
6
  "module": "dist/main.js",
7
7
  "types": "src/index.d.ts",
8
8
  "files": [
9
9
  "dist",
10
- "src",
11
- "react"
10
+ "src"
12
11
  ],
13
12
  "exports": {
14
13
  ".": {
15
14
  "import": "./dist/main.js",
16
15
  "types": "./src/index.d.ts"
17
- },
18
- "./react": {
19
- "import": "./react/index.ts",
20
- "types": "./react/index.ts"
21
16
  }
22
17
  },
23
18
  "scripts": {
24
- "build": "npm run build:scala && npm run build:react",
25
- "build:scala": "cd .. && sbt logoJS/fullLinkJS && cp js/target/scala-3.7.4/logo-opt/main.js js/target/scala-3.7.4/logo-opt/main.js.map js/dist/",
26
- "build:react": "tsc --project tsconfig.react.json",
19
+ "build": "cd .. && sbt logoJS/fullLinkJS && cp js/target/scala-3.7.4/logo-opt/main.js js/target/scala-3.7.4/logo-opt/main.js.map js/dist/",
27
20
  "prepublishOnly": "npm run build"
28
21
  },
29
22
  "keywords": [
@@ -32,7 +25,6 @@
32
25
  "turtle",
33
26
  "graphics",
34
27
  "education",
35
- "react",
36
28
  "canvas"
37
29
  ],
38
30
  "author": "Edward A. Maxedon, Sr.",
@@ -44,17 +36,5 @@
44
36
  "bugs": {
45
37
  "url": "https://github.com/edadma/logo/issues"
46
38
  },
47
- "homepage": "https://github.com/edadma/logo#readme",
48
- "peerDependencies": {
49
- "react": ">=17.0.0"
50
- },
51
- "peerDependenciesMeta": {
52
- "react": {
53
- "optional": true
54
- }
55
- },
56
- "devDependencies": {
57
- "@types/react": "^18.2.0",
58
- "typescript": "^5.0.0"
59
- }
39
+ "homepage": "https://github.com/edadma/logo#readme"
60
40
  }
@@ -312,22 +312,72 @@ class LogoJS(canvas: html.Canvas) extends js.Object:
312
312
  ctx.stroke()
313
313
 
314
314
  private def drawTurtle(x: Double, y: Double, heading: Double): Unit =
315
- val w = 15.0
316
- val h = 20.0
317
-
318
315
  ctx.save()
319
316
  ctx.translate(x, y)
320
- ctx.rotate(heading - Pi / 2)
317
+ ctx.rotate(heading + Pi / 2)
321
318
 
319
+ // Tail (behind shell)
322
320
  ctx.beginPath()
323
- ctx.moveTo(0, 0)
324
- ctx.lineTo(-w / 2, h / 2)
325
- ctx.lineTo(0, h)
326
- ctx.lineTo(w / 2, h / 2)
327
- ctx.closePath()
328
-
329
- ctx.strokeStyle = "green"
321
+ ctx.moveTo(0, 10)
322
+ ctx.lineTo(0, 14)
323
+ ctx.strokeStyle = "#4a7a44"
330
324
  ctx.lineWidth = 2
325
+ ctx.lineCap = "round"
326
+ ctx.stroke()
327
+
328
+ // Legs (behind shell)
329
+ ctx.fillStyle = "#4a7a44"
330
+ ctx.strokeStyle = "#1a3a18"
331
+ ctx.lineWidth = 1
332
+ // Front legs
333
+ ctx.beginPath()
334
+ ctx.ellipse(-7, -6, 3, 5, 0.4, 0, 2 * Pi)
335
+ ctx.fill()
336
+ ctx.stroke()
337
+ ctx.beginPath()
338
+ ctx.ellipse(7, -6, 3, 5, -0.4, 0, 2 * Pi)
339
+ ctx.fill()
340
+ ctx.stroke()
341
+ // Back legs
342
+ ctx.beginPath()
343
+ ctx.ellipse(-6, 6, 3, 4, 0.3, 0, 2 * Pi)
344
+ ctx.fill()
345
+ ctx.stroke()
346
+ ctx.beginPath()
347
+ ctx.ellipse(6, 6, 3, 4, -0.3, 0, 2 * Pi)
348
+ ctx.fill()
349
+ ctx.stroke()
350
+
351
+ // Head (behind shell)
352
+ ctx.beginPath()
353
+ ctx.ellipse(0, -14, 4, 5, 0, 0, 2 * Pi)
354
+ ctx.fillStyle = "#4a7a44"
355
+ ctx.fill()
356
+ ctx.strokeStyle = "#1a3a18"
357
+ ctx.lineWidth = 1.5
358
+ ctx.stroke()
359
+
360
+ // Eyes
361
+ ctx.fillStyle = "black"
362
+ ctx.beginPath()
363
+ ctx.arc(-1.5, -15, 1, 0, 2 * Pi)
364
+ ctx.arc(1.5, -15, 1, 0, 2 * Pi)
365
+ ctx.fill()
366
+
367
+ // Shell (on top)
368
+ ctx.beginPath()
369
+ ctx.ellipse(0, 0, 8, 10, 0, 0, 2 * Pi)
370
+ ctx.fillStyle = "#2d5a27"
371
+ ctx.fill()
372
+ ctx.strokeStyle = "#1a3a18"
373
+ ctx.lineWidth = 1.5
374
+ ctx.stroke()
375
+
376
+ // Shell pattern
377
+ ctx.strokeStyle = "#3d7a37"
378
+ ctx.lineWidth = 1
379
+ ctx.beginPath()
380
+ ctx.ellipse(0, 0, 5, 6, 0, 0, 2 * Pi)
331
381
  ctx.stroke()
332
382
 
333
383
  ctx.restore()
@@ -1,74 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { useRef, useEffect, useImperativeHandle, forwardRef } from 'react';
3
- export const LogoCanvas = forwardRef(({ width = 600, height = 400, program, pathRendering = true, onError, onComplete, className, style, }, ref) => {
4
- const canvasRef = useRef(null);
5
- const logoRef = useRef(null);
6
- // Initialize Logo instance
7
- useEffect(() => {
8
- if (canvasRef.current && typeof Logo !== 'undefined') {
9
- logoRef.current = new Logo(canvasRef.current);
10
- logoRef.current.setPathRendering(pathRendering);
11
- }
12
- }, []);
13
- // Update path rendering setting
14
- useEffect(() => {
15
- if (logoRef.current) {
16
- logoRef.current.setPathRendering(pathRendering);
17
- }
18
- }, [pathRendering]);
19
- // Run program when it changes
20
- useEffect(() => {
21
- if (logoRef.current && program !== undefined) {
22
- try {
23
- logoRef.current.clear();
24
- logoRef.current.run(program);
25
- onComplete?.();
26
- }
27
- catch (e) {
28
- onError?.(e instanceof Error ? e : new Error(String(e)));
29
- }
30
- }
31
- }, [program, onError, onComplete]);
32
- // Expose methods via ref
33
- useImperativeHandle(ref, () => ({
34
- execute: (command) => {
35
- if (logoRef.current) {
36
- try {
37
- logoRef.current.execute(command);
38
- }
39
- catch (e) {
40
- onError?.(e instanceof Error ? e : new Error(String(e)));
41
- }
42
- }
43
- },
44
- run: (prog) => {
45
- if (logoRef.current) {
46
- try {
47
- logoRef.current.run(prog);
48
- onComplete?.();
49
- }
50
- catch (e) {
51
- onError?.(e instanceof Error ? e : new Error(String(e)));
52
- }
53
- }
54
- },
55
- clear: () => {
56
- logoRef.current?.clear();
57
- },
58
- getDrawing: () => {
59
- return logoRef.current?.getDrawing() ?? { lines: [], labels: [] };
60
- },
61
- getTurtle: () => {
62
- return (logoRef.current?.getTurtle() ?? {
63
- x: 0,
64
- y: 0,
65
- heading: Math.PI / 2,
66
- visible: true,
67
- });
68
- },
69
- getLogo: () => logoRef.current,
70
- }));
71
- return (_jsx("canvas", { ref: canvasRef, width: width, height: height, className: className, style: { backgroundColor: 'white', ...style } }));
72
- });
73
- LogoCanvas.displayName = 'LogoCanvas';
74
- export default LogoCanvas;
@@ -1,2 +0,0 @@
1
- export { LogoCanvas } from './LogoCanvas';
2
- export { LogoCanvas as default } from './LogoCanvas';
@@ -1,174 +0,0 @@
1
- import React, { useRef, useEffect, useImperativeHandle, forwardRef } from 'react';
2
-
3
- // Type definitions for the Logo class from Scala.js
4
- interface LogoDrawing {
5
- lines: Array<{
6
- x1: number;
7
- y1: number;
8
- x2: number;
9
- y2: number;
10
- color: string;
11
- width: number;
12
- }>;
13
- labels: Array<{
14
- x: number;
15
- y: number;
16
- heading: number;
17
- text: string;
18
- }>;
19
- }
20
-
21
- interface TurtleState {
22
- x: number;
23
- y: number;
24
- heading: number;
25
- visible: boolean;
26
- }
27
-
28
- interface LogoInstance {
29
- run(program: string): void;
30
- execute(command: string): void;
31
- clear(): void;
32
- render(): void;
33
- setPathRendering(enabled: boolean): void;
34
- setAutoRender(enabled: boolean): void;
35
- getDrawing(): LogoDrawing;
36
- getTurtle(): TurtleState;
37
- }
38
-
39
- declare const Logo: new (canvas: HTMLCanvasElement) => LogoInstance;
40
-
41
- export interface LogoCanvasProps {
42
- /** Width of the canvas in pixels */
43
- width?: number;
44
- /** Height of the canvas in pixels */
45
- height?: number;
46
- /** Logo program to run */
47
- program?: string;
48
- /** Whether to use path-based rendering (smoother curves) */
49
- pathRendering?: boolean;
50
- /** Callback when an error occurs */
51
- onError?: (error: Error) => void;
52
- /** Callback when program execution completes */
53
- onComplete?: () => void;
54
- /** Additional CSS class for the canvas */
55
- className?: string;
56
- /** Additional inline styles for the canvas */
57
- style?: React.CSSProperties;
58
- }
59
-
60
- export interface LogoCanvasRef {
61
- /** Execute a Logo command */
62
- execute: (command: string) => void;
63
- /** Run a full Logo program */
64
- run: (program: string) => void;
65
- /** Clear the canvas and reset turtle */
66
- clear: () => void;
67
- /** Get the current drawing data */
68
- getDrawing: () => LogoDrawing;
69
- /** Get the current turtle state */
70
- getTurtle: () => TurtleState;
71
- /** Get the underlying Logo instance */
72
- getLogo: () => LogoInstance | null;
73
- }
74
-
75
- export const LogoCanvas = forwardRef<LogoCanvasRef, LogoCanvasProps>(
76
- (
77
- {
78
- width = 600,
79
- height = 400,
80
- program,
81
- pathRendering = true,
82
- onError,
83
- onComplete,
84
- className,
85
- style,
86
- },
87
- ref
88
- ) => {
89
- const canvasRef = useRef<HTMLCanvasElement>(null);
90
- const logoRef = useRef<LogoInstance | null>(null);
91
-
92
- // Initialize Logo instance
93
- useEffect(() => {
94
- if (canvasRef.current && typeof Logo !== 'undefined') {
95
- logoRef.current = new Logo(canvasRef.current);
96
- logoRef.current.setPathRendering(pathRendering);
97
- }
98
- }, []);
99
-
100
- // Update path rendering setting
101
- useEffect(() => {
102
- if (logoRef.current) {
103
- logoRef.current.setPathRendering(pathRendering);
104
- }
105
- }, [pathRendering]);
106
-
107
- // Run program when it changes
108
- useEffect(() => {
109
- if (logoRef.current && program !== undefined) {
110
- try {
111
- logoRef.current.clear();
112
- logoRef.current.run(program);
113
- onComplete?.();
114
- } catch (e) {
115
- onError?.(e instanceof Error ? e : new Error(String(e)));
116
- }
117
- }
118
- }, [program, onError, onComplete]);
119
-
120
- // Expose methods via ref
121
- useImperativeHandle(ref, () => ({
122
- execute: (command: string) => {
123
- if (logoRef.current) {
124
- try {
125
- logoRef.current.execute(command);
126
- } catch (e) {
127
- onError?.(e instanceof Error ? e : new Error(String(e)));
128
- }
129
- }
130
- },
131
- run: (prog: string) => {
132
- if (logoRef.current) {
133
- try {
134
- logoRef.current.run(prog);
135
- onComplete?.();
136
- } catch (e) {
137
- onError?.(e instanceof Error ? e : new Error(String(e)));
138
- }
139
- }
140
- },
141
- clear: () => {
142
- logoRef.current?.clear();
143
- },
144
- getDrawing: () => {
145
- return logoRef.current?.getDrawing() ?? { lines: [], labels: [] };
146
- },
147
- getTurtle: () => {
148
- return (
149
- logoRef.current?.getTurtle() ?? {
150
- x: 0,
151
- y: 0,
152
- heading: Math.PI / 2,
153
- visible: true,
154
- }
155
- );
156
- },
157
- getLogo: () => logoRef.current,
158
- }));
159
-
160
- return (
161
- <canvas
162
- ref={canvasRef}
163
- width={width}
164
- height={height}
165
- className={className}
166
- style={{ backgroundColor: 'white', ...style }}
167
- />
168
- );
169
- }
170
- );
171
-
172
- LogoCanvas.displayName = 'LogoCanvas';
173
-
174
- export default LogoCanvas;
package/react/index.ts DELETED
@@ -1,2 +0,0 @@
1
- export { LogoCanvas, type LogoCanvasProps, type LogoCanvasRef } from './LogoCanvas';
2
- export { LogoCanvas as default } from './LogoCanvas';