Skip to content

Instantly share code, notes, and snippets.

@zhangzhibin
Last active July 16, 2019 12:59
Show Gist options
  • Save zhangzhibin/c515021931cfc9adb6e9bab53b51a3c1 to your computer and use it in GitHub Desktop.
Save zhangzhibin/c515021931cfc9adb6e9bab53b51a3c1 to your computer and use it in GitHub Desktop.
A screenshot component for Cocos Creator 2.0.5 written in typescript
// https://xmanyou.com/cocos-creator-jie-tu-gong-neng-dai-ma/
// 截图组件 (如果没有提前添加Camera组件,则会自动添加一个默认参数的Camera)
// 语言:Typescript
// Cocos Creator 版本: 2.0.5
// 使用方法:
// 1. 在场景里添加一个Node, 把这个组件拖进去
// 2. 在需要截图的地方,import, 然后调用:ScreenShotNode.take()
// Screenshot component
// typescript
// Tested on Cocos Creator 2.0.5
// Usage:
// 1. add node with this component in your scene
// 2. import and call ScreenShotNode.take()
const {ccclass, property} = cc._decorator;
@ccclass
export default class ScreenShotNode extends cc.Component {
static _inst:ScreenShotNode
// LIFE-CYCLE CALLBACKS:
_camera:cc.Camera;
_texture:cc.RenderTexture;
_sprite:cc.Sprite;
// 初始化/Initialize
onLoad () {
ScreenShotNode._inst = this;
// 设置相机参数 Get/Add Camera Component
let camera = this.getComponent<cc.Camera>(cc.Camera);
if(!camera){
camera = this.addComponent<cc.Camera>(cc.Camera);
}
camera.enabled = false; // 避免自动渲染, Disable auto render
// 截图的缩放比例, Zoom ratio
let zoom = 0.5;
// 截图的尺寸,本例是640x640的正方形截图
// 如果是全屏,则为 cc.winSize.width, cc.winSize.height
// Set Screenshot size, in this case 640x640
// For full screen, use cc.winSize
let width = 640; // cc.winSize.width
let height = 640; // cc.winSize.height
let size = cc.size(width*zoom, height*zoom);
// 截图的中心点就是摄像机节点的位置
// The center of screenshot
let origin = cc.v2(0, 0);
camera.zoomRatio = zoom; // 设置缩放, set zoomRatio
// 设置目标渲染纹理
// Create and set target renderTexture for our camera
let texture = new cc.RenderTexture();
texture.initWithSize(size.width, size.height); // 截图矩形的尺寸, Size
this.node.setPosition(origin); // 截图矩形的中心点, Center Position
camera.targetTexture = texture;
// 缓存,备用
// Save for later usage
this._camera = camera;
this._texture = texture;
// 用于显示的sprite组件,如果要测试这个,需要添加sprite组件
// If you want to show screenshot on this node, add a Sprite component
this._sprite = this.getComponent<cc.Sprite>(cc.Sprite);
// var newframe = new cc.SpriteFrame(this._texture);
// this._sprite.spriteFrame = newframe;
}
shot(){
// 执行一次 render,将所渲染的内容渲染到纹理上
// Call Camera.render(<root_node>) to take a screenshot
this._camera.render(undefined);
// 到这里,截图就已经完成了
// done
// 接下去,可以从 RenderTexture 中获取数据,进行深加工
// further process with the screenshot data
let texture = this._texture;
let data = texture.readPixels();
let width = texture.width;
let height = texture.height;
// Converting to base64 data
// 转为 base64 数据
let canvas = document.createElement('canvas');
// document.body.appendChild(btn); // 没有添加到body上,不用担心内存泄漏
let ctx = canvas.getContext('2d');
canvas.width = width;
canvas.height = height;
// 1维数组转2维
// 同时做个上下翻转
let rowBytes = width * 4;
for (let row = 0; row < height; row++) {
let srow = height - 1 - row;
let imageData = ctx.createImageData(width, 1);
let start = srow*width*4;
for (let i = 0; i < rowBytes; i++) {
imageData.data[i] = data[start+i];
}
ctx.putImageData(imageData, 0, row);
}
let dataUrl = canvas.toDataURL("image/jpeg");
// 显示/Show
this.showTexture(dataUrl);
// 下载/Download
this.downloadImg(dataUrl);
// 分享到Facebook / Share to facebok
// this.shareOnFacebook(dataUrl);
}
// 显示当前截图
// 其实也可以直接用rendertexture来作为SpriteFrame的纹理
showTexture(dataUrl){
if(!this._sprite){
console.warn("Need to add a sprite component");
return;
}
var img = new Image();
img.src = dataUrl;
let self = this;
img.onload = function(){
var texture = new cc.Texture2D();
texture.initWithElement(img);
texture.handleLoadedTexture();
var newframe = new cc.SpriteFrame(texture);
self._sprite.spriteFrame = newframe;
}
}
// 下载到本地(在H5游戏里不是很实用)
downloadImg(base64:string){
//把图片生成后download到本地
var href = base64.replace(/^data:image[^;]*/, "data:image/octet-stream");
document.location.href = href;
}
// Facebook instant game的分享
shareOnFacebook(base64Url:string){
FBInstant.shareAsync({
intent: 'SHARE', // * "INVITE" | "REQUEST" | "CHALLENGE" | "SHARE"
image: base64Url,
text: 'X is asking for your help!',
data: { myReplayData: '...' },
}).then(function() {
console.info("share image done");
}).catch(e=>{
console.warn("share failed: ", e);
});
}
static take(){
ScreenShotNode._inst.shot();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment