郭轶君
(江苏电视台 新闻中心,南京 210008)
在线包装系统是一种新型的电视包装手段,2000左右年进入中国,但在欧美各国这项技术早已全面应用,即使在东南亚各国也早已具备多年的成熟应用经验。
目前世界上得到业界认可的有两家大型在线包装品牌,vizrt与奥威。下文以vizrt为例,阐述在对vizrt 本身运行机制的深入理解的基础上,进行交互性开发的应用与研究,满足更为广泛的包装需求。
触摸是主持人与设计师所设计的场景最直接交互方式,也是在线包装交互性最外在的体现,那么如何实现这样一个更为直观的交互效果,其实思路与如何让Operator(在线操控人员)更灵活地控制场景是同样的道理,下面就来逐步讲解本文的制作思路。
该触摸屏是江苏电视台购买vizrt以来第一次在大型直播中应用,也是本人第一次进行触摸屏开发。由图1-5可以看出,该触摸场景共分为5个板块,分别由红色方块标出的五个图标控制。当按下任意图标将由当前场景切换为目标场景。如初始界面为315直播的logo,当按下第三个图标,logo将动画下场,同时微博将依次划入画面。在脚本中我们通过调用切换逻辑实现任意两个状态无缝动画转换。
图1 3.15大型直播,触摸大屏起始界面
图2 3.15大型直播,触摸大屏视频连线界面
图3 3.15大型直播,触摸大屏微博互动界面
图4 3.15大型直播,触摸大屏图片浏览界面
图5 3.15大型直播,触摸大屏饼状统计图界面
按照设计需求将trio中切换逻辑的思想转移到触摸场景中来为我而用。通过到了这样一个命令(MAIN_SCENE*STAGE*DIRECTOR*$logic GOTO_TRIO $" & startpos & " $" & newState)可以模拟切换逻辑中不同状态之间的转换动画,其中startpos newState为可以理解为当前需要切换的两组动画状态名称,当此命令执行,时间线将在director:logic中的两个stop点:startpos 向 newState播放,这样便实现了所需要展现的效果。
在场景脚本中创建这样一个函数:
dim startpos as string
Sub transitionTo(newState as String)
startpos = scene.findContainer("aaa").geometry.text
SendCommand("MAIN_SCENE*STAGE*DIRECTOR*$logic GOTO_TRIO $" & startpos & " $" & newState)
End Sub
由于在实际交互过程中,我们需要确定当前触摸屏处于哪个状态,所以变量startpos用来代表当前的状态名称即当前动画中stop点的名称。而我们将要切换到的状态则由所点击的图标来表明,所以只要在相应的图标代码中调用该函数即可以获得该数据,这个函数所要解决的最后一个问题就是如何获取当前状态变量。回想切换逻辑的原理,其实我们只需要当时间线播放到某一个状态时通过命令来表明此时的状态即可,那么将这个命令写在与stop点位置一致的命令关键帧上即可,如图6。
图6
如图7中我以第一个stop点为例标出了命令设置datapool state为O这样Data Text Pluging将这个由viz conmmand传递来的数据直接输入到文字插件中,于是场景中的文字就变成了临时存储当前状态变量的容器。startpos = scene.findContainer("aaa").geometry.text将读取此时的文字数据。
图7
其余stop点内的命令关键帧填写的内容于此类似。按照换逻辑的思想,各个状态点之间的转换动画需手动制作,依照图6所示设定这5个状态点,保证两任意状态直接相连。之后,在五个图标中分别调用transitionTo(newState as String)这个函数,这样当按下任意按钮图标无论当前状态是什么,都将通过go to trio的命令驱动当前状态与目标状态之间的动画发生。
微博板块将要实现的是在上下拖拽微博版的时候每当其中一个字幕条到达一定的区域内就自动跳出,当离开这个区域时自动跳回。首先为每个字幕条制作了跳出动画(所有字幕条都在同一个父层级之下,这样保证了所有的字幕条拥有共同的相对坐标系),经过测试为四个字幕条分别确定了5个区间。(-30,30)(-230,-80)(60,120)(120,230)
sub gotodetail()
stage.finddirector("a").reverse=false
stage.finddirector("a").continueanimation()
end sub
以上代码用来控制弹出动画的正向播放。
sub gotodetail_reverse()
stage.finddirector("a").reverse=true
stage.finddirector("a").continueanimation()
end sub
用来控制弹出动画的逆向播放。
由于在弹出动画的开始与结束位置设定了stop点。所以动画不会在范围内不停的循环正向播放,或逆向播放。
当按下鼠标,程序将记录此时按点的坐标值与当前微博的坐标值,用来计算拖拽结束后的相对位移。
sub OnButtonDown6DOF(button as Integer,pos as vertex,rot as vertex)
pos_Down=pos.y
pos_Ini=position.y
end sub
当开始拖拽的时候,微博的坐标会相应的发生变化position.y=pos_Ini+(pos.y-pos_Down)*0.78接下来利用之前测试好的区间,通过逻辑判断可以激活各个字幕条的弹出动画。
以第一条为例
if position.y < 30 and position.y>-30 then
gotodetail()
else
gotodetail_reverse()
end if
当手离开屏幕,微博板块将继续滑动一段距离,模拟物体的惯性。为此我们将定义一段微博的整体位移动画GX。通过函数sub GX()修改该动画的关键帧来模拟这样的效果。起始关键帧将设置为微博板的当前坐标,并通过move函数取得的变量数据diff=pos.y-pos_Down
判断手指离开屏幕微博应该往哪个方向继续飘动。
sub GX()
dim GX as director=stage.finddirector("GX")
GX.FindKeyframe("O").xyzvalue=position.xyz
if diff<0 then
GX.FindKeyframe("IN").xyzvalue=cvertex(position.x,position.y-12,position.z)
else
GX.FindKeyframe("IN").xyzvalue=cvertex(position.x,position.y+12,position.z)
end if
GX.startanimation()
end sub
最后在 OnButtonUp6DOF中调用函数GX
sub OnButtonUp6DOF(button as Integer,pos as vertex,rot as vertex)
if system.mousex <500 then
GX()
end if
end sub
视窗交互算法将要实现的效果是:三个视窗可以被同时拖动,在松开后自动滑动返回起始位置,每个视窗可以单独弹出、弹入,三个视窗拖动并弹回效果与微博拖动算法类似。下面讲解点击效果,当点击一次视窗,视窗弹出,再次点击视窗收回,这里有两种方法可以用来实现这样的效果。
1)通过逻辑判断,设置一个布尔变量out,当out为真代表视窗弹出,当out为假表示视窗收回。 在场景脚本文件中建立这样两个函数来设置并返回视窗此时的状态。
sub setout (boolean b)
out =b
end sub
Function getout
getout=out
End Function
为视窗制作一段弹出动画 direcort VIDIO。
在开始处写入命令 THIS_SCENE*SCRIPT*INVOKE setout false;
在结尾处写入命令 THIS_SCENE*SCRIPT*INVOKE setout true;
在包含视窗的Container中编写脚本:
Dim out as boolean
Sub OnLbuttonDown()
out=scene.script..getout
If out=false then
Scene.stage.finddirector.(“VIDIO”).reverse=false
Scnene.stage.finddirecor(“VIDIO”).startanimation()
else if out=true then
Scene.stage.finddirector(“VIDIO”).reverse=true
Scene.stage.finddirector(“VIDIO”).startanimation()
End sub
2)在动画VIDIO上制作三个关键帧分别为起点位置,弹出位置并且记录一个stop点,第三个位置记录起点位置关键帧与action关键帧写入命令THIS_SCENE*STAGE*DIRECTOR*VIDIO SHOW 0.0;这样当动画开始播放,点一次时候由起点位置弹出并停止,继续点击将向第三个关键帧播放,回到了起始位置,同时利用命令action,将时间线也回零。
这样只要始终CONTINUE ANIMATION 就可以保证两次点击的效果。在VIDIO上写入程序
sub OnLButtonDown()
dim va as string
va =“VIDIO”
Stage.finddirector("VIDIO").reverse=false
stage.finddirector(va).continueanimation()
end sub
当松开手指时候,微博版式将产生动态的移动效果,当手指滑动速度快时,微博版应该产生更大的惯性继续移动比较远的距离,反之亦然。
取得系统的时间数据通过回调函数
sub OnExecPerField()
if push == false then
exit sub
else
frame=frame+1
text=cstr(frame)
dim con as container
con = Scene.FindContainer("text").GetChildContainerByIndex(0)
con.Geometry.Text=text
end if
end sub
该回调函数逐场执行程序,通过变量push对手指按下的时间进行判断,frame将存储时间值。当手指松开,在函数OnButtonUP6DOF()中,
sub OnButtonUP6DOF(button as Integer,pos as vertex,rot as vertex)
DF = pos.y-pos_Down
GX()
frame=0
end sub
所调用的GX()中将push设置为假。
con = Scene.FindContainer("text").GetChildContainerByIndex(0)
con.Geometry.Text=text
该段代码将场数返回给Text插件,显示在场景中,指示手指按下的时间。
GX()将在手松开时,调用一段动画(该动画需要时间设置在某一个director之中)并修改其关键帧。
sub GX()
dim V as double
push=false
'速度系数
V=abs(DF/(frame))+1
if V>=130 then
V=130
end if
dim GX as director=stage.finddirector("GX")
GX.FindKeyframe("O").xyzvalue=position.xyz
if DF<0 then
GX.FindKeyframe("IN").xyzvalue=cvertex(position.x,position.y-23*V,position.z)
else
if DF>0 then
GX.FindKeyframe("IN").xyzvalue=cvertex(position.x,position.y+23*V,position.z)
end if
end if
GX.startanimation()
end sub
设置速度系数V是为了使得版式在松手之后合理的运动,DF/frame模拟了手指运动的平均速度。+1是为了控制之后关键帧的合理值否则将运动过快。DF存储了手指的移动数值,该数值通过正负符号来判断手指是向上还是向下运动,并在确定方向之后合理的运用与时间相关的速度系数V进行简单的运算得到末尾关键帧属性,向下运动将减去一定的数值position.y-23*V,确保按照相应的速度继续沿下运动一段距离,反之position.y+23*V将模拟手指向上滑动产生的惯性效果。当GX()计算完成,在开始下一次触摸之前,我们需要将计算过的时间值回零,frame=0。
最后实现的效果是饼状图交互,这个交互效果设计的比较简单,我们只是通过移动手指使得饼状图形绕Y轴绕行。
这里我们需要通过手指按下的坐标、手指滑动的坐标的插值来计算图形ROTATEY的值。
sub OnButtonDown6DOF(Button as Integer,pos as vertex,rot as vertex)
Init_rot=Scene.findcontainer(“PI”).rotation.y
mouseDown = pos.x
end sub
首先取得饼图的初始y轴旋转值,Init_rot=Scene.findcontainer("PI").rotation.y
记录手指按下的坐标值mouseDown = pos.x
sub OnMove6DOF(Button as Integer,pos as vertex,rot as vertex)
diff=pos.x-mouseDown
Scene.findcontainer(“PI”).rotation.y=Init_rot+diff
end sub
函数OnMove6DOF()将逐场返回手指的坐标值储存在实参pos中。这样在该回调函数中diff将存储不断变化的手指沿X轴的变化值。Scene.findcontainer("PI").rotation.y=Init_rot+diff,最后将初始的饼图旋转值与diff值简单相加。通过手指滑动就可以控制饼图的Y轴旋转属性。
在线包装的交互应用有很广阔的发展空间,且实现同样的效果也可以由不同的算法实现。当一个设计师熟练地掌握了脚本语言,结合自身对电视包装的理解,发挥丰富的想象力,不仅仅可以将交互应用在触摸屏这样的平台。借用熟练的技术、灵活的思维,在线包装应用的方方面面都有交互的影子。作为一名在线包装设计师需要考虑的不仅仅是构图、色彩、动画、质感这些传统的图形设计问题,更需要考虑并能付诸实现的是如何从多方面增强播控的交互性。
[1]Vizrt Artist User Manual:1059-1094.
[2]金斯利 休斯.VBScript程序员参考手册[M].北京:清华大学出版社,2009.
[3]彼得斯. Flash ActionScript 3.0 动画高级教程[M].北京:人民邮电出版社,2010.