截图是游戏中非常常见的一个功能,在cocos中可以通过摄像机和RenderTexture可以快速实现一个截图功能,具体API可参考:https://docs.cocos.com/creator/manual/zh/render/camera.html?h=%E6%88%AA%E5%9B%BE,其中官方也提供了比较完整的例子。
实际上不用官网提供的全屏截图的例子,一般在网页中我们也能将页面截图保存,比如通过htmltocanvas,cocos开发的小游戏在网页中打开实际就是一个canvas,前端是可以通过将canvas保存为图片的,这里就不细说了。
我们还是来看下如何把屏幕中某一区域的内容生成图片并保存到本地。
1、创建RenderTexture
//新建一个RenderTexture,并且设置camera的targetTexture为新建的RenderTexture,这样camera的内容将会渲染到新建的RenderTexture中。
lettexture=newcc.RenderTexture();
letgl=cc.game._renderContext;
//如果截图中不含mask组件可以不加第三个参数,不过建议加上
texture.initWithSize(this.node.width,this.node.height,gl.STENCIL_INDEX8);//这里的宽高直接决定了截图的宽高,如果是全屏截图就是cc.visibleRect.width,cc.visibleRect.height,该处可以设置为截图目标区域的宽高
this.camera=this.node.addComponent(cc.Camera);this.camera.targetTexture=texture;this.texture=texture;
2、绘制canvas
createSprite(){
letwidth=this.texture.width;
letheight=this.texture.height;
//截图的本质是创建一个canvas,然后通过canvas生成图片材质
if(!this._canvas){
this._canvas=document.createElement('canvas');
this._canvas.width=width;
this._canvas.height=height;
}else{
this.clearCanvas();
}
letctx=this._canvas.getContext('2d');
this.camera.render();//相机绘制,将屏幕上的内容更新到renderTexture中
letdata=this.texture.readPixels();//读取renderTexture中的数据
letrowBytes=width*4;
for(letrow=0;row<height;row++){
letsrow=height-1-row;
letimageData=ctx.createImageData(width,1);
letstart=srow*width*4;
for(leti=0;i<rowBytes;i++){
imageData.data[i]=data[start+i];
}
ctx.putImageData(imageData,0,row);
}
returnthis._canvas;
},
上述代码中用到了canvas的createImageData()和putImageData()方法,createImageData()方法创建新的空白ImageData对象,putImageData()方法将图像数据(从指定的ImageData对象)放回画布上。
3、获取图片
initImage(img){
//returnthetypeanddataUrl
vardataURL=this._canvas.toDataURL("image/png");
varimg=document.createElement("img");
img.src=dataURL;
returnimg;
},
生成canvas就可以通过canvas.toDataURL()方法将canvas转换为图片
4、生成截图效果,将上一步生成的图片当做材质挂载到新建的node
showSprite(img){
lety=this.getTargetArea().y;
letx=this.getTargetArea().x;
letrect=newcc.Rect(x,y,770,800)
lettexture=newcc.Texture2D();
texture.initWithElement(img);
letspriteFrame=newcc.SpriteFrame();
spriteFrame.setTexture(texture);
spriteFrame.setRect(rect)
letnode=newcc.Node();
letsprite=node.addComponent(cc.Sprite);
sprite.spriteFrame=spriteFrame;
node.zIndex=cc.macro.MAX_ZINDEX;
node.parent=cc.director.getScene();
//setposition
letwidth=cc.winSize.width;
letheight=cc.winSize.height;
node.x=width/2;
node.y=height/2;
node.on(cc.Node.EventType.TOUCH_START,()=>{
node.parent=null;
node.destroy();
});
this.captureAction(node,width,height);
},
5、截图动画(类似手机截图,截图后有个缩略图动画)
captureAction(capture,width,height){
letscaleAction=cc.scaleTo(1,0.3);
lettargetPos=cc.v2(width-width/6,height/4);
letmoveAction=cc.moveTo(1,targetPos);
letspawn=cc.spawn(scaleAction,moveAction);
letfinished=cc.callFunc(()=>{
capture.destroy();
})
letaction=cc.sequence(spawn,finished);
capture.runAction(action);
},
6、下载图片到本地,动态生成a标签,模拟点击后移除
downloadImg(){
this.createSprite();
varimg=this.initImage();
this.showSprite(img)
vardataURL=this._canvas.toDataURL("image/png")
vara=document.createElement("a")
a.href=dataURL;
a.download="image";
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
},
完整代码如下:
cc.Class({
extends:cc.Component,
properties:{
_canvas:null,
targetNode:cc.Node
},
onLoad(){
this.init();
},
init(){
lettexture=newcc.RenderTexture();
letgl=cc.game._renderContext;
texture.initWithSize(this.node.width,this.node.height,gl.STENCIL_INDEX8);
this.camera=this.node.addComponent(cc.Camera);
this.camera.targetTexture=texture;
this.texture=texture;
},
//createtheimgelement
initImage(img){
//returnthetypeanddataUrl
vardataURL=this._canvas.toDataURL("image/png");
varimg=document.createElement("img");
img.src=dataURL;
returnimg;
},
//createthecanvasandcontext,filpYtheimageData
createSprite(){
letwidth=this.texture.width;
letheight=this.texture.height;
if(!this._canvas){
this._canvas=document.createElement('canvas');
this._canvas.width=width;
this._canvas.height=height;
}else{
this.clearCanvas();
}
letctx=this._canvas.getContext('2d');
this.camera.render();
letdata=this.texture.readPixels();
//writetherenderdata
letrowBytes=width*4;
for(letrow=0;row<height;row++){
letsrow=height-1-row;
letimageData=ctx.createImageData(width,1);
letstart=srow*width*4;
for(leti=0;i<rowBytes;i++){
imageData.data[i]=data[start+i];
}
ctx.putImageData(imageData,0,row);
}
returnthis._canvas;
},
getTargetArea(){
lettargetPos=this.targetNode.convertToWorldSpaceAR(cc.v2(0,0))
lety=cc.winSize.height-targetPos.y-this.targetNode.height/2;
letx=cc.winSize.width-targetPos.x-this.targetNode.width/2;
return{
x,
y
}
},
downloadImg(){
this.createSprite();
varimg=this.initImage();
this.showSprite(img)
vardataURL=this._canvas.toDataURL("image/png")
vara=document.createElement("a")
a.href=dataURL;
a.download="image";
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
},
//showonthecanvas
showSprite(img){
lety=this.getTargetArea().y;
letx=this.getTargetArea().x;
letrect=newcc.Rect(x,y,770,800)
lettexture=newcc.Texture2D();
texture.initWithElement(img);
letspriteFrame=newcc.SpriteFrame();
spriteFrame.setTexture(texture);
spriteFrame.setRect(rect)
letnode=newcc.Node();
letsprite=node.addComponent(cc.Sprite);
sprite.spriteFrame=spriteFrame;
node.zIndex=cc.macro.MAX_ZINDEX;
node.parent=cc.director.getScene();
//setposition
letwidth=cc.winSize.width;
letheight=cc.winSize.height;
node.x=width/2;
node.y=height/2;
node.on(cc.Node.EventType.TOUCH_START,()=>{
node.parent=null;
node.destroy();
});
this.captureAction(node,width,height);
},
//spriteaction
captureAction(capture,width,height){
letscaleAction=cc.scaleTo(1,0.3);
lettargetPos=cc.v2(width-width/6,height/4);
letmoveAction=cc.moveTo(1,targetPos);
letspawn=cc.spawn(scaleAction,moveAction);
letfinished=cc.callFunc(()=>{
capture.destroy();
})
letaction=cc.sequence(spawn,finished);
capture.runAction(action);
},
clearCanvas(){
letctx=this._canvas.getContext('2d');
ctx.clearRect(0,0,this._canvas.width,this._canvas.height);
}
});
如需转载,请注明文章出处和来源网址:http://www.divcss5.com/html/h56595.shtml