flash中gif动态图片分解解的位图怎么复制

  最近碰到的一个项目需要用flash做出动态的“饼图”,众所周知,flash并不支持动态创建和改动图形(除了简单的缩放旋转以外),所以没有什么直接的方法动态绘制不同角度的扇形。没有可程序控制的扇形,动态的饼图当然也无法实现。当然如果用svg会方便很多,可是现在它还太不成熟,几乎不可能拿来实用。而且这个饼图的功能是一个flash game中的一部分,所以只好想办法利用flash本身的功能来实现。
  先来分析一下饼图的结构,饼图实际上是不同角度和颜色的扇形的组合,如果能够做到用程序控制扇形的角度,那么饼图就可以实现了。如果精度要求不高的话,有一种比较简单的办法,就是制作小角度的扇形作为基础,然后通过复制拼接这些小扇形来组成大扇形。这个方法比较直观而简单,但缺点也很明显,首先它精度无法做到很高,其次过多的小扇形会影响效率而且如果要做到用户动态控制(比如用户实时调整扇区大小)就会变得很复杂,所以这里不能采用这种办法。
  还有一种办法就是遮罩,如图1,用一个半圆形被遮物体和一个矩形遮罩(或者其他形状都行,只要它有一个平直的上边。这里要注意的是半圆形的圆心必须精确的位于遮罩的矩形的上面一条边上,否则最终会有较大误差),程序可以控制被遮物体的旋转角度。
     
  我们用另外一个划杆动态控制半圆形的旋转角度,请看如下的flash,在遮罩效果的合成下,一个能够从0-180度变换角度的扇形就出现了:)很简单是吗?
  呵呵~ 事情还没有完,这只能作出0-180度的角,因为遮罩是平的,所以出现的最大角度只能是180度。如果角度大于180度的时候怎么办呢?也许我们可以试一下用大于180度的遮罩和被遮物体,这很简单,你可以现在就试试。(为了节省版面这里就不演示了)然后,你很快就会发现这样其实根本行不通,因为这样虽然确实能够做到大于180度的角,但是,在小于某个角度(和遮罩角度大小有关)时,这个做法就会出现问题,本来不应该有东西的遮罩另外一边竟然也出现一个扇形。这种情况当然是不能容忍的。
  那么,难道就不能做出大于180度的扇形了吗?当然不是,办法其实也很简单,可能很多读者已经想到,就是在角度大于180度的时候,先显示一个半圆,然后我们从这个半圆开始绘制扇形(如图2所示,把刚才的遮罩和半圆旋转180度,并在原来的遮罩的地方放上一个半圆形),于是园的另外一半就在我们的控制之下了。你也许会说,这样的话180度以下的角度不就不能实现吗?哈哈,这个问题其实很容易解决,我们可以利用flash的MovieClip机制和自定义函数把扇形的两种实现方法包装(当然学术的说法是封装)起来,也就是说把小于180度和大于180度的扇形实现方法放入一个MovieClip,然后制作一个函数来自动判断应该用哪种方式来实现并自行绘制出来,这种判断再简单不过,只用判断输入的角度是否大于180就行了。如下面的flash所示,一个完美的,可以动态控制的扇形就出来了:D。
  饼图的基础已经完成,剩下的工作就是取得正确的数据并且根据它显示出相应的图形。分解开来也就是根据数据计算出具体需要多少个扇形,每个扇形的角度是多少,然后复制出这些扇形并且给其设定相应的位置和角度了。而且,你还可以通过服务器端脚本或者xml来获取动态的数据,真正做到动态的图形显示!这些部分我想熟悉ActionScript的同学们应该能够容易的做出来,在这里就不详细叙述了。有疑问的话可以参考下面给出的fla文档,或者给我写信。
  这仅仅是这个教程的上篇而已,其实真正困难的部分还在后头。因为我碰到的这个项目的变态之处在于,它不仅要求能绘制出饼图,还要求用户能够通过鼠标拖动饼图上扇形的分割线(!)来改变比例!当然,bt归bt,我最终还是解决了它:)对此感兴趣的同学们请留意这个教程的下篇。当然如果只是需要一个饼图而并不需要更多的功能,那么这个教程的内容已经足够简单和实用了,希望这篇文章能够给你帮助和启发:)
  上篇已经解决了饼图的显示问题,接下来的问题是用户的动态控制,这里要求用户可以直观的改变饼图中元素的比例。为了不至于在描述目标上费太多口舌,先给大家看看最终完成的样子:
  用鼠标移动到扇形分界线和圆周相交的地方,会出现一个小圆点,通过拖动控制点可以改变分割线的角度,同时相邻的扇形的角度也会变化。于是我们就可以通过简单的拖动改变这个饼图的比例。
  实现这种效果的思路应该比较容易想到,我们只需要做出能够用鼠标拖动的控制点,而且要把它的运动范围限制在圆周上,然后根据控制点的坐标来计算分割线的旋转角度(让分割线始终指向控制点),最后得到线条之间的角度的大小并根据它来绘制扇形。看起来似乎并不太难,鼠标拖动是flash很基本的功能,通过坐标来计算分割线的旋转角度也是很容易的,然会绘制扇形我们只需要调用上篇的结果就行了。最难的地方,就在限制控制点的拖动范围,我们要求它必须在圆周上运动,而且不可以越过其他控制点。
  这就稍微有些麻烦了,我们知道,flash中的startDrag()函数内建了对鼠标拖动范围限制的支持,但是它只能定义一个矩形范围,其他形状的就无法通过这个直接的方法实现了。:(flash内部函数没有的功能,只好我们自己动手实现它了。(这里假定读者对flash编程有一定的了解,而且有些制作过程无法用文字表述的很清晰,若用较多图形来描述又会造成篇幅过大,所以部分比较基础和简单直观的内容可能并没有讲解得很详细,如果您觉得阅读有困难,可以先下载源代码,然后找到代码中相应的地方,边看这篇文章边查阅代码,我想这样应该会帮助您理解)
  我们先来做一个能够拖动的圆点,为了最终产生的饼图的美观,我们把它定义为通常状况下透明,只有rollover的时候才出现;on(press)的代码写上startDrag(""),on(release,releaseOutside)写入stopdrag的代码。由于我们要限制它的运动范围,所以鼠标拖动过程中几乎肯定会滑出按钮的范围之外,所以release和releaseOutside事件都应该勾上。然后按F8把它做成一个mc。试一下,应该可以拖动了,鼠标移开之后控制点就看不到了。接着画一个圆圈和圆的一条半径,半径的那条直线做成clip,并作相应的中心点的调整,让它旋转时一头始终在圆心上。半径的instance name取为line。半径和控制点我们做到一个clip里面,然后为了方便计算我们把圆心放在(0,0)。
  有了flash5之后计算圆周运动在也不是难事了,用内建的函数就可以方便的完成(想起4.0时代的那些公式我就害怕。。。)。在控制点上加入下面的代码
onClipEvent (enterFrame) {
 if (move) {
 angle = Math.atan2(_y, _x)*180/Math.PI;
 _parent.line._rotation =
  除了必要的角度/弧度转换之外,这段代码加入if(move)的目的是避免无谓的资源消耗,move的值在控制点的onpress事件设成true,onrelease设成false。运行一下,正常的话我们可以看到半径的直线始终指着控制点的方向。这个步骤应该有更优化的方法,不过这种要直观一些。
  接下来我们要限制控制点了,判断一个点是否在圆上的最简单方法我想可能是计算点到圆心的距离,只要它等于半径,就一定在圆上,如果它不等于,我们就要改变点的位置让它在圆上。这样我们的限制的目的就可以达到了。在上面的if(move)中加上下面的代码
r = math.sqrt(_x*_x+_y*_y);_x = _x*_parent.r/r;_y = _y*_parent.r/r;
  _parent.r是我们设定的圆的半径,再运行一下,这时我们就可以看到控制点已经严格在圆周上滑动了,如果你返回上一层,然后把控制点和支线组成的mc多复制几个然后错开角度摆在圆上,哇~ 一个饼图的框架已经出来了!而且你可以随意改变线条方向,线条间的夹角也就是扇形的角度也就发生了变化!象下面这样:
  这么简单就搞定了吗?当然没有,这个简陋的饼图的问题在于它上面的控制点不受其他控制点影响,可以随意穿过去,也就是说假如用户在缩小一个扇形的角度,结果它发现在角度小到0之后它还可以向缩小的方向移动以至于跑到另外一个点后面去了,这样可就乱了,某一个扇区是负值的饼图你见过吗?
  所以我们还要限制控制点不可以超过其他的控制点,也就是说它要在移动到其他控制点附近时停下来,而不可以跑到它的另一边去。我们如何比较控制点之间的位置呢?当然是利用它相对圆心的角度。我们用一个数组来记录每个控制点的角度,初始化和每次移动的时候对数组重新设置值,移动控制点的时候就根据这个数组判断控制点之间是否会发生越过的现象。
  数组lines在初始化时建立,保存不同控制点的角度。同时,一个控制点只会和与它相邻的控制点打交道,所以初始化的时候还要告诉它它的邻居是谁。初始化还要消除不同mc间坐标系的不同造成的差异。(具体代码请参考源代码中的MovieClip:line的定义中的第一桢)
  在上面的代码中设置line旋转后面插入这一行_parent._parent.lines[myNo] =在每次移动过后保存新的角度。接下来我们要在移动之前加入新的条件,也就是判断是否发生控制点之间的交叉,如果发生了,就不要移动。
  如何判断呢?电脑懂得比较大小,你也许会说:这个简单,比较自己的新角度和邻居们的角度不就行了,新角度应该比上一个点的角度大,比下一个点的角度小,否则就不要移动。呵呵~
  其实这样是行不通的,因为角度不同于线性的量,它在绕过360度之后又会回到原点,比如-330度=30度=390度=...,在flash中,圆周上半圈内的角度是0到180度之间,下半圈则是-180到0度之间,比如下图的情况,p1是145度,p3是-145度,p2是175度,此时p2>p1 p2>p3,如果p2沿逆时针方向移动,转到右边状态,我们看到,p1p3不变,p2角度变成-175度,此时p2<p1,p2<p3,但是实际上这三个点之间的位置关系并没有发生变化,我们是应该允许这样的移动的。
  为了解决这个问题,我们必须统一角度的值,必须把它格式化为一组在一个固定区间内,并且具有相互之间的比较关系的值。为此,加入这个函数:
 function formatAngle (a1,a2) {  //format a2 to smaller than a1;  if (a2>a1) {
 a2-=360;
 } while (a2>a1);  }  return a2; }
  它的作用是把输入的a2转换成一个比a1要小的但等同于a2的角度,实际应用中我们取一个合适的a1,然后对要比较的值分别是用这个函数就可以得到可以比较的值了。
  回到刚才,我们这里需要比较的是自己的新角度和两个相邻控制点的角度共三个角度,而且我们知道哪个点应该在我的顺时针方向哪个在逆时针方向,所以我们取自己逆时针方向的角度稍稍再向逆时针转动的角度作为a1,分别把三个角度作为a2,最后得到的值互相比较就可以判断出是否有越过相邻的控制点了。同样对上图,我们以p3+5度为a1,就是-140度,格式化后,p1p2p3分别是-215度、-185度和-145度,p3>p2>p1,转到右边的情况后,p1p2p3格式化后分别是-215、-175和-145,仍然是p3>p2>p1,和我们从图上的观察吻合!
  ok,现在所有的问题都已经解决,只要稍稍花些工夫就可以把刚才的分析以及上篇的内容合并起来,我们的动态饼图,终于可以大功告成了。。。哈哈哈哈~
&&&&&&&&&&
没有推荐文章怎样把photoshop里的位图复制到flash里啊?_百度知道
怎样把photoshop里的位图复制到flash里啊?
请问谁知道怎样把photoshop里的位图复制到flash里啊请各位大侠帮个忙?用flash画图太难了,我想把用PS作的图弄到flash里,不过都带有方形框
提问者采纳
你是想弄背景透明吧?存为gif或png再导入就好
其他类似问题
您可能关注的推广回答者:
photoshop的相关知识
其他1条回答
另外背景色要透明JPEG不支持透明色。另外,用PNG或者GIF格式才支持,用fireworks的话,直接复制粘贴到flash里面最好
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁动态图片怎样导入Flash里_百度知道
动态图片怎样导入Flash里
还让它是动态的,我导了几个都变成静态得了
提问者采纳
就OK了,把电影剪辑拖到场景的第一帧,导入到库,测试动画,库里就自动产生一个电影剪辑动态图片GIF格式的
其他类似问题
动态图片的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁

我要回帖

更多关于 位图转矢量图 的文章

 

随机推荐