调查:是否还有玩家的手机浏览器是只能跑 Canvas 的呢?

我也不期待后续版本能支持Canvas,反正现在版本Canvas的功能已经够用。
“想体验最新最快最酷功能的请用最新版,想继续使用Canvas的就用现有版本”,这大概就是我的心声了。
赞 -1

你确定能去掉?:innocent:

WebGL 同样支持 toDataURL,你这个需求和 Canvas 渲染模式无关。

我们的异常统计,大概还有19%的用户是因为没有webgl

1赞

好像不是没有webgl,有些是有,但是用不了,不知道为什么?,特别奇怪

webgl崩溃也会导致游戏无法使用webgl的

额,不是吧,webgl怎么用toDataURL。有相关资料么

我指的是类似烘培的功能,不是截全屏。

有些是引擎选的自动模式,自动模式下切换到 Canvas 了,其实强制用 WebGL 也问题不大

toDataURL 不就是截全屏幕吗?不然还有哪个 API?

支持今早抛弃过时的技术

1、 WebGL可以使用toDataURL,不过直接使用截出来的是黑屏,要在获取webgl的时候加preserveDrawingBuffer参数(对性能有影响)或者在cc.Director.EVENT_AFTER_DRAW事件中截图。相关链接:

2、 如果要截局部的图,目前可以使用cc.RenderTexture去截某个node及其所有子节点(有点不好用,需要一些hack代码去调整位置,据说2.0会有新的截图组件),然后:

// 以下width, height变量为局部截图的宽高
let rt = cc.RenderTexture.create(width, height, cc.Texture2D.PIXEL_FORMAT_RGBA8888, gl.DEPTH_STENCIL);
...... // 用rt截图
let texture = rt._texture._glID;
let frameBuffer = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
// 每个像素点需要rgba四个值
let data = new Uint8Array(width * height * 4);
gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, data);

// RenderTexture截出来的图是反向的,下面这段代码通过把data数组反向,来把图像反过来。
let halfHeight: number = Math.floor(height / 2);
let bytesPerRow: number = width * 4;
let temp = new Uint8Array(width * 4);
for (let y = 0; y < halfHeight; ++y) {
    let topOffset: number = Math.round(y * bytesPerRow);
    let bottomOffset = Math.round((height - y - 1) * bytesPerRow);
    temp.set(data.subarray(topOffset, topOffset + bytesPerRow));
    data.copyWithin(topOffset, bottomOffset, bottomOffset + bytesPerRow);
    data.set(temp, bottomOffset);
}
// RenderTexture截出来的图是反向的,上面这段代码通过把data数组反向,来把图像反过来。

gl.deleteFramebuffer(frameBuffer);

// 创建一个2D Canvas来保存截图结果
let canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
let context = canvas.getContext('2d');
let imageData = context.createImageData(width, height);
imageData.data.set(data);
context.putImageData(imageData, 0, 0);

// str即为截图结果
let str = canvas.toDataURL();
4赞

能提供一下相关代码吗… 谢谢了
我就是截图的时候截的是个黑的 所以用了canvas

这段代码挂在Canvas上,点击Canvas就能看到效果。

this.node.on(cc.Node.EventType.TOUCH_END, () => {
    cc.director.once(cc.Director.EVENT_AFTER_DRAW, () => {
        let canvas = document.getElementById('GameCanvas') as HTMLCanvasElement;
        let str = canvas.toDataURL();
        let img = new Image();
        img.onload = () => {
            let texture = new cc.Texture2D();
            texture.initWithElement(img);
            texture.handleLoadedTexture();
            let spriteFrame = new cc.SpriteFrame(texture);
            let spriteNode = new cc.Node();
            let sprite = spriteNode.addComponent(cc.Sprite);
            sprite.spriteFrame = spriteFrame;
            this.node.addChild(spriteNode);
            spriteNode.scale = 0.4;
        };
        img.src = str;
    });
});

多谢:kissing_heart:

我觉得可以忽略掉canvas了。就算支持了canvas又能怎么样呢?性能太差了,完全没法满足正常的需求。

支持去掉 Canvas :clap:

国产好多浏览器不支持webgl或者支持不太好,他们心里没有点逼数吗

1赞

在opp浏览器上 首次进来的时候 用webGL会启动报错 退出页面再重新进来就可以