feat(boards): 增加python_skulpt_car板卡
This commit is contained in:
@@ -2,15 +2,22 @@
|
||||
import Sk from './skulpt/skulpt';
|
||||
import { Events, Debug } from 'mixly';
|
||||
import MIXPY_TEMPLATE from '../templates/python/mixpy.py';
|
||||
import NUMPY_URL from '../others/skulpt/libs/numpy/__init__.js?url';
|
||||
import PYGAL_URL from '../others/skulpt/libs/pygal/__init__.js?url';
|
||||
import MATPLOTLIB_URL from '../others/skulpt/libs/matplotlib/__init__.js?url';
|
||||
import PYPLOT_URL from '../others/skulpt/libs/pyplot/__init__.js?url';
|
||||
import PGZHELPER_URL from '../others/skulpt/libs/pgzhelper/pgzhelper.js?url';
|
||||
import SPRITE_URL from '../others/skulpt/libs/sprite/basic.js?url';
|
||||
|
||||
const externalLibs = {//外部引入的第三方库
|
||||
"./numpy/__init__.js": "../common/js/skulpt_libs/numpy/__init__.js",
|
||||
"./pygal/__init__.js": "../common/js/skulpt_libs/pygal/__init__.js",
|
||||
// "./numpy/random/__init__.js" : 'https://cdn.jsdelivr.net/gh/ebertmi/skulpt_numpy@master/numpy/random/__init__.js',
|
||||
"./matplotlib/__init__.js": '../common/js/skulpt_libs/matplotlib/__init__.js',
|
||||
"./matplotlib/pyplot/__init__.js": "../common/js/skulpt_libs/pyplot/__init__.js",
|
||||
'./pgzhelper/__init__.js': "../common/js/skulpt_libs/pgzhelper/pgzhelper.js",
|
||||
"./sprite/__init__.js": "../common/js/skulpt_libs/sprite/basic.js"
|
||||
|
||||
// 外部引入的第三方库
|
||||
const externalLibs = {
|
||||
'./numpy/__init__.js': NUMPY_URL,
|
||||
'./pygal/__init__.js': PYGAL_URL,
|
||||
'./matplotlib/__init__.js': MATPLOTLIB_URL,
|
||||
'./matplotlib/pyplot/__init__.js': PYPLOT_URL,
|
||||
'./pgzhelper/__init__.js': PGZHELPER_URL,
|
||||
'./sprite/__init__.js': SPRITE_URL
|
||||
};
|
||||
|
||||
var GLOBAL_VALUE;
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
var $builtinmodule = function(name)
|
||||
{
|
||||
var matplotlib = {};
|
||||
|
||||
return matplotlib;
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,5 @@
|
||||
var $builtinmodule = function (name) {
|
||||
let pgzhelper= {__name__: new Sk.builtin.str("pgzhelper")};
|
||||
|
||||
return pgzhelper;
|
||||
}
|
||||
@@ -0,0 +1,393 @@
|
||||
var $builtinmodule = function(name) {
|
||||
function fill(arr, val) {
|
||||
if (Array.prototype.fill) {
|
||||
return Array.prototype.fill.bind(arr)(val, arguments[2], arguments[3]);
|
||||
}
|
||||
|
||||
// Steps 1-2.
|
||||
if (arr == null) {
|
||||
throw new TypeError('arr is null or not defined');
|
||||
}
|
||||
|
||||
var O = Object(arr);
|
||||
|
||||
// Steps 3-5.
|
||||
var len = O.length >>> 0;
|
||||
|
||||
// Steps 6-7.
|
||||
var start = arguments[2];
|
||||
var relativeStart = start >> 0;
|
||||
|
||||
// Step 8.
|
||||
var k = relativeStart < 0 ?
|
||||
Math.max(len + relativeStart, 0) :
|
||||
Math.min(relativeStart, len);
|
||||
|
||||
// Steps 9-10.
|
||||
var end = arguments[3];
|
||||
var relativeEnd = end === undefined ?
|
||||
len : end >> 0;
|
||||
|
||||
// Step 11.
|
||||
var final = relativeEnd < 0 ?
|
||||
Math.max(len + relativeEnd, 0) :
|
||||
Math.min(relativeEnd, len);
|
||||
|
||||
// Step 12.
|
||||
while (k < final) {
|
||||
O[k] = value;
|
||||
k++;
|
||||
}
|
||||
|
||||
// Step 13.
|
||||
return O;
|
||||
}
|
||||
|
||||
|
||||
var mod = {};
|
||||
|
||||
var COLORS = [
|
||||
[255, 89, 149], [182, 227, 84], [254, 237, 108], [140, 237, 255],
|
||||
[158, 111, 254], [137, 156, 161], [248, 248, 242], [191, 70, 70],
|
||||
[81, 96, 131], [249, 38, 114], [130, 180, 20], [253, 151, 31],
|
||||
[86, 194, 214], [128, 131, 132], [140, 84, 254], [70, 84, 87]
|
||||
];
|
||||
|
||||
var KWARGS = ['title', 'width', 'height', 'range', 'include_x_axis', 'x_title', 'y_title', 'title_font_size', 'fill', 'stroke', 'x_labels'];
|
||||
|
||||
function Chart(options) {
|
||||
this._options = options;
|
||||
this._data = [];
|
||||
}
|
||||
|
||||
function rgba(rgb, a) {
|
||||
return 'rgba(' + rgb.join(',') + ',' + a + ')';
|
||||
}
|
||||
|
||||
Chart.prototype.add = function(label, values) {
|
||||
this._data.unshift({
|
||||
name: label,
|
||||
color: rgba(COLORS[this._data.length%COLORS.length], 0.75),
|
||||
data: values,
|
||||
marker : {
|
||||
symbol: 'circle'
|
||||
},
|
||||
stack : 1
|
||||
});
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
Chart.prototype.render = function(renderer) {
|
||||
var options = this._options;
|
||||
var $elem = Sk.domOutput('<div></div>');
|
||||
var title_style = {
|
||||
color: '#FFFFFF'
|
||||
};
|
||||
if (options.title_font_size) {
|
||||
title_style['font-size'] = options.title_font_size + 'px';
|
||||
}
|
||||
var xPlotLines = [];
|
||||
var yPlotLines = [];
|
||||
|
||||
if (options.range) {
|
||||
yPlotLines.push({
|
||||
value: options.range.min,
|
||||
width: 1,
|
||||
color: '#FFFFFF'
|
||||
});
|
||||
}
|
||||
|
||||
var defaultWidth = Sk.availableWidth || 400;
|
||||
var defaultHeight = Math.min(defaultWidth, Sk.availableHeight || 300);
|
||||
|
||||
var chart = {
|
||||
chart: {
|
||||
width : options.width || defaultWidth,
|
||||
height: options.height || defaultHeight,
|
||||
backgroundColor: '#000'
|
||||
},
|
||||
credits: {
|
||||
enabled: false
|
||||
},
|
||||
title: {
|
||||
text: options.title,
|
||||
style : title_style
|
||||
},
|
||||
xAxis: {
|
||||
title: {
|
||||
text: options.x_title || null,
|
||||
style : title_style,
|
||||
margin: 20
|
||||
},
|
||||
categories: options.x_labels,
|
||||
labels : {
|
||||
enabled: options.x_labels ? true : false
|
||||
},
|
||||
tickLength: 0
|
||||
},
|
||||
yAxis: {
|
||||
startOnTick: false,
|
||||
title: {
|
||||
text: options.y_title || null,
|
||||
style : title_style,
|
||||
margin: 20
|
||||
},
|
||||
plotLines: yPlotLines,
|
||||
min : options.include_x_axis
|
||||
? 0
|
||||
: options.range
|
||||
? options.range.min
|
||||
: null,
|
||||
max : options.range ? options.range.max : null,
|
||||
gridLineDashStyle : 'ShortDash',
|
||||
gridLineColor: '#DDD',
|
||||
tickLength: 0
|
||||
},
|
||||
legend: {
|
||||
itemStyle : {
|
||||
color : '#FFFFFF'
|
||||
},
|
||||
layout: 'vertical',
|
||||
align: 'left',
|
||||
verticalAlign: 'top',
|
||||
y: 50,
|
||||
borderWidth: 0
|
||||
},
|
||||
labels : {
|
||||
style : {
|
||||
color: '#FFFFFF'
|
||||
}
|
||||
},
|
||||
series: this._data
|
||||
};
|
||||
|
||||
for(var i = 0; i < chart.series.length; i++) {
|
||||
chart.series[i].legendIndex = chart.series.length - i;
|
||||
chart.series[i].index = chart.series.length - i;
|
||||
}
|
||||
|
||||
if (renderer) {
|
||||
chart = renderer(options, chart);
|
||||
}
|
||||
|
||||
$elem.highcharts(chart);
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
function some(val) {
|
||||
return val && val !== Sk.builtin.none.none$;
|
||||
}
|
||||
|
||||
function kwfunc(impl, kwargs) {
|
||||
if (kwargs && kwargs.length) {
|
||||
impl.co_varnames = ['__self__'].concat(kwargs);
|
||||
impl.$defaults = fill(new Array(kwargs.length), Sk.builtin.none.none$);
|
||||
}
|
||||
return new Sk.builtin.func(impl);
|
||||
}
|
||||
|
||||
function createChartType(type, renderer) {
|
||||
mod[type] = Sk.misceval.buildClass(mod, function($gbl, $loc) {
|
||||
$loc.__init__ = kwfunc(
|
||||
function(self, title, width, height, range, include_x_axis, x_title, y_title, title_font_size, fill, stroke, x_labels) {
|
||||
var options = {};
|
||||
if (some(title)) options.title = title.v;
|
||||
if (some(width)) options.width = width.v;
|
||||
if (some(height)) options.height = height.v;
|
||||
if (some(range)) options.range = {
|
||||
min: range.v[0].v,
|
||||
max: range.v[1].v
|
||||
};
|
||||
if (some(include_x_axis)) options.include_x_axis = include_x_axis.v;
|
||||
if (some(x_title)) options.x_title = x_title.v;
|
||||
if (some(y_title)) options.y_title = y_title.v;
|
||||
if (some(title_font_size)) options.title_font_size = title_font_size.v;
|
||||
if (some(fill)) options.fill = fill.v;
|
||||
if (some(stroke)) options.stroke = stroke.v;
|
||||
if (some(x_labels)) options.x_labels = x_labels.v;
|
||||
|
||||
self.instance = new Chart(options);
|
||||
}, KWARGS
|
||||
);
|
||||
|
||||
$loc.add = new Sk.builtin.func(function(self, label, values) {
|
||||
values = (values instanceof Sk.builtin.list)
|
||||
? Sk.ffi.remapToJs(values)
|
||||
: [values.v];
|
||||
|
||||
return self.instance.add(label.v, values);
|
||||
});
|
||||
|
||||
$loc.render = new Sk.builtin.func(function(self) {
|
||||
var i, key, val;
|
||||
|
||||
for (i = 0; i < KWARGS.length; i++) {
|
||||
key = KWARGS[i];
|
||||
val = self.tp$getattr(key);
|
||||
|
||||
if (typeof val !== "undefined") {
|
||||
self.instance._options[key] = Sk.ffi.remapToJs(val);
|
||||
}
|
||||
}
|
||||
|
||||
return self.instance.render(renderer);
|
||||
});
|
||||
}, type, []);
|
||||
}
|
||||
|
||||
createChartType('Line', function(options, chart) {
|
||||
chart.chart.type = options.fill ? 'area' : 'line';
|
||||
return chart;
|
||||
});
|
||||
createChartType('StackedLine', function(options, chart) {
|
||||
chart.chart.type = options.fill ? 'area' : 'line';
|
||||
chart.plotOptions = {
|
||||
area : {
|
||||
stacking : 'percent'
|
||||
},
|
||||
series : {
|
||||
stacking : 'percent'
|
||||
}
|
||||
};
|
||||
return chart;
|
||||
});
|
||||
createChartType('Bar', function(options, chart) {
|
||||
chart.chart.type = 'column';
|
||||
return chart;
|
||||
});
|
||||
createChartType('StackedBar', function(options, chart) {
|
||||
chart.chart.type = 'column';
|
||||
chart.plotOptions = {
|
||||
column : {
|
||||
stacking: 'percent'
|
||||
}
|
||||
};
|
||||
return chart;
|
||||
});
|
||||
createChartType('HorizontalBar', function(options, chart) {
|
||||
chart.chart.type = 'bar';
|
||||
return chart;
|
||||
});
|
||||
createChartType('StackedHorizontalBar', function(options, chart) {
|
||||
chart.chart.type = 'bar';
|
||||
chart.plotOptions = {
|
||||
bar : {
|
||||
stacking: 'percent'
|
||||
}
|
||||
};
|
||||
return chart;
|
||||
});
|
||||
createChartType('XY', function(options, chart) {
|
||||
if (options.stroke === false) {
|
||||
chart.chart.type = 'scatter'
|
||||
}
|
||||
else {
|
||||
chart.chart.type = options.fill ? 'area' : 'line';
|
||||
}
|
||||
chart.xAxis.labels.enabled = true;
|
||||
|
||||
return chart;
|
||||
});
|
||||
createChartType('Radar', function(options, chart) {
|
||||
chart.chart.polar = true;
|
||||
chart.chart.type = 'line';
|
||||
chart.xAxis = {
|
||||
categories: options.x_labels,
|
||||
tickmarkPlacement: 'on',
|
||||
lineWidth: 0
|
||||
}
|
||||
chart.yAxis = {
|
||||
gridLineInterpolation: 'polygon',
|
||||
lineWidth: 0,
|
||||
min: 0,
|
||||
gridLineDashStyle : 'ShortDash',
|
||||
gridLineColor: '#DDD'
|
||||
}
|
||||
for(var i = 0; i < chart.series.length; i++) {
|
||||
chart.series[i].pointPlacement = 'on';
|
||||
}
|
||||
|
||||
return chart;
|
||||
});
|
||||
createChartType('Pie', function(options, chart) {
|
||||
chart.chart.type = 'pie';
|
||||
var slices = [];
|
||||
var breakdown = [];
|
||||
var useBreakdown = false;
|
||||
for(var i = 0; i < chart.series.length; i++) {
|
||||
var slice = chart.series[i];
|
||||
if (slice.data.length === 1) {
|
||||
slices.unshift({
|
||||
name : slice.name,
|
||||
color : slice.color,
|
||||
borderColor : slice.color,
|
||||
legendIndex : slice.legendIndex,
|
||||
y : slice.data[0]
|
||||
});
|
||||
breakdown.unshift({
|
||||
name : slice.name,
|
||||
color : slice.color,
|
||||
borderColor : slice.color,
|
||||
y : slice.data[0]
|
||||
});
|
||||
}
|
||||
else {
|
||||
useBreakdown = true;
|
||||
var sum = 0;
|
||||
var maxDecimal = 0;
|
||||
for(var j = 0; j < slice.data.length; j++) {
|
||||
var parts = slice.data[j].toString().split('.');
|
||||
maxDecimal = Math.max(maxDecimal, parts[1] ? parts[1].length : 0);
|
||||
sum += slice.data[j];
|
||||
breakdown.unshift({
|
||||
name: slice.name,
|
||||
color: 'rgba(0,0,0,0)',
|
||||
borderColor : slice.color,
|
||||
y: slice.data[j]
|
||||
});
|
||||
}
|
||||
slices.unshift({
|
||||
name : slice.name,
|
||||
color : slice.color,
|
||||
borderColor : slice.color,
|
||||
legendIndex : slice.legendIndex,
|
||||
y : parseFloat(sum.toFixed(maxDecimal))
|
||||
});
|
||||
}
|
||||
}
|
||||
chart.tooltip = {
|
||||
formatter: function() {
|
||||
return this.key + ': ' + this.y;
|
||||
}
|
||||
};
|
||||
chart.plotOptions = {
|
||||
pie: {
|
||||
allowPointSelect: !useBreakdown,
|
||||
cursor: useBreakdown ? null : 'pointer',
|
||||
shadow: false,
|
||||
center: ['50%', '50%'],
|
||||
dataLabels: {
|
||||
enabled: false
|
||||
}
|
||||
}
|
||||
};
|
||||
chart.series = [{
|
||||
name: ' ',
|
||||
data: slices,
|
||||
showInLegend: true
|
||||
}];
|
||||
if (useBreakdown) {
|
||||
chart.series.push({
|
||||
name: ' ',
|
||||
data: breakdown,
|
||||
innerSize: '90%',
|
||||
showInLegend: false
|
||||
});
|
||||
}
|
||||
return chart;
|
||||
});
|
||||
|
||||
return mod;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,229 @@
|
||||
var $builtinmodule = function (name) {
|
||||
var sprite = {__name__: new Sk.builtin.str("sprite")};
|
||||
sprite.createBackground = new Sk.builtin.func(function(img) {
|
||||
img=Sk.ffi.remapToJs(img);
|
||||
return Sk.ffi.remapToPy(SPRITE.CreateBackground(img));
|
||||
});
|
||||
|
||||
sprite.Sprite = Sk.misceval.buildClass(sprite, function($gbl, $loc) {
|
||||
|
||||
$loc.__init__ = new Sk.builtin.func(function(self, img, x, y, name) {
|
||||
img=Sk.ffi.remapToJs(img);
|
||||
x=Sk.ffi.remapToJs(x);
|
||||
y=Sk.ffi.remapToJs(y);
|
||||
name=Sk.ffi.remapToJs(name);
|
||||
self.v$name = Sk.ffi.remapToPy(SPRITE.CreateASprite(img, x, y, name));
|
||||
});
|
||||
|
||||
$loc.show = new Sk.builtin.func(function(self) {
|
||||
var name = Sk.ffi.remapToJs(self.v$name);
|
||||
var t = SPRITE.sprites[name];
|
||||
t.show();
|
||||
});
|
||||
|
||||
$loc.hide = new Sk.builtin.func(function(self) {
|
||||
var name = Sk.ffi.remapToJs(self.v$name);
|
||||
var t = SPRITE.sprites[name];
|
||||
t.hide();
|
||||
});
|
||||
|
||||
$loc.enlarge = new Sk.builtin.func(function(self, s) {
|
||||
var name = Sk.ffi.remapToJs(self.v$name);
|
||||
var s = Sk.ffi.remapToJs(s);
|
||||
var t = SPRITE.sprites[name];
|
||||
t.enlarge(s);
|
||||
});
|
||||
|
||||
$loc.enlargeTo = new Sk.builtin.func(function(self, s) {
|
||||
var name = Sk.ffi.remapToJs(self.v$name);
|
||||
var s = Sk.ffi.remapToJs(s);
|
||||
var t = SPRITE.sprites[name];
|
||||
t.enlargeTo(s);
|
||||
});
|
||||
|
||||
$loc.expandTo = new Sk.builtin.func(function(self, s, time) {
|
||||
var name = Sk.ffi.remapToJs(self.v$name);
|
||||
var s = Sk.ffi.remapToJs(s);
|
||||
var t = SPRITE.sprites[name];
|
||||
return t.expandTo(s, time);
|
||||
});
|
||||
|
||||
$loc.move = new Sk.builtin.func(function(self, step) {
|
||||
var name = Sk.ffi.remapToJs(self.v$name);
|
||||
step=Sk.ffi.remapToJs(step);
|
||||
var t = SPRITE.sprites[name];
|
||||
t.move(step);
|
||||
});
|
||||
|
||||
$loc.moveTo = new Sk.builtin.func(function(self, x, y) {
|
||||
var name = Sk.ffi.remapToJs(self.v$name);
|
||||
x=Sk.ffi.remapToJs(x);
|
||||
y=Sk.ffi.remapToJs(y);
|
||||
var t = SPRITE.sprites[name];
|
||||
t.moveTo(x, y);
|
||||
});
|
||||
|
||||
$loc.slideTo = new Sk.builtin.func(function(self, x, y, time) {
|
||||
var name = Sk.ffi.remapToJs(self.v$name);
|
||||
x=Sk.ffi.remapToJs(x);
|
||||
y=Sk.ffi.remapToJs(y);
|
||||
time=Sk.ffi.remapToJs(time);
|
||||
var t = SPRITE.sprites[name];
|
||||
return t.slideTo(x, y, time);
|
||||
});
|
||||
|
||||
$loc.addX = new Sk.builtin.func(function(self, step) {
|
||||
var name = Sk.ffi.remapToJs(self.v$name);
|
||||
step = Sk.ffi.remapToJs(step);
|
||||
var t = SPRITE.sprites[name];
|
||||
t.addX(step);
|
||||
});
|
||||
|
||||
$loc.addY = new Sk.builtin.func(function(self, step) {
|
||||
var name = Sk.ffi.remapToJs(self.v$name);
|
||||
step = Sk.ffi.remapToJs(step);
|
||||
var t = SPRITE.sprites[name];
|
||||
t.addY(step);
|
||||
});
|
||||
|
||||
$loc.getX = new Sk.builtin.func(function(self) {
|
||||
var name = Sk.ffi.remapToJs(self.v$name);
|
||||
var t = SPRITE.sprites[name];
|
||||
return Sk.ffi.remapToPy(t.x);
|
||||
});
|
||||
|
||||
$loc.getY = new Sk.builtin.func(function(self) {
|
||||
var name = Sk.ffi.remapToJs(self.v$name);
|
||||
var t = SPRITE.sprites[name];
|
||||
return Sk.ffi.remapToPy(t.y);
|
||||
});
|
||||
|
||||
$loc.rotate = new Sk.builtin.func(function(self, degree) {
|
||||
var name = Sk.ffi.remapToJs(self.v$name);
|
||||
degree=Sk.ffi.remapToJs(degree);
|
||||
var t = SPRITE.sprites[name];
|
||||
t.rotate(degree);
|
||||
});
|
||||
|
||||
$loc.rotateTo = new Sk.builtin.func(function(self, degree) {
|
||||
var name = Sk.ffi.remapToJs(self.v$name);
|
||||
degree=Sk.ffi.remapToJs(degree);
|
||||
var t = SPRITE.sprites[name];
|
||||
t.rotateTo(degree);
|
||||
});
|
||||
|
||||
$loc.circleTo = new Sk.builtin.func(function(self, degree, time) {
|
||||
var name = Sk.ffi.remapToJs(self.v$name);
|
||||
degree=Sk.ffi.remapToJs(degree);
|
||||
var t = SPRITE.sprites[name];
|
||||
return t.circleTo(degree);
|
||||
});
|
||||
|
||||
$loc.hit = new Sk.builtin.func(function(self, sprite2) {
|
||||
var name = Sk.ffi.remapToJs(self.v$name);
|
||||
var name2 = Sk.ffi.remapToJs(sprite2.v$name);
|
||||
var t = SPRITE.sprites[name];
|
||||
var t2 = SPRITE.sprites[name2];
|
||||
return Sk.ffi.remapToPy(t.hit(t2));
|
||||
});
|
||||
|
||||
$loc.outOfScreen = new Sk.builtin.func(function(self) {
|
||||
var name = Sk.ffi.remapToJs(self.v$name);
|
||||
var t = SPRITE.sprites[name];
|
||||
return Sk.ffi.remapToPy(t.outOfScreen());
|
||||
});
|
||||
|
||||
$loc.mouseAction = new Sk.builtin.func(function(self, calc) {
|
||||
var name = Sk.ffi.remapToJs(self.v$name);
|
||||
var t = SPRITE.sprites[name];
|
||||
t.mouseAction(()=>{Sk.misceval.callsim(calc)});
|
||||
});
|
||||
|
||||
$loc.isClicked = new Sk.builtin.func(function(self) {
|
||||
var name = Sk.ffi.remapToJs(self.v$name);
|
||||
var t = SPRITE.sprites[name];
|
||||
return Sk.ffi.remapToPy(t.isDown);
|
||||
});
|
||||
|
||||
// new
|
||||
$loc.setScale = new Sk.builtin.func(function(self, h, w) {
|
||||
var name = Sk.ffi.remapToJs(self.v$name);
|
||||
var t = SPRITE.sprites[name];
|
||||
t.setScale(h, w);
|
||||
});
|
||||
$loc.filterGray = new Sk.builtin.func(function(self) {
|
||||
var name = Sk.ffi.remapToJs(self.v$name);
|
||||
var t = SPRITE.sprites[name];
|
||||
t.filterGray();
|
||||
});
|
||||
$loc.filterBrighter = new Sk.builtin.func(function(self) {
|
||||
var name = Sk.ffi.remapToJs(self.v$name);
|
||||
var t = SPRITE.sprites[name];
|
||||
t.filterBrighter();
|
||||
});
|
||||
$loc.filterOrigin = new Sk.builtin.func(function(self) {
|
||||
var name = Sk.ffi.remapToJs(self.v$name);
|
||||
var t = SPRITE.sprites[name];
|
||||
t.filterOrigin();
|
||||
});
|
||||
}, 'Sprite', []);
|
||||
|
||||
sprite.Text = Sk.misceval.buildClass(sprite, function($gbl, $loc) {
|
||||
|
||||
$loc.__init__ = new Sk.builtin.func(function(self, text, x, y, name) {
|
||||
text=Sk.ffi.remapToJs(text);
|
||||
x=Sk.ffi.remapToJs(x);
|
||||
y=Sk.ffi.remapToJs(y);
|
||||
name=Sk.ffi.remapToJs(name);
|
||||
self.v$name = Sk.ffi.remapToPy(SPRITE.CreateText(text, x, y, name));
|
||||
});
|
||||
|
||||
$loc.changeText = new Sk.builtin.func(function(self, text) {
|
||||
var name = Sk.ffi.remapToJs(self.v$name);
|
||||
text=Sk.ffi.remapToJs(text);
|
||||
var t = SPRITE.texts[name];
|
||||
t.changeText(text);
|
||||
});
|
||||
|
||||
$loc.show = new Sk.builtin.func(function(self) {
|
||||
var name = Sk.ffi.remapToJs(self.v$name);
|
||||
var t = SPRITE.texts[name];
|
||||
t.show();
|
||||
});
|
||||
|
||||
$loc.hide = new Sk.builtin.func(function(self) {
|
||||
var name = Sk.ffi.remapToJs(self.v$name);
|
||||
var t = SPRITE.texts[name];
|
||||
t.hide();
|
||||
});
|
||||
|
||||
}, 'Text', []);
|
||||
|
||||
sprite.clearAllSprites = new Sk.builtin.func(function() {
|
||||
return Sk.ffi.remapToPy(SPRITE.ClearAllSprites());
|
||||
});
|
||||
|
||||
sprite.repeat = new Sk.builtin.func(function(calc = new Function()) {
|
||||
SPRITE.Repeat(()=>{Sk.misceval.callsim(calc)});
|
||||
});
|
||||
|
||||
sprite.keyboardListener = new Sk.builtin.func(function(key, calc = new Function()) {
|
||||
key = Sk.ffi.remapToJs(key);
|
||||
SPRITE.KeyboardListener(key,()=>{Sk.misceval.callsim(calc)});
|
||||
});
|
||||
|
||||
sprite.isKeyboardHit = new Sk.builtin.func(function(keyvalue) {
|
||||
keyvalue = Sk.ffi.remapToJs(keyvalue);
|
||||
return Sk.ffi.remapToPy(SPRITE.IsKeyboardHit(keyvalue));
|
||||
});
|
||||
|
||||
sprite.getTime = new Sk.builtin.func(function() {
|
||||
return Sk.ffi.remapToPy(Math.floor(SPRITE.timer/1000));
|
||||
});
|
||||
|
||||
sprite.clearTimer = new Sk.builtin.func(function() {
|
||||
SPRITE.ClearTimer();
|
||||
});
|
||||
|
||||
return sprite;
|
||||
}
|
||||
@@ -51,114 +51,114 @@ class StatusBarImage extends PageBase {
|
||||
let canvas = null;
|
||||
let iframe = null;
|
||||
switch (data.display_type) {
|
||||
case 'p5':
|
||||
root.style.width = '100%';
|
||||
root.style.height = '100%';
|
||||
root.style.display = 'flex';
|
||||
root.style.justifyContent = 'center';
|
||||
root.style.alignItems = 'center';
|
||||
case 'p5':
|
||||
root.style.width = '100%';
|
||||
root.style.height = '100%';
|
||||
root.style.display = 'flex';
|
||||
root.style.justifyContent = 'center';
|
||||
root.style.alignItems = 'center';
|
||||
|
||||
// some canvas nodes can be added later so we observe...
|
||||
new MutationObserver(function (mutationsList) {
|
||||
mutationsList.forEach((mutation) =>
|
||||
mutation.addedNodes.forEach((node) => {
|
||||
const elem = node;
|
||||
if (
|
||||
elem.tagName != null &&
|
||||
// some canvas nodes can be added later so we observe...
|
||||
new MutationObserver(function (mutationsList) {
|
||||
mutationsList.forEach((mutation) =>
|
||||
mutation.addedNodes.forEach((node) => {
|
||||
const elem = node;
|
||||
if (
|
||||
elem.tagName != null &&
|
||||
['canvas', 'video'].includes(elem.tagName.toLowerCase())
|
||||
)
|
||||
autoFit(elem);
|
||||
})
|
||||
);
|
||||
}).observe(root, { childList: true });
|
||||
)
|
||||
autoFit(elem);
|
||||
})
|
||||
);
|
||||
}).observe(root, { childList: true });
|
||||
|
||||
root.querySelectorAll('canvas,video').forEach(autoFit);
|
||||
$content.append(root);
|
||||
break;
|
||||
case 'matplotlib':
|
||||
canvas = root.querySelector('canvas');
|
||||
if (canvas) root = canvas;
|
||||
root.style.width = '';
|
||||
root.style.height = '';
|
||||
root.style.maxWidth = '100%';
|
||||
root.style.maxHeight = '100%';
|
||||
$content.append(root);
|
||||
break;
|
||||
case 'ocaml-canvas':
|
||||
root.style.width = '';
|
||||
root.style.height = '';
|
||||
root.style.maxWidth = '100%';
|
||||
root.style.maxHeight = '100%';
|
||||
$content.append(root);
|
||||
break;
|
||||
case 'turtle':
|
||||
// Turtle result
|
||||
root.setAttribute('width', '100%');
|
||||
root.setAttribute('height', '100%');
|
||||
$content.append(root.outerHTML);
|
||||
break;
|
||||
case 'sympy':
|
||||
$content.append(data.content);
|
||||
if (typeof window.MathJax === 'undefined') {
|
||||
// dynamically loading MathJax
|
||||
console.log('Loading MathJax (Sympy expression needs it).');
|
||||
(function () {
|
||||
let script = document.createElement('script');
|
||||
script.type = 'text/javascript';
|
||||
script.src =
|
||||
root.querySelectorAll('canvas,video').forEach(autoFit);
|
||||
$content.append(root);
|
||||
break;
|
||||
case 'matplotlib':
|
||||
canvas = root.querySelector('canvas');
|
||||
if (canvas) root = canvas;
|
||||
root.style.width = '';
|
||||
root.style.height = '';
|
||||
root.style.maxWidth = '100%';
|
||||
root.style.maxHeight = '100%';
|
||||
$content.append(root);
|
||||
break;
|
||||
case 'ocaml-canvas':
|
||||
root.style.width = '';
|
||||
root.style.height = '';
|
||||
root.style.maxWidth = '100%';
|
||||
root.style.maxHeight = '100%';
|
||||
$content.append(root);
|
||||
break;
|
||||
case 'turtle':
|
||||
// Turtle result
|
||||
root.setAttribute('width', '100%');
|
||||
root.setAttribute('height', '100%');
|
||||
$content.append(root.outerHTML);
|
||||
break;
|
||||
case 'sympy':
|
||||
$content.append(data.content);
|
||||
if (typeof window.MathJax === 'undefined') {
|
||||
// dynamically loading MathJax
|
||||
console.log('Loading MathJax (Sympy expression needs it).');
|
||||
(function () {
|
||||
let script = document.createElement('script');
|
||||
script.type = 'text/javascript';
|
||||
script.src =
|
||||
'https://cdn.jsdelivr.net/npm/mathjax@3.0.5/es5/tex-mml-chtml.js';
|
||||
document.getElementsByTagName('head')[0].appendChild(script);
|
||||
})();
|
||||
} else {
|
||||
// otherwise, render it
|
||||
window.MathJax.typeset();
|
||||
}
|
||||
break;
|
||||
case 'multiple':
|
||||
/* typically dispached by display() */
|
||||
for (let mime of [
|
||||
'image/svg+xml',
|
||||
'image/png',
|
||||
'text/html',
|
||||
'text/plain',
|
||||
]) {
|
||||
if (mime in data.content) {
|
||||
let content = data.content[mime];
|
||||
if (mime === 'image/png') {
|
||||
content =
|
||||
document.getElementsByTagName('head')[0].appendChild(script);
|
||||
})();
|
||||
} else {
|
||||
// otherwise, render it
|
||||
window.MathJax.typeset();
|
||||
}
|
||||
break;
|
||||
case 'multiple':
|
||||
/* typically dispached by display() */
|
||||
for (let mime of [
|
||||
'image/svg+xml',
|
||||
'image/png',
|
||||
'text/html',
|
||||
'text/plain',
|
||||
]) {
|
||||
if (mime in data.content) {
|
||||
let content = data.content[mime];
|
||||
if (mime === 'image/png') {
|
||||
content =
|
||||
'<img src="data:image/png;base64,' +
|
||||
content +
|
||||
'" style="max-width: 100%; max-height: 100%;">';
|
||||
}
|
||||
$content.append(content);
|
||||
break;
|
||||
}
|
||||
$content.append(content);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'tutor':
|
||||
// hacky but iframe.document.body.style require to wait for
|
||||
// iframe loading
|
||||
$content.append($(data.content.replace('overflow-y%3A%20hidden%3B', '')));
|
||||
iframe = this.getContent()[0].getElementsByTagName('iframe')[0];
|
||||
if (iframe == null) return;
|
||||
// trick to avoid taking height update into account
|
||||
iframe.style.maxHeight = iframe.style.minHeight = '100%';
|
||||
break;
|
||||
case 'tutor':
|
||||
// hacky but iframe.document.body.style require to wait for
|
||||
// iframe loading
|
||||
$content.append($(data.content.replace('overflow-y%3A%20hidden%3B', '')));
|
||||
iframe = this.getContent()[0].getElementsByTagName('iframe')[0];
|
||||
if (iframe == null) return;
|
||||
// trick to avoid taking height update into account
|
||||
iframe.style.maxHeight = iframe.style.minHeight = '100%';
|
||||
|
||||
// force rendering when visible,
|
||||
// otherwise, strange things happends
|
||||
// since PythonTutor check for visibility at some point
|
||||
new IntersectionObserver((entries, observer) => {
|
||||
const entry = entries[0];
|
||||
if (entry && !entry.isIntersecting) return;
|
||||
iframe.contentWindow?.postMessage({ type: 'redraw' }, '*');
|
||||
observer.disconnect();
|
||||
}).observe(iframe);
|
||||
// force rendering when visible,
|
||||
// otherwise, strange things happends
|
||||
// since PythonTutor check for visibility at some point
|
||||
new IntersectionObserver((entries, observer) => {
|
||||
const entry = entries[0];
|
||||
if (entry && !entry.isIntersecting) return;
|
||||
iframe.contentWindow?.postMessage({ type: 'redraw' }, '*');
|
||||
observer.disconnect();
|
||||
}).observe(iframe);
|
||||
|
||||
break;
|
||||
default:
|
||||
console.error(
|
||||
`Not supported node type '${data.display_type}' in eval.display result processing.`
|
||||
);
|
||||
break;
|
||||
default:
|
||||
console.error(
|
||||
`Not supported node type '${data.display_type}' in eval.display result processing.`
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const path = require("path");
|
||||
const common = require("../../../webpack.common");
|
||||
const { merge } = require("webpack-merge");
|
||||
const path = require('path');
|
||||
const common = require('../../../webpack.common');
|
||||
const { merge } = require('webpack-merge');
|
||||
|
||||
module.exports = merge(common, {
|
||||
resolve: {
|
||||
@@ -16,7 +16,11 @@ module.exports = merge(common, {
|
||||
rules: [
|
||||
{
|
||||
test: /\.py$/,
|
||||
type: "asset/source",
|
||||
type: 'asset/source',
|
||||
}, {
|
||||
test: /\.js$/,
|
||||
resourceQuery: /url/,
|
||||
type: 'asset/resource',
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user