webcam dialogs working

upd4.1
Bernat Romagosa 2017-04-11 17:51:06 +02:00
rodzic c8491c00ce
commit c9885ad5b1
3 zmienionych plików z 256 dodań i 5 usunięć

Wyświetl plik

@ -9515,7 +9515,8 @@ SymbolMorph.prototype.names = [
'arrowRight',
'arrowRightOutline',
'robot',
'magnifiyingGlass'
'magnifiyingGlass',
'camera'
];
// SymbolMorph instance creation:
@ -9687,6 +9688,8 @@ SymbolMorph.prototype.symbolCanvasColored = function (aColor) {
return this.drawSymbolRobot(canvas, aColor);
case 'magnifiyingGlass':
return this.drawSymbolMagnifyingGlass(canvas, aColor);
case 'camera':
return this.drawSymbolCamera(canvas, aColor);
default:
return canvas;
}
@ -10865,6 +10868,41 @@ SymbolMorph.prototype.drawSymbolMagnifyingGlass = function (canvas, color) {
return canvas;
};
SymbolMorph.prototype.drawSymbolCamera = function (canvas, color) {
// answer a canvas showing a camera
var ctx = canvas.getContext('2d'),
w = canvas.width,
h = canvas.width,
r = w * 0.16,
l = Math.max(w / 20, 0.5);
ctx.lineWidth = l * 2;
// camera body
ctx.fillStyle = color.toString();
ctx.beginPath();
ctx.moveTo(l, h * 5 / 6);
ctx.lineTo(w - l, h * 5 / 6);
ctx.lineTo(w - l, h / 4);
ctx.lineTo(w * 3 / 4 , h / 4);
ctx.lineTo(w * 5 / 8 , l);
ctx.lineTo(w * 3 / 8 , l);
ctx.lineTo(w / 4 , h / 4);
ctx.lineTo(l , h / 4);
ctx.closePath();
ctx.fill();
// camera lens
ctx.save();
ctx.globalCompositeOperation = 'destination-out';
ctx.beginPath();
ctx.arc(w / 2, h / 2, r, radians(0), radians(360), false);
ctx.fill();
ctx.restore();
return canvas;
};
// ColorSlotMorph //////////////////////////////////////////////////////
/*

100
gui.js
Wyświetl plik

@ -1416,6 +1416,7 @@ IDE_Morph.prototype.createCorralBar = function () {
var padding = 5,
newbutton,
paintbutton,
cambutton,
colors = [
this.groupColor,
this.frameColor.darker(50),
@ -1477,6 +1478,31 @@ IDE_Morph.prototype.createCorralBar = function () {
this.corralBar.left() + padding + newbutton.width() + padding
);
this.corralBar.add(paintbutton);
cambutton = new PushButtonMorph(
this,
"newCamSprite",
new SymbolMorph("camera", 15)
);
cambutton.corner = 12;
cambutton.color = colors[0];
cambutton.highlightColor = colors[1];
cambutton.pressColor = colors[2];
cambutton.labelMinExtent = new Point(36, 18);
cambutton.padding = 0;
cambutton.labelShadowOffset = new Point(-1, -1);
cambutton.labelShadowColor = colors[1];
cambutton.labelColor = this.buttonLabelColor;
cambutton.contrast = this.buttonContrast;
cambutton.drawNew();
cambutton.hint = "take a camera snapshot and\nimport it as a new sprite";
cambutton.fixLayout();
cambutton.setCenter(this.corralBar.center());
cambutton.setLeft(
this.corralBar.left() + padding + newbutton.width() + padding + paintbutton.width() + padding
);
this.corralBar.add(cambutton);
};
IDE_Morph.prototype.createCorral = function () {
@ -2137,6 +2163,30 @@ IDE_Morph.prototype.paintNewSprite = function () {
);
};
IDE_Morph.prototype.newCamSprite = function () {
var sprite = new SpriteMorph(this.globalVariables),
camDialog,
myself = this;
sprite.name = this.newSpriteName(sprite.name);
sprite.setCenter(this.stage.center());
this.stage.add(sprite);
this.sprites.add(sprite);
this.corral.addSprite(sprite);
this.selectSprite(sprite);
camDialog = new CamSnapshotDialogMorph(
this,
sprite,
function () { myself.removeSprite(sprite); },
function (costume) {
sprite.addCostume(costume);
sprite.wearCostume(costume);
});
camDialog.popUp(this.world());
};
IDE_Morph.prototype.duplicateSprite = function (sprite) {
var duplicate = sprite.fullCopy();
@ -7168,7 +7218,7 @@ CostumeIconMorph.prototype.removeCostume = function () {
var wardrobe = this.parentThatIsA(WardrobeMorph),
idx = this.parent.children.indexOf(this),
ide = this.parentThatIsA(IDE_Morph);
wardrobe.removeCostumeAt(idx - 2);
wardrobe.removeCostumeAt(idx - 3); // ignore the paintbrush and camera buttons
if (ide.currentSprite.costume === this.object) {
ide.currentSprite.wearCostume(null);
}
@ -7429,7 +7479,8 @@ WardrobeMorph.prototype.updateList = function () {
icon,
template,
txt,
paintbutton;
paintbutton,
cambutton;
this.changed();
oldFlag = Morph.prototype.trackChanges;
@ -7470,9 +7521,32 @@ WardrobeMorph.prototype.updateList = function () {
paintbutton.setCenter(icon.center());
paintbutton.setLeft(icon.right() + padding * 4);
this.addContents(paintbutton);
cambutton = new PushButtonMorph(
this,
"newFromCam",
new SymbolMorph("camera", 15)
);
cambutton.padding = 0;
cambutton.corner = 12;
cambutton.color = IDE_Morph.prototype.groupColor;
cambutton.highlightColor = IDE_Morph.prototype.frameColor.darker(50);
cambutton.pressColor = paintbutton.highlightColor;
cambutton.labelMinExtent = new Point(36, 18);
cambutton.labelShadowOffset = new Point(-1, -1);
cambutton.labelShadowColor = paintbutton.highlightColor;
cambutton.labelColor = TurtleIconMorph.prototype.labelColor;
cambutton.contrast = this.buttonContrast;
cambutton.drawNew();
cambutton.hint = "Import a new costume from your webcam";
cambutton.setPosition(new Point(x, y));
cambutton.fixLayout();
cambutton.setCenter(paintbutton.center());
cambutton.setLeft(paintbutton.right() + padding * 4);
this.addContents(cambutton);
txt = new TextMorph(localize(
"costumes tab help" // look up long string in translator
));
@ -7483,7 +7557,6 @@ WardrobeMorph.prototype.updateList = function () {
this.addContents(txt);
y = txt.bottom() + padding;
this.sprite.costumes.asArray().forEach(function (costume) {
template = icon = new CostumeIconMorph(costume, template);
icon.setPosition(new Point(x, y));
@ -7541,6 +7614,25 @@ WardrobeMorph.prototype.paintNew = function () {
});
};
WardrobeMorph.prototype.newFromCam = function () {
var camDialog,
ide = this.parentThatIsA(IDE_Morph),
myself = this,
sprite = this.sprite;
camDialog = new CamSnapshotDialogMorph(
ide,
sprite,
nop,
function (costume) {
sprite.addCostume(costume);
sprite.wearCostume(costume);
myself.updateList();
});
camDialog.popUp(this.world());
};
// Wardrobe drag & drop
WardrobeMorph.prototype.wantsDropOf = function (morph) {

Wyświetl plik

@ -97,6 +97,7 @@ var WatcherMorph;
var StagePrompterMorph;
var Note;
var SpriteHighlightMorph;
var CamSnapshotDialogMorph;
function isSnapObject(thing) {
return thing instanceof SpriteMorph || (thing instanceof StageMorph);
@ -8661,4 +8662,124 @@ StagePrompterMorph.prototype.mouseClickLeft = function () {
StagePrompterMorph.prototype.accept = function () {
this.isDone = true;
}
// CamSnapshotDialogMorph /////////////////////////////////////////////////////////
/*
I am a dialog morph that lets users take a snapshot using their webcam
and use it as a costume for their sprites or a background for the Stage.
*/
// CamSnapshotDialogMorph inherits from DialogBoxMorph:
CamSnapshotDialogMorph.prototype = new DialogBoxMorph();
CamSnapshotDialogMorph.prototype.constructor = CamSnapshotDialogMorph;
CamSnapshotDialogMorph.uber = DialogBoxMorph.prototype;
// CamSnapshotDialogMorph instance creation
function CamSnapshotDialogMorph(ide, sprite, onCancel, onAccept) {
this.init(ide, sprite, onCancel, onAccept);
};
CamSnapshotDialogMorph.prototype.init = function (ide, sprite, onCancel, onAccept) {
this.ide = ide;
this.sprite = sprite;
this.padding = 10;
this.oncancel = onCancel;
this.accept = onAccept;
this.videoElement = null; // an HTML5 video element
this.videoView = new Morph(); // a morph where we'll copy the video contents
CamSnapshotDialogMorph.uber.init.call(this);
this.labelString = 'Camera';
this.createLabel();
this.buildContents();
};
CamSnapshotDialogMorph.prototype.buildContents = function () {
var myself = this,
stage = this.ide.stage;
this.videoElement = document.createElement('video');
this.videoElement.hidden = true;
document.body.appendChild(this.videoElement);
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
navigator.mediaDevices.getUserMedia({ video: true })
.then(function (stream) {
myself.videoElement.src = window.URL.createObjectURL(stream);
myself.videoElement.play();
});
}
this.videoView.setExtent(this.ide.stage.dimensions);
this.videoView.image = newCanvas(this.videoView.extent());
this.videoView.drawOn = function (aCanvas) {
var context = aCanvas.getContext('2d'),
w = this.width(),
h = this.height();
context.save();
// Flip the image so it looks like a mirror
context.translate(w, 0);
context.scale(-1, 1);
context.drawImage(
myself.videoElement,
this.left() * -1,
this.top(),
w,
h
);
context.restore();
};
this.videoView.step = function () {
this.changed();
};
this.addBody(new AlignmentMorph('column', this.padding / 2));
this.body.add(this.videoView);
this.body.fixLayout();
this.addButton('ok', 'Save');
this.addButton('cancel', 'Cancel');
this.fixLayout();
this.drawNew();
};
CamSnapshotDialogMorph.prototype.ok = function () {
var stage = this.ide.stage,
canvas = newCanvas(stage.dimensions);
context = canvas.getContext('2d');
context.translate(stage.dimensions.x, 0);
context.scale(-1, 1);
context.drawImage(
this.videoElement,
0,
0,
stage.dimensions.x,
stage.dimensions.y
);
this.accept(new Costume(canvas), this.sprite.newCostumeName('camera'));
CamSnapshotDialogMorph.uber.destroy.call(this);
};
CamSnapshotDialogMorph.prototype.destroy = function () {
this.videoElement.remove();
this.oncancel.call(this);
CamSnapshotDialogMorph.uber.destroy.call(this);
};