zoukankan      html  css  js  c++  java
  • Silverlight——简单3D效果的探究

    3D:

     在MSDN上有个关于silverlight的3D展示,点击两边的图片时,图片转换会出先立体视觉动画效果:

    这个效果看上去很炫,但偏偏就这个实例MSDN上不给代码!郁闷啊。

    立体感与3D:

      既然没有那我就自己来。虽学习SL有段时间了,但多是在内部数据方面。虽然也看到过别人做出的3D效果的作品,但就觉的很炫,也就过过
    眼。既不知道如何实现这样的效果的,也没想过原理。偶然看到一张很让人纠结的图片:
      我还为这个三角形是站着的还是躺着的,思考了半天。其实我也并不清楚这种“3D”和《阿凡达》要带眼镜的“3D”那个更确切。
    其实这个利用的是人的视觉,让人产生一种立体的感觉。
    布局:
    回到那个例子上,当然这些图片都是平面的。下面用数据说明,如何让平面的看起来
    像个立体的:
      
    旁边的是刚开始我设计的动作变化。下面还有实验时候的布局代码,并不完全,但已经有了思路了:
      
    代码
    <Rectangle x:Name="AR" Tag="left" Width="200" Height="250" Canvas.Top="20" Canvas.Left="50" Canvas.ZIndex="3" MouseLeftButtonDown="btnMouseLeftButtonDown">
    <Rectangle.Projection>
    <PlaneProjection x:Name="AP" RotationY="-60"></PlaneProjection>
    </Rectangle.Projection>
    <Rectangle.Fill>
    <ImageBrush x:Name="Aimg" ImageSource="/SLDemo3D;component/florian.jpg">
    </ImageBrush>
    </Rectangle.Fill>
    </Rectangle>

    <Rectangle x:Name="BR" Tag="mid" Width="200" Height="250" Canvas.Top="20" Canvas.Left="300" Canvas.ZIndex="2" MouseLeftButtonDown="btnMouseLeftButtonDown">
    <Rectangle.Projection>
    <PlaneProjection x:Name="BP" RotationY="0"></PlaneProjection>
    </Rectangle.Projection>
    <Rectangle.Fill>
    <ImageBrush x:Name="Bimg" ImageSource="/SLDemo3D;component/jareck.jpg">
    </ImageBrush>
    </Rectangle.Fill>
    </Rectangle>

    <Rectangle x:Name="CR" Tag="right" Width="200" Height="250" Canvas.Top="20" Canvas.Left="550" Canvas.ZIndex="1" MouseLeftButtonDown="btnMouseLeftButtonDown">
    <Rectangle.Projection>
    <PlaneProjection x:Name="CP" RotationY="60"></PlaneProjection>
    </Rectangle.Projection>
    <Rectangle.Fill>
    <ImageBrush x:Name="Cimg" ImageSource="/SLDemo3D;component/kamil.jpg">
    </ImageBrush>
    </Rectangle.Fill>
    </Rectangle>
    就是用了:<Rectangle.Projection>
                    <PlaneProjection x:Name="CP" RotationY="60"></PlaneProjection>
                </Rectangle.Projection>
    使图片产生侧面立体的效果,简单吧。(为了看起来更逼真,您可以将中间一幅设置稍大点)这样就会有:

    动画:
      下面最主要的问题就是如何设定动画。将动画分解,其实就是两部:
        1,图片视角的动画
        2,图片位置的动画
      这样就好办了,利用<Storyboard >
                          <DoubleAnimation Storyboard.TargetName=""Storyboard.TargetProperty=""From="" To="" Duration="">
                </DoubleAnimation>
               </Storyboard>
    很容易就实现动画效果了。只需要将这两个动画组合起来,同时进行。就会实现类似MSDN上的效果了。
    代码
    <Canvas.Resources>
    <Storyboard x:Name="myStoryboard" Completed="myStoryboard_Completed">
    <!--图片的旋转-->
    <DoubleAnimation x:Name="daAP" Storyboard.TargetName="AP"
    Storyboard.TargetProperty
    ="RotationY"
    From
    ="-60" To="0" Duration="0:0:1"></DoubleAnimation>
    <DoubleAnimation x:Name="daBP" Storyboard.TargetName="BP"
    Storyboard.TargetProperty
    ="RotationY"
    From
    ="0" To="60" Duration="0:0:1"></DoubleAnimation>
    <DoubleAnimation x:Name="daCP" Storyboard.TargetName="CP"
    Storyboard.TargetProperty
    ="RotationY"
    From
    ="60" To="-60" Duration="0:0:1"></DoubleAnimation>
    <!--图片换位-->
    <DoubleAnimation x:Name="daAR" Storyboard.TargetName="AR"
    Storyboard.TargetProperty
    ="(Canvas.Left)"
    From
    ="50" To="300" Duration="0:0:1"></DoubleAnimation>
    <DoubleAnimation x:Name="daBR" Storyboard.TargetName="BR"
    Storyboard.TargetProperty
    ="(Canvas.Left)"
    From
    ="300" To="550" Duration="0:0:1"></DoubleAnimation>
    <DoubleAnimation x:Name="daCR" Storyboard.TargetName="CR"
    Storyboard.TargetProperty
    ="(Canvas.Left)"
    From
    ="550" To="50" Duration="0:0:1"></DoubleAnimation>
    </Storyboard>
    <Storyboard x:Name="myStoryboard2" Completed="myStoryboard2_Completed">
    <!--图片的旋转-->
    <DoubleAnimation x:Name="daAP2" Storyboard.TargetName="AP"
    Storyboard.TargetProperty
    ="RotationY"
    From
    ="-60" To="60" Duration="0:0:1"></DoubleAnimation>
    <DoubleAnimation x:Name="daBP2" Storyboard.TargetName="BP"
    Storyboard.TargetProperty
    ="RotationY"
    From
    ="0" To="-60" Duration="0:0:1"></DoubleAnimation>
    <DoubleAnimation x:Name="daCP2" Storyboard.TargetName="CP"
    Storyboard.TargetProperty
    ="RotationY"
    From
    ="60" To="0" Duration="0:0:1"></DoubleAnimation>
    <!--图片换位-->
    <DoubleAnimation x:Name="daAR2" Storyboard.TargetName="AR"
    Storyboard.TargetProperty
    ="(Canvas.Left)"
    From
    ="50" To="550" Duration="0:0:1"></DoubleAnimation>
    <DoubleAnimation x:Name="daBR2" Storyboard.TargetName="BR"
    Storyboard.TargetProperty
    ="(Canvas.Left)"
    From
    ="300" To="50" Duration="0:0:1"></DoubleAnimation>
    <DoubleAnimation x:Name="daCR2" Storyboard.TargetName="CR"
    Storyboard.TargetProperty
    ="(Canvas.Left)"
    From
    ="550" To="300" Duration="0:0:1"></DoubleAnimation>
    </Storyboard>
    </Canvas.Resources>
    代码中设定了两个动画效果,一个是图片向左旋转的,一个是向右旋转的。
    实验了一下,基本上实现了“3D”效果。

    进一步的改进:
      
    似乎我们的目的达到了,但是很多地方还要改进。首先就是我们图片只会向左或向右移动一次,然后就是重复动画了,这当然是不行的。
      所以首先动态设定图片立体视觉的参数:
    代码
    //旋转参数
    double tempdaAP = (double)daAP2.From;
    daAP2.From
    =daAP2.To;
    daBP2.To
    =daAP2.From ;
    daBP2.From
    = daBP2.To;
    daCP2.To
    =daBP2.From ;
    daCP2.From
    =daCP2.To;
    daCP2.To
    =tempdaAP;
    还有动画位移的参数:
    代码
    //坐标参数
    double tempdaAR = (double)daAR2.From;
    daAR2.From
    =daAR2.To;
    daBR2.To
    = daAR2.From;
    daBR2.From
    = daBR2.To;
    daCR2.To
    = daBR2.From;
    daCR2.From
    = daCR2.To;
    daCR2.To
    = tempdaAR;
    细心的您一定会发现这只是向左边移动时的情况,向右移动的时候上面的两组代码又会不一样!
    同样的问题还在图片的ZIndex参数上:
    代码
    //zindex参数
    int tempindex = Canvas.GetZIndex(AR);
    Canvas.SetZIndex(AR, Canvas.GetZIndex(BR));
    Canvas.SetZIndex(BR, Canvas.GetZIndex(CR));
    Canvas.SetZIndex(CR, tempindex);
    string temptag = AR.Tag.ToString();
    这是向右移动时Zindex修改情况,但向左时的又是另一情况!
    还有个问题,就是如何判断图片向左还是向右?跟据上面的代码,可以用同样的方式处理这个问题。
    CR.MouseLeftButtonDown += new MouseButtonEventHandler(btnMouseLeftButtonDown);
    CR.MouseLeftButtonDown -= new MouseButtonEventHandler(btnMouseLeftButtonDown);
    为不同位置的图片移除和绑定不同的事件。这是方法之一,同样还可以这样做:
      为每个图片设定tag,用于存放位置的信息。然后根据触发事件的sender判断当前图片的位置。动画完成后利用上面轮换的方法重新
    设定图片的tag。(因为name不能随便修改,所以使用tag)
    //tag用于判定动画
    string temptag = AR.Tag.ToString();
    AR.Tag
    =BR.Tag;
    BR.Tag
    = CR.Tag;
    CR.Tag
    = temptag;

     
    结束:
      根据以上的信息,我想您应该明白我是如何设计和实现这个MSDN的“3D”效果了。别高兴的太早,还有很多东西需要完善的。比如:
    如何让判断左右移动代码更简洁?如何处理动画未完成时,用户又点击动画了?如何处理以上的代码的顺序,是在移动前还是在移动完成
    后?等等等。以上问题我都实现和优化了,但不知与MSDN上的代码有多大的差距呢?
      我建议您自己思考一下,因为我在设计的时候很多东西有的方法并不容易实现的,还有的处理方法可能会是多样的。
    OK,这就是一个从未见识过这方面内容和没有任何参考的人关于简单“3D”实现的思考。各位不要见笑。
      如果您有何这方面的经验和新的想法,不妨说出来,让我也学习学习。

      

      
  • 相关阅读:
    Asp.net MVC 传递数据 从前台到后台,包括单个对象,多个对象,集合 前端javascript数组,后端接受
    jquery each循环遍历完再执行的方法 因为each是异步的 所以要加计数器.
    分布式中的一些概念,分布式简单理解,分布式架构的常见概念
    href="#"与href="javascript:void(0)"的区别
    Newtonsoft.Json高级用法DataContractJsonSerializer,JavaScriptSerializer 和 Json.NET即Newtonsoft.Json datatable,dataset,modle,序列化
    Newtonsoft.Json高级用法,json序列号,model反序列化,支持序列化和反序列化DataTable,DataSet,Entity Framework和Entity,字符串
    C#利用反射实现两个类的对象之间相同属性的值的复制,一个对象的属性复制给另一个对性的属性
    指定文件兼容性模式 < meta http-equiv = "X-UA-Compatible" content = "IE=edge,chrome=1" />的意义
    使用 IIS 在 Windows 上托管 ASP.NET Core2.0
    jQuery.data() 的实现方式,jQuery16018518865841457738的由来,jQuery后边一串数字的由来
  • 原文地址:https://www.cnblogs.com/yaoge/p/1824653.html
Copyright © 2011-2022 走看看