Jelajahi Sumber

feat: IJS.input.xy(event) — unified touch-to-canvas coordinate conversion

- IJS.input.xy(e) converts touch event clientX/Y to canvas logical
  coordinates using getBoundingClientRect and the scale factor
- Handles both TouchEvent and MouseEvent
- Power of Two plugin now uses IJS.input.xy(e) instead of manual math
- Plugin system no longer requires per-plugin coordinate conversion

Co-Authored-By: Claude <noreply@anthropic.com>
nonvioce 3 bulan lalu
induk
melakukan
3d4f951334

+ 15 - 0
app/src/main/assets/console.js

@@ -995,6 +995,21 @@ class SymjaConsole {
                 onTouchStart: function(cb) { this._callbacks.touchstart = cb; },
                 onTouchStart: function(cb) { this._callbacks.touchstart = cb; },
                 onTouchMove: function(cb) { this._callbacks.touchmove = cb; },
                 onTouchMove: function(cb) { this._callbacks.touchmove = cb; },
                 onTouchEnd: function(cb) { this._callbacks.touchend = cb; this._bind(); },
                 onTouchEnd: function(cb) { this._callbacks.touchend = cb; this._bind(); },
+                /** 将触摸事件的 clientX/Y 转换为画布逻辑坐标 */
+                xy: function(e) {
+                    var idx = 0;
+                    if (e.changedTouches) idx = 0;
+                    else if (e.touches) idx = 0;
+                    var touch = e.changedTouches ? e.changedTouches[0] : (e.touches ? e.touches[0] : e);
+                    if (!touch) return {x:0,y:0};
+                    var c = IJS.canvas._canvas;
+                    if (!c) return {x: touch.clientX, y: touch.clientY};
+                    var r = c.getBoundingClientRect();
+                    return {
+                        x: (touch.clientX - r.left) * (IJS.canvas._logicalW / r.width),
+                        y: (touch.clientY - r.top) * (IJS.canvas._logicalH / r.height)
+                    };
+                },
                 _bound: false,
                 _bound: false,
                 _bind: function() {
                 _bind: function() {
                     if (this._bound) return;
                     if (this._bound) return;

File diff ditekan karena terlalu besar
+ 0 - 0
app/src/main/assets/plugins/power_of_two.json


+ 1 - 1
app/src/main/java/com/nonvioce/ijs/McpServer.java

@@ -929,7 +929,7 @@ public class McpServer extends NanoHTTPD {
             symja.put("matrix", "{det,inverse,transpose,eigenvalues,rank}");
             symja.put("matrix", "{det,inverse,transpose,eigenvalues,rank}");
             api.put("IJS.Symja", symja);
             api.put("IJS.Symja", symja);
             api.put("IJS.canvas", "create(w?,h?), getContext(), getSize(), width(), height(), clear(), fill(color), size(w,h), loop(cb), stop() — create() without args auto-fills fullscreen panel");
             api.put("IJS.canvas", "create(w?,h?), getContext(), getSize(), width(), height(), clear(), fill(color), size(w,h), loop(cb), stop() — create() without args auto-fills fullscreen panel");
-            api.put("IJS.input", "onTouchStart(cb), onTouchMove(cb), onTouchEnd(cb)");
+            api.put("IJS.input", "xy(event) — convert touch event to canvas coords, onTouchStart/Move/End(cb)");
             api.put("IJS.io", "read(filename), write(filename,content), list(), delete(filename)");
             api.put("IJS.io", "read(filename), write(filename,content), list(), delete(filename)");
             api.put("IJS.audio", "beep(freq,dur,type), playNote(note,oct,dur), playMelody(melody,tempo)");
             api.put("IJS.audio", "beep(freq,dur,type), playNote(note,oct,dur), playMelody(melody,tempo)");
             api.put("IJS.ui", "close(), setBackground(color)");
             api.put("IJS.ui", "close(), setBackground(color)");

Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini