kopia lustrzana https://github.com/backface/turtlestitch
pixel access primitives for bitmap and vector graphics
rodzic
ad96635b2e
commit
223e493316
|
@ -20,6 +20,7 @@
|
|||
* new "play sound at sample rate" command
|
||||
* accept lists and lists of lists as inputs to all sound primitives
|
||||
* new "play frequency" commands in the Sounds category
|
||||
* pixel access primitives for bitmap and vector (!) graphics
|
||||
* added "neg" selector to monadic function reporter in "Operators" category
|
||||
* added "log2" selector to monadic function reporter in "Operators" category
|
||||
* added "^" reporter (power of) in the Operators category
|
||||
|
@ -61,6 +62,9 @@
|
|||
* German
|
||||
* French
|
||||
|
||||
### 2019-04-09
|
||||
* Blocks, Objects, Threads: new "getImageAttribute" reporter primitive
|
||||
|
||||
### 2019-04-08
|
||||
* Blocks, Objects, Threads: new "getSoundAttribute" reporter primitive
|
||||
* Blocks, Objects, Threads: new "play sound at sample rate" command primitive
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
<link rel="shortcut icon" href="src/favicon.ico">
|
||||
<script type="text/javascript" src="src/morphic.js?version=2019-02-07"></script>
|
||||
<script type="text/javascript" src="src/widgets.js?version=2019-04-05"></script>
|
||||
<script type="text/javascript" src="src/blocks.js?version=2019-04-08"></script>
|
||||
<script type="text/javascript" src="src/threads.js?version=2019-04-08"></script>
|
||||
<script type="text/javascript" src="src/objects.js?version=2019-04-08"></script>
|
||||
<script type="text/javascript" src="src/blocks.js?version=2019-04-09"></script>
|
||||
<script type="text/javascript" src="src/threads.js?version=2019-04-09"></script>
|
||||
<script type="text/javascript" src="src/objects.js?version=2019-04-09"></script>
|
||||
<script type="text/javascript" src="src/gui.js?version=2019-03-25"></script>
|
||||
<script type="text/javascript" src="src/paint.js?version=2019-02-22"></script>
|
||||
<script type="text/javascript" src="src/lists.js?version=2019-02-07"></script>
|
||||
|
|
|
@ -148,7 +148,7 @@ CustomCommandBlockMorph, SymbolMorph, ToggleButtonMorph, DialMorph*/
|
|||
|
||||
// Global stuff ////////////////////////////////////////////////////////
|
||||
|
||||
modules.blocks = '2019-April-08';
|
||||
modules.blocks = '2019-April-09';
|
||||
|
||||
var SyntaxElementMorph;
|
||||
var BlockMorph;
|
||||
|
@ -1010,6 +1010,19 @@ SyntaxElementMorph.prototype.labelPart = function (spec) {
|
|||
true // read-only
|
||||
);
|
||||
break;
|
||||
case '%img': // image attributes
|
||||
part = new InputSlotMorph(
|
||||
null, // text
|
||||
false, // numeric?
|
||||
{
|
||||
'name' : ['name'],
|
||||
'width' : ['width'],
|
||||
'height' : ['height'],
|
||||
'pixels' : ['pixels']
|
||||
},
|
||||
true // read-only
|
||||
);
|
||||
break;
|
||||
case '%rate':
|
||||
part = new InputSlotMorph(
|
||||
null,
|
||||
|
|
|
@ -84,7 +84,7 @@ BlockEditorMorph, BlockDialogMorph, PrototypeHatBlockMorph, localize,
|
|||
TableMorph, TableFrameMorph, normalizeCanvas, BooleanSlotMorph, HandleMorph,
|
||||
AlignmentMorph, Process, XML_Element, VectorPaintEditorMorph*/
|
||||
|
||||
modules.objects = '2019-April-08';
|
||||
modules.objects = '2019-April-09';
|
||||
|
||||
var SpriteMorph;
|
||||
var StageMorph;
|
||||
|
@ -304,6 +304,12 @@ SpriteMorph.prototype.initBlocks = function () {
|
|||
category: 'looks',
|
||||
spec: 'costume #'
|
||||
},
|
||||
reportGetImageAttribute: {
|
||||
type: 'reporter',
|
||||
category: 'looks',
|
||||
spec: '%img of costume %cst',
|
||||
defaults: [['width']]
|
||||
},
|
||||
doSayFor: {
|
||||
only: SpriteMorph,
|
||||
type: 'command',
|
||||
|
@ -1994,6 +2000,8 @@ SpriteMorph.prototype.blockTemplates = function (category) {
|
|||
blocks.push(watcherToggle('getCostumeIdx'));
|
||||
blocks.push(block('getCostumeIdx', this.inheritsAttribute('costume #')));
|
||||
blocks.push('-');
|
||||
blocks.push(block('reportGetImageAttribute'));
|
||||
blocks.push('-');
|
||||
blocks.push(block('doSayFor'));
|
||||
blocks.push(block('bubble'));
|
||||
blocks.push(block('doThinkFor'));
|
||||
|
@ -7492,6 +7500,8 @@ StageMorph.prototype.blockTemplates = function (category) {
|
|||
blocks.push(watcherToggle('getCostumeIdx'));
|
||||
blocks.push(block('getCostumeIdx'));
|
||||
blocks.push('-');
|
||||
blocks.push(block('reportGetImageAttribute'));
|
||||
blocks.push('-');
|
||||
blocks.push(block('changeEffect'));
|
||||
blocks.push(block('setEffect'));
|
||||
blocks.push(block('clearEffects'));
|
||||
|
@ -8893,6 +8903,32 @@ Costume.prototype.thumbnail = function (extentPoint) {
|
|||
return trg;
|
||||
};
|
||||
|
||||
// Costume pixel access
|
||||
|
||||
Costume.prototype.rasterized = function () {
|
||||
return this;
|
||||
};
|
||||
|
||||
Costume.prototype.pixels = function () {
|
||||
var i,
|
||||
pixels = [],
|
||||
src = this.contents.getContext('2d').getImageData(
|
||||
0,
|
||||
0,
|
||||
this.contents.width,
|
||||
this.contents.height
|
||||
);
|
||||
for (i = 0; i < src.data.length; i += 4) {
|
||||
pixels.push(new List([
|
||||
src.data[i],
|
||||
src.data[i + 1],
|
||||
src.data[i + 2],
|
||||
src.data[i + 3]
|
||||
]));
|
||||
}
|
||||
return new List(pixels);
|
||||
};
|
||||
|
||||
// Costume catching "tainted" canvases
|
||||
|
||||
Costume.prototype.isTainted = function () {
|
||||
|
@ -9022,6 +9058,22 @@ SVG_Costume.prototype.edit = function (
|
|||
);
|
||||
};
|
||||
|
||||
// SVG_Costume pixel access
|
||||
|
||||
SVG_Costume.prototype.rasterized = function () {
|
||||
var canvas = newCanvas(this.extent(), true),
|
||||
ctx = canvas.getContext('2d'),
|
||||
rasterized;
|
||||
|
||||
ctx.drawImage(this.contents, 0, 0);
|
||||
rasterized = new Costume(
|
||||
canvas,
|
||||
this.name,
|
||||
this.rotationCenter.copy()
|
||||
);
|
||||
return rasterized;
|
||||
};
|
||||
|
||||
// CostumeEditorMorph ////////////////////////////////////////////////////////
|
||||
|
||||
// CostumeEditorMorph inherits from Morph:
|
||||
|
|
|
@ -62,7 +62,7 @@ StageMorph, SpriteMorph, StagePrompterMorph, Note, modules, isString, copy,
|
|||
isNil, WatcherMorph, List, ListWatcherMorph, alert, console, TableMorph, Color,
|
||||
TableFrameMorph, ColorSlotMorph, isSnapObject, Map*/
|
||||
|
||||
modules.threads = '2019-April-08';
|
||||
modules.threads = '2019-April-09';
|
||||
|
||||
var ThreadManager;
|
||||
var Process;
|
||||
|
@ -2291,7 +2291,7 @@ Process.prototype.doPlaySoundAtRate = function (name, rate) {
|
|||
}
|
||||
source.pause = source.stop;
|
||||
source.ended = false;
|
||||
source.onended = function () {this.ended = true; }
|
||||
source.onended = function () {this.ended = true; };
|
||||
source.start();
|
||||
rcvr.parentThatIsA(StageMorph).activeSounds.push(source);
|
||||
return source;
|
||||
|
@ -2420,7 +2420,7 @@ Process.prototype.encodeSound = function (samples, rate) {
|
|||
}
|
||||
source = ctx.createBufferSource();
|
||||
source.buffer = arrayBuffer;
|
||||
source.audioBuffer = source.buffer; // +++
|
||||
source.audioBuffer = source.buffer;
|
||||
return source;
|
||||
};
|
||||
|
||||
|
@ -4335,6 +4335,33 @@ Process.prototype.doSetInstrument = function (num) {
|
|||
}
|
||||
};
|
||||
|
||||
// Process image processing primitives
|
||||
|
||||
Process.prototype.reportGetImageAttribute = function (choice, name) {
|
||||
var cst = name instanceof Costume ? name
|
||||
: (typeof name === 'number' ?
|
||||
this.blockReceiver().costumes.at(name)
|
||||
: detect(
|
||||
this.blockReceiver().costumes.asArray(),
|
||||
function (c) {return c.name === name.toString(); }
|
||||
)
|
||||
),
|
||||
option = this.inputOption(choice);
|
||||
|
||||
switch (option) {
|
||||
case 'name':
|
||||
return cst.name;
|
||||
case 'width':
|
||||
return cst.width();
|
||||
case 'height':
|
||||
return cst.height();
|
||||
case 'pixels':
|
||||
return cst.rasterized().pixels();
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
// Process constant input options
|
||||
|
||||
Process.prototype.inputOption = function (dta) {
|
||||
|
|
Ładowanie…
Reference in New Issue