本案例参考:http://emoji.decathlon.trustingme.cn/
但是实现方式不一样。
教程目录
一 head first
二 打开本地图片功能
三 拖拽和缩放手势,调整图片
四 gifjs工具类动态表情合成
五 demo源码下载
一 head first
显示原理
1.1 利用<input>标签打开本地图片。
1.2 FileReader读取图片,生成base64字符串给Egret显示。
1.3 Egret中利用RenderTexture截取多张表情图的base64字符串,传给gifjs工具类生成动态GIF。
二 本地图片上传
首先我们实现打开本地图片功能。微信里有图片接口,但是还得接微信jssdk。
我们这里用<input>标签实现。
1
|
< input type = "file" id = "uploadImg" > |
页面显示效果这样
<ignore_js_op>
我们把它隐藏起来,不然显示在游戏里就很丑了。
1
|
< input type = "file" id = "uploadImg" style = "display:none" / > |
我们在exml上创建一个上传按钮,ID为openFileBtn。
创建一个确认按钮,ID为okBtn。
再创建一个图片的容器。里面有3层,顶层表情遮罩图,中间放我将要上传的图片,底层放表情背景。
我们在ts里监听我要换脸按钮的点击事件,当点击“我要换脸”时,触发input标签的click事件。
这样即使我们隐藏了input标签,仍然能使用input标签的打开本地文件的功能。
1
2
3
|
var uploadImg : any = document .getElementById ( "uploadImg" ) ; uploadImg.onchange = this.onChang; uploadImg.click ( ) ; |
点击“我要换脸”,看看input标签生效了吧。手机上的效果则是让你选择打开相册。
我们选择的是彭于晏,然后用FileReader加载打开的图片,将read结果base64字符串赋值给eui.Image,这样才能把彭于晏显示在exml中。
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
private onChang ( ) { / / 获取选择图片 var uploadImg : any = document .getElementById ( "uploadImg" ) ; var file = uploadImg.files[ 0 ]; / / 判断图片类型 var imageType = / ^ image \ / / ; if ( !imageType.test ( file .type ) ) { alert ( "请选择图片类型上传" ) ; return ; } / / 加载图片 var reader = new FileReader ( ) ; reader.onload = function ( ) { window [ "homeScene" ].loadFileComplete ( reader. result ) ; } reader.readAsDataURL ( file ) ; } |
this.myImg是拖动到exml上的eui.Image组件,用来显示加载图片的。
1
2
3
4
5
6
|
/ / 加载图片完成 public loadFileComplete ( result ) { / / 将加载图片的数据赋值给myImg this.myImg.addEventListener ( egret.Event.COMPLETE , this.onMyImgComplete , this ) ; this.myImg.source = result ; } |
三 拖拽和缩放手势,调整图片
然后我们需要调整这个图片的位置和比例。
这里我自己写了2个手势。具体看源码,代码太多就不贴了。
gesturePinch
gestureDrag
上传本地图片后。
四 gifjs工具类动态表情合成
我们调整完图片后,选择“确认生成”。
将图片容器pictrueGroup截图成几张renderTexture,用于gif显示。
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
|
/ / 截取合成图 var render : egret.RenderTexture = new egret.RenderTexture ( ) ; render.drawToTexture ( this.pictureGroup , new egret.Rectangle ( 0 , 0 , 400 , 350 ) ) ; var img : eui.Image = new eui.Image ( ) ; img.texture = render; var list = []; list .push ( img.texture.toDataURL ( "image/png" ) ) ; var render 2 : egret.RenderTexture = new egret.RenderTexture ( ) ; this.imgGroup.y = 15 ; render 2. drawToTexture ( this.pictureGroup , new egret.Rectangle ( 0 , 0 , 400 , 350 ) ) ; var img 2 : eui.Image = new eui.Image ( ) ; img 2. texture = render 2 ; list .push ( img 2. texture.toDataURL ( "image/png" ) ) ; |
注:我这里表情为了省事随便调的,就把y调了一下。实际根据需求,要更换表情图,挪动彭于晏,就像摆pose拍照一样。
现在我们已经截取了两张表情图的base64字符串了,下面我们来合成gif。
先创建显示gif的<img>标签。
我们获取egret的div,这里我设置id为gameDiv。 然后在这个div下创建一个img标签,id为"gif",这个标签将会用来显示gif。
1
2
3
4
5
6
|
/ / 创建Gif var htmlImg; var gameDiv = document .getElementById ( "gameDiv" ) ; htmlImg = document .createElement ( "img" ) ; htmlImg. id = "gif" ; gameDiv.appendChild ( htmlImg ) ; |
我们把几张截图生成base64字符串数组,传递给gifjs的createGIF,这段代码会在id为"gif"的<img>标签下生成动态GIF。
createGIF写在index.html里。
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
|
< ! -- create gif --> < script src = "gifshot.min.js" > < / script > < script > function createGif ( imgList ) { var src = imgList; gifshot.createGIF ( { gifWidth : 400 , gifHeight : 350 , images : src , interval : 1.0 } , function ( obj ) { if ( !obj. error ) { var image = obj. image ; var imageDIV = document .getElementById ( 'gif' ) imageDIV.src = image ; } } ) ; } < / script > < ! -- create gif end--> |
生成的gif效果:
https://files-cdn.cnblogs.com/files/gamedaybyday/Egret3.2.6_GifExample.7z