本案例参考:http://emoji.decathlon.trustingme.cn/
但是实现方式不一样。
教程目录
一 head first
二 打开本地图片功能
三 拖拽和缩放手势,调整图片
四 gifjs工具类动态表情合成
五 demo源码下载
一 head first
显示原理
1.1 利用标签打开本地图片。
1.2 FileReader读取图片,生成base64字符串给Egret显示。
1.3 Egret中利用RenderTexture截取多张表情图的base64字符串,传给gifjs工具类生成动态GIF。
二 本地图片上传
首先我们实现打开本地图片功能。微信里有图片接口,但是还得接微信jssdk。
我们这里用标签实现。
1
|
<
input type
=
"file"
id
=
"uploadImg"
>
|
页面显示效果这样
我们把它隐藏起来,不然显示在游戏里就很丑了。
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的标签。
我们获取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"的标签下生成动态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效果:
五 demo源码下载