码丁实验室,一站式儿童编程学习产品,寻地方代理合作共赢,微信联系:leon121393608。
前言
在前一篇文章中,我们开发了一个Scratch-vm架构的Scratch 3.0 Extension。当时我们提到,scratch-vm架构下的Extension脚本在初始化时可以接收runtime这个物件,并透过runtime物件与scratch底层进行沟通,所以可以完成更为复杂的功能。在这篇文章中,我将利用runtime物件来实作具备拍照功能的积木。
安装Preview 版Scratch 3.0
这个范例同样需要安装Node.js、Git、 scratch-gui与scratch-vm,详细步骤请前一篇文章。
加入 Extension
为了简化说明,在这个范例中我将直接把Extension 脚本放在本机的目录下。不过比较建议的做法还是应该使用Github 或类似的服务来做脚本的管控。
- 利用档案总管在C:\Scratch3\scratch-vm\src\extensions 下建立目录scratch3_camera。
- 在scratch3_camera 目录中新增档案index.js,内容如下:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869constBlockType=require(‘../../extension-support/block-type’);constJpegCoder=require(‘jpeg-js’);classScratch3CameraBlocks{constructor(runtime){this.runtime=runtime;}getInfo(){this.runtime.ioDevices.video.enableVideo();return{id:‘camera’,name:‘Camera’,blocks:[{opcode:'takePicture',blockType:BlockType.COMMAND,text:'Take a picture from webcam',},{opcode:'videoOn',blockType:BlockType.COMMAND,text:'Turn webcam on',},{opcode:'videoOff',blockType:BlockType.COMMAND,text:'Turn webcam off',}],}}takePicture(){varframe=this.runtime.ioDevices.video.getFrame({format:“image-data”,dimensions:[800,600]});if(frame){varjpegImageData=JpegCoder.encode(frame,90);varsaveByteArray=(function(){vara=document.createElement(“a”);document.body.appendChild(a);a.style=“display: none”;returnfunction(data,name){varblob=newBlob([newUint8Array(data)],{type:“application/octet-stream”});varurl=window.URL.createObjectURL(blob);a.href=url;a.download=name;a.click();window.URL.revokeObjectURL(url);};}());saveByteArray(jpegImageData.data,‘webcam.jpg’);}}videoOn(){this.runtime.ioDevices.video.enableVideo();}videoOff(){this.runtime.ioDevices.video.disableVideo();}}module.exports=Scratch3CameraBlocks;
Scratch3CameraBlocks 物件在初始化时接受runtime 物件,并储存在runtime 变数中(第6 行)。这个Extension 共定义了三个积木,opcode 分别是takePicture (第16 行)、videoOn (第21 行) 与videoOff (第26 行)。videoOn 与videoOff 分别利用runtime 物件的ioDevices.video 来控制webcam 的开启与关闭。takePicture 则利用ioDevices.video 的getFrame 来取得画面的影像,不过因为浏览器并不支援直接存档的功能,所以程式使用动态产生html 下载连结的方式来下载抓取到的影像资料(第42~54 行)。
- 修改档案C:\Scratch3\scratch-vm\src\extension-support\extension-manager.js,将
123456789101112constScratch3SpeechBlocks=require(‘../extensions/scratch3_speech’);constbuiltinExtensions={pen:Scratch3PenBlocks,wedo2:Scratch3WeDo2Blocks,music:Scratch3MusicBlocks,microbit:Scratch3MicroBitBlocks,speak:Scratch3SpeakBlocks,translate:Scratch3TranslateBlocks,videoSensing:Scratch3VideoSensingBlocks,speech:Scratch3SpeechBlocks};
修改为
1234567891011121314constScratch3SpeechBlocks=require(‘../extensions/scratch3_speech’);constScratch3CameraBlocks=require(‘../extensions/scratch3_camera’);constbuiltinExtensions={pen:Scratch3PenBlocks,wedo2:Scratch3WeDo2Blocks,music:Scratch3MusicBlocks,microbit:Scratch3MicroBitBlocks,speak:Scratch3SpeakBlocks,translate:Scratch3TranslateBlocks,videoSensing:Scratch3VideoSensingBlocks,speech:Scratch3SpeechBlocks,camera:Scratch3CameraBlocks}; - 选择一张用来作为Extension 选择页面的代表图片,并放置到目录C:\Scratch3\scratch-gui\src\lib\libraries\extensions 下。
- 修改档案C:\Scratch3\scratch-gui\src\lib\libraries\extensions\index.js,在
1import translateImage from‘./translate.png’;
下方加上
1import cameraImage from‘./webcam.png’;其中webcam.png 需改成你所使用的图片名称。此外,需将
12345678{name:‘LEGO Boost’,extensionId:‘boost’,iconURL:boostImage,description:‘Build with motors and sensors.’,featured:true,disabled:true}改为
123456789101112131415{name:‘LEGO Boost’,extensionId:‘boost’,iconURL:boostImage,description:‘Build with motors and sensors.’,featured:true,disabled:true},{name:‘Camera’,extensionId:‘camera’,iconURL:cameraImage,description:‘Camera (DEMO)’,featured:true}
测试Extension
- 回到浏览器,此时应该会重新出现欢迎画面,再次点选Try It! 进入Scratch 3.0 的编辑页面。
- 点选左下方图示开启Extension 选择页面。
- 拉到最下方应该可以看到我们新增的Extension,而显示的图示则会是你之前复制到 C:\Scratch3\scratch-gui\src\lib\libraries\extensions 这个目录下的图片。点选这个图示就可以载入我们新增的Extension。
- 载入成功后可以看到左边下方出现Camera 的选项,包含三个积木、分别是Turn webcam on、Turn webcam off 与 Take a picture from webcam。
- 此Extension 在载入时会自动开启webcam。积木Turn webcam off 可以用来关闭webcam,积木Turn webcam on 则用来开启webcam,至于积木Take a picture from webcam 则会拍摄一张解析度为800×600 的照片并下载成为图档webcam.jpg。需要特别注意的是必须在webcam 开启的状态下才能顺利拍摄照片。
在这个范例中,我们利用scratch-vm的runtime物件来控制webcam的功能。除了控制IO元件外,runtime物件还可以用来与scratch本身进行复杂的互动。更为完整的资讯请参考runtime.js程式码。