diff --git a/HISTORY.md b/HISTORY.md index 8d2bc068..a5199fa5 100755 --- a/HISTORY.md +++ b/HISTORY.md @@ -13,6 +13,7 @@ * new blocks for setting and changing the stage's background color * new "microphone" reporter in Sensing for getting volume, note, pitch signals and frequencies * new experimental live audio-scripting support + * new video capturing and video-motion detection support, thanks, Josep! * new "object" reporter in the Sensing category for getting a sprite by its name * blocks for changing and querying the "flat line ends" setting * selectors for changing and querying "draggable" and "rotation style" settings @@ -77,6 +78,9 @@ * German * French +### 2019-05-09 +* Blocks, Objects, Threads: tweaked new video-snap (still capture) feature + ### 2019-05-08 * Blocks, Objects, Threads: integrated video capture control into global settings prims in Sensing * Blocks, Threads: added a %self menu diff --git a/snap.html b/snap.html index 76cd9725..36e14b4b 100755 --- a/snap.html +++ b/snap.html @@ -7,8 +7,8 @@ - - + + diff --git a/src/objects.js b/src/objects.js index 04522c49..09baf1f0 100644 --- a/src/objects.js +++ b/src/objects.js @@ -84,7 +84,7 @@ BlockEditorMorph, BlockDialogMorph, PrototypeHatBlockMorph, localize, TableMorph, TableFrameMorph, normalizeCanvas, BooleanSlotMorph, HandleMorph, AlignmentMorph, Process, XML_Element, VectorPaintEditorMorph*/ -modules.objects = '2019-May-08'; +modules.objects = '2019-May-09'; var SpriteMorph; var StageMorph; @@ -1639,7 +1639,7 @@ SpriteMorph.prototype.init = function (globals) { this.cachedPropagation = false; // not to be persisted this.inheritedAttributes = []; // 'x position', 'direction', 'size' etc... - this.imageData = {}; // version: date, pixels: Uint32Array, canvas: Canvas + this.imageData = {}; // version: date, pixels: Uint32Array this.motionAmount = 0; this.motionDirection = 0; this.frameNumber = 0; @@ -1929,7 +1929,7 @@ SpriteMorph.prototype.colorFiltered = function (aColor) { return morph; }; -SpriteMorph.prototype.getImageData = function (asCanvas) { +SpriteMorph.prototype.getImageData = function () { // used for video motion detection. // Get sprite image data scaled to 1 an converted to ABGR array, // cache to reduce GC load @@ -1954,24 +1954,33 @@ SpriteMorph.prototype.getImageData = function (asCanvas) { .getImageData(0, 0, newExtent.x, newExtent.y).data; this.imageData = { version : this.version, - pixels : new Uint32Array(imageData.buffer.slice(0)), - canvas : canvas + pixels : new Uint32Array(imageData.buffer.slice(0)) }; } - return asCanvas ? this.imageData.canvas : this.imageData.pixels; + return this.imageData.pixels; }; SpriteMorph.prototype.videoSnap = function() { var stage = this.parentThatIsA(StageMorph), - img = this.getImageData(true), - offset = this.position().subtract(stage.position()) + center = this.center().subtract(stage.position()) .divideBy(stage.scale), - snap = newCanvas(new Point(img.width, img.height), true), - ctx = snap.getContext('2d'); + cst = this.costume || this.image, + offset, + snap, + ctx; + if (cst instanceof Costume) { + cst = cst.contents; + } + offset = new Point( + Math.floor(center.x - (cst.width / 2)), + Math.floor(center.y - (cst.height / 2)) + ); + snap = newCanvas(new Point(cst.width, cst.height), true); + ctx = snap.getContext('2d'); ctx.drawImage(stage.videoLayer(), -offset.x, -offset.y); ctx.globalCompositeOperation = 'destination-atop'; - ctx.drawImage(img, 0, 0); + ctx.drawImage(cst, 0, 0); return new Costume(snap, this.newCostumeName(localize('snap'))); }; diff --git a/src/threads.js b/src/threads.js index 711f85b6..8da64b82 100644 --- a/src/threads.js +++ b/src/threads.js @@ -61,7 +61,7 @@ StageMorph, SpriteMorph, StagePrompterMorph, Note, modules, isString, copy, isNil, WatcherMorph, List, ListWatcherMorph, alert, console, TableMorph, Color, TableFrameMorph, ColorSlotMorph, isSnapObject, Map, newCanvas, Symbol*/ -modules.threads = '2019-May-08'; +modules.threads = '2019-May-09'; var ThreadManager; var Process;