【HTML5】使用Canvas绘制Flash导出的png序列帧,实现Flash动态效果

1.背景

现有信息系统左上角有一个swf格式的logo,是简单的文字特效类效果。由于高版本的谷歌内核浏览器不再内置Flash播放器,所以导致谷歌内核浏览器打开系统后,logo区域一片灰色,只有"该插件不受支持的提示"。

2.需求

该动态文字效果的logo在IE和谷歌内核浏览器上均能显示,并且依然保持背景透明。

3.方案

3.1 废弃方案

  1. 使用Flash导出为gif:    锯齿超级严重;
  2. 使用Flash导出为视频:无法实现背景透明;
  3. 使用Flash导出为gif,再使用PS逐帧去除锯齿:费时费力。
  4. 使用Canvas直接绘图,实现动态效果:无法实现

总结:因为gif本身格式的限制,注定了使用gif图片无法实现高清晰度的展示。而使用Canvas直接绘制,根本不可能实现flash那炫酷丝滑的效果。

3.2 完美方案

  1. 使用 Flash 把 swf 转为 png 序列图
  2. 编写 python 脚本将序列图拼接为1张 png 格式 Sprite图
  3. 使用JavaScript在Canvas中不断绘制 png 图

4.效果

该动画效果仅是在文字的表面模拟光照划过的闪光效果。制作GIF动图不方便,此处截图对比作为参考。

可以看到效果非常完美,和Flash一样的清晰流畅。

5. 实操

1. 使用Flash Profession CS6 将 SWF 导出为 PNG序列图

2. 查看导出的序列图

总共50个图,大小一致,均是 600*100(即舞台背景的大小),背景透明。

3. 编写python脚本拼接序列图

其实也可以在PS里,手动一个个拼接。写Python脚本也挺费时间。

使用该Python脚本将 50 个 600*100 的 png 拼接成一个 10行5列,大小为 3000*1000 的单一 png 图片,背景透明。

 

下面是拼接 50 张 png 的 Python3代码:

注:需使用CMD命令:pip install pillow 提前安装Python3的图形库 PIL 。关于PNG的打开和粘贴等处理不明白的可参考我之前的博文或自行搜索。

# make pngs to sprite
# 注意:我的PNG图片存放在 png_seq 文件夹内,本脚本存放在
#      与 png_seq 文件夹同级别的目录里

from PIL import Image, ImageDraw, ImageFont


# sprite 对象
sprite = Image.new(mode='RGBA', size=(3000, 1000))


line,column = 10,5		# 粘贴成 10行5列
pngw,pngh = 600,100		# 每个png图片的宽高

# create file name
def fname(i):
	if i < 10:
		return 'wh000' + str(i) + '.png'
	else:
		return 'wh00' + str(i) + '.png'

# 打开 PNG 图片序列,位置 png_seq/wh0001到wh0050.png
for x in range(1,51):	
	pngfile = 'png_seq/'+ fname(x)
	png = Image.open(pngfile).convert('RGBA')
	r,g,b,a = png.split()

	lineIndex = int( (x-1)/ 5)
	columnIndex = (x-1) % 5

	print(columnIndex)
	#粘贴的位置坐标 左上角x,y 右下角x,y
	box= (600*columnIndex, 100*lineIndex, 600*columnIndex+600, 100*lineIndex+100)
	sprite.paste(png, box, png)		#参数3是alpha通道


# 保存结果
output = 'sprite.png'
sprite.save(output, 'png', quality = 100)

4. 在html/jsp 页面编写Javascript代码绘制动画

该代码可实现:自动检测浏览器是否支持 canvas。如果支持canvas,就使用JS绘图。如果不支持,就退化为播放 Flash。

代码里面用到了一点点 JQuery 。

<!DOCTYPE html>
<html>
<head>
	<title></title>
	<script src="http://apps.bdimg.com/libs/jquery/1.9.1/jquery.min.js"></script>
</head>
<body>
	<div id="banner" >
	    <embed id="bannerSwf" src="images/logo.swf" width="600" height="100" quality="high" wmode="transparent" type="application/x-shockwave-flash"/>
	    <canvas id="bannerCanvas"></canvas>
	</div>
</body>

<script type="text/javascript">

//----banner使用Canvas绘制--开始----
$(document).ready(function(){

    //逐帧绘制Sprite
    var bannerAnimate = function(){
        var canvas = document.getElementById("bannerCanvas");
        var ctx = canvas.getContext('2d');
        canvas.width = 600;
        canvas.height = 100;
        var img = new Image();
        img.src = "sprite.png";  //加载精灵图sprite
        img.onload = function(){
            var pngNum = 0;                 //帧序号
            var colIndex = 0;   
            var lineIndex = 0;
            setInterval(function(){
                ctx.clearRect(0,0,canvas.width,canvas.height);
                lineIndex = parseInt(pngNum / 5);
                colIndex = pngNum % 5;
                ctx.drawImage(
                    img,
                    colIndex * 600,         //截取精灵图的每一帧
                    lineIndex * 100,        //截取精灵图的每一帧
                    600,
                    100,
                    0,
                    0,
                    600,
                    100
                );
                pngNum ++;
                pngNum %= 50;   //1~50循环播放
            }, 600/10)          //播放速度
        }
    };

    //检测浏览器是否支持Canvas
    try{
        document.createElement("canvas").getContext("2d");
        $('#bannerSwf').hide(); 
        $('#bannerCanvas').show();  
        bannerAnimate();            //用Canvas绘制图片帧
    }catch(e){  
        $('#bannerSwf').show();     //不支持Canvas
        $('#bannerCanvas').hide();
    }
});
//----banner使用Canvas绘制--结束----
</script>
</html>

 

 

下面是关键方法 drawImage()方法的说明。

参数

描述
img规定要使用的图像、画布或视频。
sx可选。开始剪切的 x 坐标位置。
sy可选。开始剪切的 y 坐标位置。
swidth可选。被剪切图像的宽度。
sheight可选。被剪切图像的高度。
x在画布上放置图像的 x 坐标位置。
y在画布上放置图像的 y 坐标位置。
width可选。要使用的图像的宽度。(伸展或缩小图像)
height可选。要使用的图像的高度。(伸展或缩小图像

 

全文完。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qilei2010

痛饮夏日的冰阔落

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值