Files
PyCanvas/screen.js
Hugo H ec720711d4
All checks were successful
FTP Upload on Push / deploy (push) Successful in 7s
Added textalign
2025-12-26 15:17:06 +00:00

256 lines
13 KiB
JavaScript

window.onerror = function (message, source, lineno, colno, error) {
if (window.outf) window.outf(`[JS Error] ${message} at ${source}:${lineno}:${colno}\n`);
return false;
};
var $builtinmodule = function (name) {
var mod = {};
var lc_instance = null;
var python_callbacks = {};
function toJS(obj) {
if (obj === undefined || obj === null) return obj;
if (obj instanceof Sk.builtin.int_ || obj instanceof Sk.builtin.float_) {
return Sk.ffi.remapToJs(obj);
}
if (obj instanceof Sk.builtin.str) return obj.v;
if (obj instanceof Sk.builtin.bool) return obj.v;
if (obj instanceof Sk.builtin.list || obj instanceof Sk.builtin.tuple || obj instanceof Sk.builtin.dict) {
return Sk.ffi.remapToJs(obj);
}
return obj;
}
function toPy(obj) {
if (obj === undefined || obj === null) return Sk.builtin.none.none$;
if (typeof obj === 'number') {
return (obj % 1 === 0) ? new Sk.builtin.int_(obj) : new Sk.builtin.float_(obj);
}
if (typeof obj === 'string') return new Sk.builtin.str(obj);
if (typeof obj === 'boolean') return obj ? Sk.builtin.bool.true$ : Sk.builtin.bool.false$;
if (Array.isArray(obj)) return new Sk.builtin.list(obj.map(toPy));
return obj;
}
function makePyCallback(pyFunc) {
if (!pyFunc || pyFunc === Sk.builtin.none.none$) return null;
return function (...args) {
var pyArgs = args.map(toPy);
return Sk.misceval.callsimArray(pyFunc, pyArgs);
};
}
function getDictItem(skDict, keyStr) {
if (!skDict || !(skDict instanceof Sk.builtin.dict)) return null;
const key = new Sk.builtin.str(keyStr);
return skDict.mp$lookup(key);
}
mod.start = new Sk.builtin.func(function (settings) {
let jsSettings = {};
var loopInit = null;
var loopUpdate = null;
var loopDraw = null;
var loopResized = null;
var loopTap = null;
var loopUntap = null;
var loopTapping = null;
var loopTapped = null;
if (settings && settings !== Sk.builtin.none.none$) {
jsSettings = toJS(settings);
if (settings instanceof Sk.builtin.dict) {
var loopDict = getDictItem(settings, 'loop');
if (loopDict && loopDict instanceof Sk.builtin.dict) {
loopInit = getDictItem(loopDict, 'init');
loopUpdate = getDictItem(loopDict, 'update');
loopDraw = getDictItem(loopDict, 'draw');
loopResized = getDictItem(loopDict, 'resized');
loopTap = getDictItem(loopDict, 'tap');
loopUntap = getDictItem(loopDict, 'untap');
loopTapping = getDictItem(loopDict, 'tapping');
loopTapped = getDictItem(loopDict, 'tapped');
}
}
}
if (!jsSettings.canvas) jsSettings.canvas = '#canvas';
const canvasEl = document.querySelector(jsSettings.canvas);
if (canvasEl) {
const rect = canvasEl.getBoundingClientRect();
canvasEl.width = rect.width || canvasEl.clientWidth;
canvasEl.height = rect.height || canvasEl.clientHeight;
jsSettings.width = Math.floor(canvasEl.clientWidth);
jsSettings.height = Math.floor(canvasEl.clientHeight);
jsSettings.canvas = canvasEl;
jsSettings.fullscreen = false;
jsSettings.autoscale = false;
}
if (jsSettings.autoscale === undefined) jsSettings.autoscale = false;
var jsLoop = jsSettings.loop || {};
python_callbacks = {
init: loopInit || jsLoop.init,
update: loopUpdate || jsLoop.update,
draw: loopDraw || jsLoop.draw,
resized: loopResized || jsLoop.resized,
tap: loopTap || jsLoop.tap,
untap: loopUntap || jsLoop.untap,
tapping: loopTapping || jsLoop.tapping,
tapped: loopTapped || jsLoop.tapped
};
jsSettings.loop = {
init: python_callbacks.init ? makePyCallbackNoArgs(python_callbacks.init) : null,
update: python_callbacks.update ? makePyCallbackNoArgs(python_callbacks.update) : null,
draw: python_callbacks.draw ? makeSafePyCallbackNoArgs(python_callbacks.draw) : null,
resized: python_callbacks.resized ? makePyCallback(python_callbacks.resized) : null,
tap: python_callbacks.tap ? makePyCallbackTapArgs(python_callbacks.tap) : null,
untap: python_callbacks.untap ? makePyCallbackTapArgs(python_callbacks.untap) : null,
tapping: python_callbacks.tapping ? makePyCallbackTapArgs(python_callbacks.tapping) : null,
tapped: python_callbacks.tapped ? makePyCallbackTapArgs(python_callbacks.tapped) : null
};
if (typeof litecanvas === 'undefined') {
throw new Sk.builtin.ImportError("litecanvas library not found.");
}
try {
lc_instance = litecanvas(jsSettings);
window.__lc_instance = lc_instance;
} catch (e) {
if (window.outf) window.outf(`[litecanvas] Error: ${e}\n`);
throw e;
}
return Sk.builtin.none.none$;
});
var current_dt = 0;
function makeSafePyCallbackNoArgs(pyFunc) {
if (!pyFunc || pyFunc === Sk.builtin.none.none$) return null;
return function (dt) {
if (typeof dt === 'number') current_dt = dt;
try { return Sk.misceval.callsimArray(pyFunc, []); }
catch (e) {
if (window.outf) window.outf(`[Error] ${e}\n`);
if (lc_instance) lc_instance.pause();
throw e;
}
};
}
function makePyCallbackNoArgs(pyFunc) {
if (!pyFunc || pyFunc === Sk.builtin.none.none$) return null;
return function (dt) {
if (typeof dt === 'number') current_dt = dt;
return Sk.misceval.callsimArray(pyFunc, []);
};
}
function makePyCallbackTapArgs(pyFunc) {
if (!pyFunc || pyFunc === Sk.builtin.none.none$) return null;
return function (x, y, id) {
const el = document.getElementById('canvas');
let lx = x;
let ly = y;
if (el) {
const rect = el.getBoundingClientRect();
// Map from window coordinates to canvas local coordinates
lx = (x - rect.left) * (el.width / rect.width);
ly = (y - rect.top) * (el.height / rect.height);
}
var pyArgs = [lx, ly, id].map(toPy);
return Sk.misceval.callsimArray(pyFunc, pyArgs);
};
}
Object.defineProperty(mod, 'T', { get: function () { return toPy(lc_instance ? lc_instance.T : (window.T || 0)); } });
Object.defineProperty(mod, 'W', { get: function () { return toPy(lc_instance ? lc_instance.W : (window.W || 0)); } });
Object.defineProperty(mod, 'H', { get: function () { return toPy(lc_instance ? lc_instance.H : (window.H || 0)); } });
Object.defineProperty(mod, 'DT', {
get: function () {
if (lc_instance && lc_instance.dt !== undefined) return toPy(lc_instance.dt);
return toPy(current_dt);
}
});
Object.defineProperty(mod, 'MX', {
get: function () {
let mx = lc_instance ? lc_instance.MX : (window.MX || -1);
const el = document.getElementById('canvas');
if (!el || mx === -1) return toPy(mx);
const r = el.getBoundingClientRect();
return toPy((mx - r.left) * (el.width / r.width));
}
});
Object.defineProperty(mod, 'MY', {
get: function () {
let my = lc_instance ? lc_instance.MY : (window.MY || -1);
const el = document.getElementById('canvas');
if (!el || my === -1) return toPy(my);
const r = el.getBoundingClientRect();
return toPy((my - r.top) * (el.height / r.height));
}
});
Object.defineProperty(mod, 'CENTERX', {
get: function () {
if (lc_instance && lc_instance.CENTERX !== undefined) return toPy(lc_instance.CENTERX);
if (window.CENTERX !== undefined) return toPy(window.CENTERX);
let w = lc_instance ? lc_instance.W : (window.W || 0);
return toPy(w / 2);
}
});
Object.defineProperty(mod, 'CENTERY', {
get: function () {
if (lc_instance && lc_instance.CENTERY !== undefined) return toPy(lc_instance.CENTERY);
if (window.CENTERY !== undefined) return toPy(window.CENTERY);
let h = lc_instance ? lc_instance.H : (window.H || 0);
return toPy(h / 2);
}
});
mod.PI = toPy(Math.PI);
mod.TWO_PI = toPy(Math.PI * 2);
mod.HALF_PI = toPy(Math.PI / 2);
mod.cls = new Sk.builtin.func((c) => { cls(c !== undefined ? toJS(c) : undefined); return Sk.builtin.none.none$; });
mod.rectfill = new Sk.builtin.func((x, y, w, h, c) => { rectfill(toJS(x), toJS(y), toJS(w), toJS(h), c !== undefined ? toJS(c) : 0); return Sk.builtin.none.none$; });
mod.rect = new Sk.builtin.func((x, y, w, h, c) => { rect(toJS(x), toJS(y), toJS(w), toJS(h), c !== undefined ? toJS(c) : 0); return Sk.builtin.none.none$; });
mod.circfill = new Sk.builtin.func((x, y, r, c) => { circfill(toJS(x), toJS(y), toJS(r), c !== undefined ? toJS(c) : 0); return Sk.builtin.none.none$; });
mod.circ = new Sk.builtin.func((x, y, r, c) => { circ(toJS(x), toJS(y), toJS(r), c !== undefined ? toJS(c) : 0); return Sk.builtin.none.none$; });
mod.text = new Sk.builtin.func((x, y, t, c, s) => { text(toJS(x), toJS(y), toJS(t), c !== undefined ? toJS(c) : 3, s !== undefined ? toJS(s) : 'normal'); return Sk.builtin.none.none$; });
mod.textsize = new Sk.builtin.func((s) => { textsize(toJS(s)); return Sk.builtin.none.none$; });
mod.textalign = new Sk.builtin.func((h, v) => { textalign(toJS(h), v !== undefined ? toJS(v) : undefined); return Sk.builtin.none.none$; });
mod.ovalfill = new Sk.builtin.func((x, y, rx, ry, c) => { ovalfill(toJS(x), toJS(y), toJS(rx), toJS(ry), c !== undefined ? toJS(c) : 0); return Sk.builtin.none.none$; });
mod.oval = new Sk.builtin.func((x, y, rx, ry, c) => { oval(toJS(x), toJS(y), toJS(rx), toJS(ry), c !== undefined ? toJS(c) : 0); return Sk.builtin.none.none$; });
mod.line = new Sk.builtin.func((x1, y1, x2, y2, c) => { line(toJS(x1), toJS(y1), toJS(x2), toJS(y2), c !== undefined ? toJS(c) : 0); return Sk.builtin.none.none$; });
mod.linewidth = new Sk.builtin.func((v) => { linewidth(toJS(v)); return Sk.builtin.none.none$; });
mod.push = new Sk.builtin.func(() => { push(); return Sk.builtin.none.none$; });
mod.pop = new Sk.builtin.func(() => { pop(); return Sk.builtin.none.none$; });
mod.translate = new Sk.builtin.func((x, y) => { translate(toJS(x), toJS(y)); return Sk.builtin.none.none$; });
mod.scale = new Sk.builtin.func((x, y) => { window.scale(toJS(x), y !== undefined ? toJS(y) : undefined); return Sk.builtin.none.none$; });
mod.rotate = new Sk.builtin.func((r) => { rotate(toJS(r)); return Sk.builtin.none.none$; });
mod.alpha = new Sk.builtin.func((v) => { alpha(toJS(v)); return Sk.builtin.none.none$; });
mod.fill = new Sk.builtin.func((c) => { fill(toJS(c)); return Sk.builtin.none.none$; });
mod.stroke = new Sk.builtin.func((c) => { window.stroke(toJS(c)); return Sk.builtin.none.none$; });
mod.sfx = new Sk.builtin.func((p, ps, vf) => { var r = sfx(toJS(p), ps ? toJS(ps) : 0, vf ? toJS(vf) : 1); return r ? toPy(r) : Sk.builtin.bool.false$; });
mod.volume = new Sk.builtin.func((v) => { volume(toJS(v)); return Sk.builtin.none.none$; });
mod.iskeydown = new Sk.builtin.func((k) => toPy(iskeydown(k ? toJS(k) : undefined)));
mod.iskeypressed = new Sk.builtin.func((k) => toPy(iskeypressed(k ? toJS(k) : undefined)));
mod.rand = new Sk.builtin.func((mn, mx) => toPy(rand(mn ? toJS(mn) : 0, mx ? toJS(mx) : 1)));
mod.randi = new Sk.builtin.func((mn, mx) => toPy(randi(mn ? toJS(mn) : 0, mx ? toJS(mx) : 1)));
mod.rseed = new Sk.builtin.func((s) => { seed(toJS(s)); return Sk.builtin.none.none$; });
mod.sin = new Sk.builtin.func((a) => toPy(Math.sin(toJS(a))));
mod.cos = new Sk.builtin.func((a) => toPy(Math.cos(toJS(a))));
mod.abs = new Sk.builtin.func((n) => toPy(Math.abs(toJS(n))));
mod.sqrt = new Sk.builtin.func((n) => toPy(Math.sqrt(toJS(n))));
mod.pause = new Sk.builtin.func(() => { pause(); return Sk.builtin.none.none$; });
mod.resume = new Sk.builtin.func(() => { resume(); return Sk.builtin.none.none$; });
return mod;
};