Scratch3.0——作品截图

Posted 帷幄庸者

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Scratch3.0——作品截图相关的知识,希望对你有一定的参考价值。

Scratch 的舞台是基于canvas,最初尝试直接通过canvas的dom,然后生成图片,但最后只能得到一个黑色的图片,得到黑色图片的原因是没有取到有效的canvas而不是因为图片跨域,当初在这里走了很多弯路,继续研究舞台组件stage.jsx,从vm.renderer可以获取canvas,于是通过这个canvas对象生成图片,记得当时的效果是偶尔会得到有效图片,但是大部分时候依然是黑色的图片,原因稍后回解释。为了实现截图,当时又进一步研究了renderer的代码,最后找到了draw方法,通过多次尝试发现在draw方法的最后执行canvas对象生成图片可以获得舞台的有效图片

最初的笨办法

在node_modules中找到scratch-render/src/RenderWebGL.js中的draw方法,也可以直接在dist中修改编译后的文件。顺便解释一下draw是对舞台进行了清理和重新绘制,而draw的频率非常频繁,因此不能直接通过canvas获取图片。在重绘后追加获取图片的toDataURL方法,考虑到需要在gui里面调用,此处采用了监听键盘事件来通信,接收到截图请求将舞台图片放在window.sessionStorage内存中,在需要使用的时候可以直接从sessionStorage获得。

 draw () {
        this._doExitDrawRegion();
		// 获取gl
        const gl = this._gl;
		// 
        twgl.bindFramebufferInfo(gl, null);
        gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
        gl.clearColor.apply(gl, this._backgroundColor);
        gl.clear(gl.COLOR_BUFFER_BIT);
		// 重新绘制
        this._drawThese(this._drawList, ShaderManager.DRAW_MODE.default, this._projection);
        // 增加如下代码
        let img = new Image();
        img.src = gl.canvas.toDataURL('image/png',0.7)
        document.onkeydown = function (e) {
            if(e.keyCode == 16){
                window.sessionStorage.setItem("coverImg",img.src)
                console.log('webGL')
            }
        }
    }

带来问题

  1. 直接修改node_modules依赖的内容,严重影响团队开发、项目部署,提升了项目维护的复杂度。
  2. 每次draw都会执行toDataURL方法,并且赋值,增大了系统开销。
  3. 通过事件映射,提升了项目的复杂度。

优化

回归最初问题的本源,不能直接从canvas.toDataURL获得舞台截图的原因是执行toDataURL的时候可能正好draw在重绘。因此先截图前先draw然后获取图片。

this.renderer.draw();
const img = new Image();
img.src = this.canvas.toDataURL('image/png', 0.7);

你可以从container/stage.jsx中拿到当前舞台的renderer,最后提供方法供其他组件调用,在有vm的地方也可以通过vm.renderer拿到renderer

码猿Scratch学习平台:https://scratch.imayuan.com

以上是关于Scratch3.0——作品截图的主要内容,如果未能解决你的问题,请参考以下文章

scratch3.0教程2.2 魔力手环

Scratch3.0——克隆代码仓库的正确姿势

scratch3.0如何设置为不可以修改

Scratch3自定义积木块之新增积木块

移动记账-作品展示(视频,截图)

使用scratch3.0制作《礼佛大忏悔文》播放器及视频