cocoscreator截屏分享

背景

公司是做电商的,新年将近,运营部预模仿某宝集福卡模式出一款集福卡小游戏,由H5游戏开发人员(也就是本人)完成并提
供游戏入口链接交由运营人员配置。其中不免会涉及到分享功能,链接分享和海报分享。由于公司之前没有往app中内嵌过
H5类型小游戏,原生这边留下的图片分享是针对于H5网页的,我这边在接入截屏分享的时候则出现了白屏的情况,界面上的图像和文字资源没有截取到一点(除了调试模式下的那个VConsole绿色标志和标题)。经过两天的论坛摸索,发现原生那边的方法在截取屏幕元素时,只能截取浏览器canvas画布上的直接子元素,而通过引擎制作的各种画面元素则无法获得(原因未知)。知道了问题源头,找到如下解决方法。

解决方法

在creator构建发布后的入口index.html文件中加入如下子元素:

  <div id="shareDiv" style="display: flex;justify-content: center;align-items: center;position: fixed;top: 0;bottom: 0;right: 0;left: 0;margin: 0 auto;">
    <img id="shareImg" style="width:10px;height: 10px;" src="" />
  </div>

并在下方的function方法中隐藏该节点:

document.getElementById('shareDiv').style.display = 'none';

截图如下:
在这里插入图片描述
截图方法:

/**
     * 截屏
     * @param {*摄像机 cc.Camera类型} camera 
     */
    screenShot(camera){
        let canvas = null;
        //第一步------>给摄像机指定渲染目标 不直接渲染到屏幕上
        let texture = new cc.RenderTexture();
        texture.initWithSize(cc.visibleRect.width, cc.visibleRect.height, cc.gfx.RB_FMT_S8);
        camera.targetTexture = texture;
        //第二步----->创建并渲染画布
        let width = texture.width;
        let height = texture.height;
        if(canvas == null){
            //创建canvas
            canvas = document.createElement('canvas');
            canvas.width = width;
            canvas.height = height;
        }else{
            //清理画布上指定矩形区域内的像素
            canvas.getContext('2d').clearRect(0, 0, canvas.width, canvas.height);
        }
        //返回值 ctx 一个 CanvasRenderingContext2D 对象,使用它可以绘制到 Canvas 元素中。
        let ctx = canvas.getContext('2d');
        //手动渲染一次摄像机
        camera.render();
        //readPixels 方法 从 render texture 读取像素数据
        let data = texture.readPixels();
        //把从摄像机读取的像素 渲染到canvas画布上去
        let rowBytes = width * 4; 
        for (let row = 0; row < height; row++) {
            let srow = height - 1 - row;
            let imageData = ctx.createImageData(width, 1);//创建新的空白 ImageData 对象
            let start = srow * width * 4;
            for (let i = 0; i < rowBytes; i++) {
                imageData.data[i] = data[start + i];
            }

            ctx.putImageData(imageData, 0, row);//将图像数据拷贝回画布上
        }
        //第三步------>把画布显示在屏幕上
        document.getElementById('shareDiv').style.display = 'block';
        let shareImg = document.getElementById('shareImg');
        shareImg.style.width = '100vw';
        shareImg.style.height = '100vh';
        //toDataURL 方法 将当前画布的内容作为图像返回
        let dataURL = canvas.toDataURL('image/png');
        shareImg.src = dataURL;
        // console.log('shareImg==>', shareImg);
    },

分享后回调一定要有这一句代码:

//隐藏截屏图片
document.getElementById('shareDiv').style.display = 'none';

备注:
这个解决方法大体思想是,在要截屏的节点下面添加一个摄像机组件,要截屏的时候摄像机手动渲染一次,然后把摄取到的像素信息提取出来放入到shareImg元素中再调用原生的截屏方法去截取捕获屏幕信息,截屏分享结束后再把shareImg元素隐藏起来即可。当然,每个人遇到的情况都不一样,希望该文档对你有那么一丢丢的启发,文章内的错误理解之处欢迎指出。

Logo

这里是一个专注于游戏开发的社区,我们致力于为广大游戏爱好者提供一个良好的学习和交流平台。我们的专区包含了各大流行引擎的技术博文,涵盖了从入门到进阶的各个阶段,无论你是初学者还是资深开发者,都能在这里找到适合自己的内容。除此之外,我们还会不定期举办游戏开发相关的活动,让大家更好地交流互动。加入我们,一起探索游戏开发的奥秘吧!

更多推荐