1

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

 2 years ago
source link: https://www.zhangxinxu.com/wordpress/2012/05/js-html5-zxx-carton-%e9%91%ab%e6%83%85%e5%8a%a8%e7%94%bb/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

by zhangxinxu from http://www.zhangxinxu.com
本文地址:http://www.zhangxinxu.com/wordpress/?p=2367

本文小动漫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了点,希望不要见笑。

(本篇完)1f44d.svg 是不是学到了很多?可以分享到微信
1f44a.svg 有话要说?点击这里


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK