近期折腾:使用JS以及HTML5实现鑫情动画

这篇文章发布于 2012年05月2日,星期三,22:36,归类于 JS实例。 阅读 100297 次, 今日 5 次 12 条评论

 

本文小动漫demo访问点击后面:zxx-carton-test(svg).html

一、关于鑫情动画

大学时期,因为兴趣,花了不少时间学习flash动画制作以及AS脚本。后来开发个人网站时候,一方面想自娱自乐,另一方面由于这份无法割舍的情愫,开辟了个“阳光鑫情”
的频道(目前首页即可见)。
首页的阳光鑫情栏目导航 张鑫旭-鑫空间-鑫生活

就是类似下面截图的,自己开发(播放器),自己配音,自己手绘人物、场景的轻松小动漫。
鑫情动画播放器截图 张鑫旭-鑫空间-鑫生活

要知道,这玩意很耗精力的。
首先录音:表情啊,语调啊什么的要一气呵成,所以经常因为一些瑕疵不能重来;而后音频处理:主要包括降噪,静音,长度精简等;接着手绘:要根据音频内容在flash软件上绘制合适的人物以及场景,虽然都是傻傻简单的人物造型,真正绘制起来,也要一顿饭的功夫;然后动画呈现:根据音频语句关键时间点添加合适的关键帧,制作动画,还要手动更改同步字幕。最后发布:要导出flash,在photoshop中处理截图(尺寸限制,大小优化),然后后台上传。

Adobe Audition → Adobe Flash → Adobe Photoshop

后来,工作忙了,任务重了,还要博客这块的压力,我只是个普通凡人,无法同时专注于几个事情,因此,“阳光鑫情”就让它去海南晒太阳去了。

就像男女朋友一样,即使已经分手很久了,也可能对EX念念不忘。

上周五一节前的几天,基本上没有什么活,各种x, y, z因素参杂在一起,让我突然脑中灯泡一亮——我是不是可以用HTML5实现“鑫情动画”?跑马灯式地过了遍各个环节的技术实现,发现可行。Have an idea, just do it!

花了几天时间折腾了下,还真像模像样的。

作总结有助于自我提高,同时本身具有实际应用价值,因此,分享下,顺便介绍一些HTML5小知识。

二、你也可以得瑟几个搞笑小动漫

我们做前端的心中也是有文艺情怀的,只是犹如醇厚的美酒,平时都窖藏的很深而已。

你只要略通点JS,完全可以做几个搞笑动漫,自娱自乐,一抒自己的搞笑气质和文艺情怀,哇咔咔大笑

您可以狠狠地点击这里(请使用FireFox, Chrome, Opera等浏览器访问,IE10应该也可以):HTML5搞笑小动漫demo
html5鑫情动漫demo页面截图 张鑫旭-鑫空间-鑫生活

如何使用?
首先,调用如下CSS:

<link rel="stylesheet" href="http://www.zhangxinxu.com/study/css/zxxCarton.css" type="text/css" />

然后,调用如下JS(不依赖于任何库的原生JS):

<script src="http://www.zhangxinxu.com/study/js/zxxCarton.js"></script>

最后,调用类似下面的一行脚本就可以了:

zxxCarton({ /* 动画相关数据 */ });

很简单吧!

三、兴奋吧!其实你被忽悠了~~

就像魔术一样,说穿了很简单,但是,一旦自己操作起来,就不是那么回事了。

说个最简单的,音频文件如何获取?自己录制,编辑可不是很轻松的活。除非你做无声动画(抱歉,本动画JS脚本是基于音频文件运行的),或者从网上download。即使你轻松搞到声音资源,但是考虑到不同浏览器对音频文件的支持不同,您还需要对文件做格式转换,例如从mp3格式转成ogg格式。

虽然芙蓉姐长得有点抽象,但是跟凤姐站一块,那活脱脱写实派了。同样的,虽然这里的音频处理要折腾点,但是,比起传统flash实现,要节约N多脑细胞和N多把妹时间。

拿本文演示demo举例:
我是从搜狗音乐中下载了一个“笑话”音频,然后使用Adobe Audition做了简单编辑和格式转换(直接文件另存为)。一回生两回熟,有了经验后,音频部分分分钟就可以搞定了。剩下的就是填数据了。

对了,忘说了,还有一个可能要花点时间的就是动画元件(如场景,人物,道具等)处理了。与音频文件一样,你可以自己制作,或是从网上download;或者直接使用文字作为元件。

拿本文演示demo举例:
里面的人物(包括baby)都自己用鼠标+画笔工具搞出来的,以SVG背景形式载入的。具体相关,后面介绍脚本数据的时候会介绍。

本段更多的是下点调料,重点在下一段,关于动画数据的介绍。

四、将行为以数据形式呈现

下面是难点也是重点,关于动画呈现的数据介绍。

主体参数以及结构

{
    // 动画的舞台,如果使用默认的document.body, zxCarton.js会自动创建一个id为carton_container的新舞台
    container: document.body,
    // 动画默认等待播放时候显示的主标题
    title: "标题",
    // 动画默认等待播放时显示的副标题,如果不想显示副标题,可以使用空字符串
    subtitle: "副标题",
    // 必须数据,动画音频文件
    audio: {
        // IE浏览器, Chrome
        urlMp3: "xxx.mp3",
        // Opera, FireFox
        urlOgg: "xxx.ogg"
    },
    // 舞台元件显示以及运动的数据,基于时间轴
    data: []
}

云里雾里?下面是demo页面使用数据,一看就知庐山面目了:

{
    title: "测试动画",
    subtitle: "by zhangxinxu 2012-04-26",
    audio: {
        urlMp3: "baby-marry.mp3",
        urlOgg: "baby-marry.ogg"
    },
    data: []
}

时间轴参数
下面要介绍的就是上面的data属性,其为一个基于关键时间点的对象数组(类似于时间轴)。

所谓“关键时间点”,就是一段话结束的那个时间点,或是一个镜头切换的那个时间点。一个时间点上的完整数据示例如下(绿色的注释很重要):

{
    // 当前关键时间点的时间,单位是秒,如果是0,默认播放开始时候舞台呈现的一切
    time: 0,
    // 关键字text, 表示舞台上需要呈现/隐藏(值为null)某文本元件
    text: {
        // customTextId表示文本元件的唯一id, 可随意定义,用来准确匹配舞台元素
        "customTextId": {
            // 文本元件中显示的文字(支持HTML字符)
            html: "文本文件中显示的文字",
            // 文本元件的样式控制,例如这里就是文字大小100px(数值默认单位px,下同)
            styles: {  fontSize: 100 }
        }
    },
    // 关键字shape, 表示舞台上需要呈现的图形元件(背景图片形式)
    shape: {
        // 图形元件的唯一id,只能是当前元件的背景图片地址,如果同一背景图用做多个元件,可以使用customBgUrl.svg?v=1, 2, 3, ...
        "customBgUrl.svg": {
            // 图形元件的样式控制,一般只关心高宽以及位置(动画效果)
            styles: {
                width: 300,
                height: 300
            },
            // 图形元件中的对话框内容,一般用在人物对话以及物件说明上
            dialog: {
                // direction指当前对象物体(一般为说话者)的面部朝向
                direction: "right",
                // 对话框相对于当前图片元件内部的偏移位置
                offsets: { x: 100, y: -10 },
                // 对话框中的文字内容
                word: "对话框中的文字内容"
            }
        }
    },
    // 关键时间点上的字幕
    title: "舞台下方呈现的字幕"
}

说明:无论是文字元件,或是图形元件,在下一个关键时间点(flash中的关键帧)上的时候,如果需要隐藏,则设为null;如果样式一样,可以设置对应的styles属性值为null, {}或可读性更好的"same";如果有位置和尺寸的变化,仅需要设置要变化的样式即可。

所有的元件都是绝对定位的,因此,你无需再styles中设置position属性,更多注意力放在尺寸以及位置上。

对照下面demo的实际代码再次具体分析:
先看看0秒时候:

{
    time: 0,
    text: {
        "customTextId_1": {
            html: "5个月",
            styles: {
                fontSize: 100,
                fontWeight: "bold",
                left: "50%",
                marginLeft: -125,
                top: "30%"
            }
        }
    },
    title: "结婚才5个月"
}

time: 0表示动画开始播放的第一秒舞台的呈现。只有text,表示舞台只有文本元件。"customTextId_1"表示这个文本元件的idcustomTextId_1. html: "5个月"表示文本元件里面显示的文字是“5个月”。styles就是文字的大小,位置什么的。title就是舞台同步字幕咯!
该时间点上舞台截图如下:
0秒时候的舞台呈现状态 张鑫旭-鑫空间-鑫生活

然后就是2.5秒的时候:

{
    time: 2.5,
    shape: {
        "zxx_baby_1.svg": {
            styles: {
                width: 300,
                height: 300,
                left: "30%",
                top: "25%"
            },
            dialog: null    
        }
    },
    text: {
        "customTextId_1": null    
    },
    title: "妻子就生下了一个白白胖胖的小男孩"
}

time: 2.5表示第2.5秒的时候,舞台发生一些变化。text: { "customTextId_1": null }表示在这个时间点上,idcustomTextId_1的文本元件从舞台上移除。而新增的shape表示舞台添加背景图片地址为zxx_baby_1.svg,高宽300像素,左30%, 上25%的图形元件,没有对话框内容(dialog: null)。舞台字幕变成了“妻子……小男孩”。如下图:
2.5秒时候的舞台场景截图 张鑫旭-鑫空间-鑫生活

下面就是第7秒,demo中,2.5秒→7秒是有动画的,如何实现的,如下:

{
    time: 7,
    shape: {
        "zxx_baby_1.svg": {
            styles: {
                width: 400,
                height: 400,
                left: "26%",
                top: "20%"    
            }  
        }
    },
    title: "丈夫非常地怀疑"
}

前后时间点上,同一元件同时存在,且样式有差异,即默认以动画形式呈现(动画时长为前后两个时间点的时差)。因此,你只需要关心关键时间点上:各个元件存在与否,位置如何即可。例如这里,小baby图形元件尺寸变成了400 * 400, 位置也发生了移动。

基本上,这几个时间点将80%~90%属性以及值含义介绍了,其他一些细节等对照后面几个时间点的源代码(右键demo页面→查看页面源代码)和效果应该就明白了。为了节约篇幅,后面几个时间点就不一一详述了。

五、应用到的CSS3/HTML5技术

要说HTML5的应用,这里最最重要的就是audio音频使用。应用的HTML5代码类似下面:

<audio preload="auto">
    <source src="baby-marry.mp3"></source>
    <source src="baby-marry.ogg"></source>
    <p>您的浏览器不支持<code>audio</code>元素!</p>
</audio>

多个source时候,浏览器会从上往下应用,例如FireFox浏览器,先玩玩mp3格式,发现不支持,得,继续下面一个,ogg格式,可以,就播放之~~

为了声音的播放与动画呈现同步,需要音频可以一次性播放完毕的时候在可以执行动画。因此,动画的播放控制如下(audio为标签为<audio>的音频元素):

audio.addEventListener("canplaythrough", function() {
    // 声音播放
    this.play();
    
    // 动画播放
    play();
});

而声音播放完毕的重新播放是调用的ended事件:

audio.addEventListener("ended", function () { }, false);

在本demo中,还使用了HTML5 SVG背景技术。使用SVG背景的好处在于图形元件尺寸拉伸的时候,没有位图那样的模糊或是锯齿等。本demo的SVG背景图我是在这个页面上使用画笔画下来的。关于何为SVG, SVG如何创建,如何使用等推荐参考我之前的文章:“使用SVG实现gradient背景渐变”。这里就不详细介绍了。

当然,你也可以使用普通的jpg图片作为背景图。

您可以狠狠地点击这里:jpg背景图作为图形元件动画demo
使用jpg作为图形元件背景demo 张鑫旭-鑫空间-鑫生活

最后,动画效果是使用的CSS3的transition属性,这个讲得够多的了,不多说,有兴趣可以参考我之前的“CSS3 Transitions, Transforms和Animation使用简介与应用展示”一文,讲得很详细。

六、局限、以及未来

局限很明显,就是浏览器兼容性。不过,目前看来,在手机上应用是无障碍的。

虽然这里的HTML5实现比Flash实现省了一定的功夫,但是,从实际操作的角度讲,还是麻烦了点;而且受众也小,使用者需要懂一点JS,要懂一点音频处理等。

我大胆设想了下,如果浏览器可以支持音频输入录制的话,加上科大讯飞的语言识别技术和一些其他音频分析技术。对应的时间点可以自动呈现出现,对应的字幕也直接通过语言识别呈现。然后,呈现出的是可视化的操作界面,我们所要做的就是在关键时间点上创建以及移动元件,会自动生成动画数据,一旦保存到数据库,直接就可以在线生成一个网页动漫了。按照这种设想,其实就是把Flash部分动画制作功能搬到了浏览器上,集制作,发布一体。而且,学习成本低很多。

如果这样,可以使从事艺术的,或是医学的,或是建筑的,各行各业人都能做个简单的搞笑动漫。声音录入,简单操作,保存发布! 妈妈再也不用担心我的动漫了,so easy! 你说,这种情景出现会不会加速我国动漫事业的发展呢?

呵呵,貌似有点想多了。不过,如果技术允许,这个idea做成产品还是可行的。至少目前在手机上就是可以的,手机支持声音录入,语音识别;现在不是流行你猜我画吗?再多画几张,录个音就变成搞笑动漫/文艺动漫/言情动漫/等,说不定还真会火呢?我对产品不懂,想法傻b了点,希望不要见笑。

(本篇完)

分享到:


发表评论(目前12 条评论)

  1. Apparition2018说道:

    结婚才5个月,就生下白白胖胖的。。。奉子成婚啊

  2. jeff说道:

    鑫旭兄,看了你文章受益匪浅,用你的方式我自己做了一个,不足之处还请见谅,纯粹娱乐之作!地址:http://020web.testonnet.cn/fly/index.html

  3. wmtimes说道:

    效果不错。就是有点颤抖。

  4. zrwlc2008说道:

    有点不顾忌站长面子了,不好意思呵呵,但是我是真的这么想的

  5. zrwlc2008说道:

    这个动画其实用flash两三下就搞定了,用html5来做动画还是稍显得费劲些,html5还有很多更强大的,跟flash功能不重叠的地方

  6. 亡灵说道:

    老兄,可以把你QQ留下不?(交流,学习)

  7. 锐风说道:

    刚才我看图片版本的时候, 图片没显示出来. 应该在动画开始前把图片都预先加载好.

  8. Edwardup说道:

    “加速我国动漫事业的发展”,这才是重点~
    既然有网页版的photoshop,做网页版的flash当然很值,挺好的想法的~

  9. rockyxia说道:

    顶起啊
    最多的idea可以搞

  10. 卜卜口の说道:

    这个不错哟,简单的html5动画脚本

  11. kshaw说道:

    呵呵,有意思

  12. Hao.Wu说道:

    这个画的蛮有意思。
    现在有了Adobe Edge,以前Flash的技术基础就可以搬过来用了,创作html5+js的动画简便不少。