• 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”实现的思考。各位不要见笑。
      如果您有何这方面的经验和新的想法,不妨说出来,让我也学习学习。

      

      
  • 相关阅读:
    两种常用图像识别迁移学习方法
    学习备忘
    图像处理代码举例(C++、MATLAB、OpenCV)
    Java 读取clob字段的几种方法
    Oracle 查询表注释以及字段注释
    Oracle 查询表的索引包含的字段
    Oracle 获取表的主键、外键以及唯一约束条件
    Oracle列信息表 all_tab_columns中的data_length和data_precision字段区别
    Oracle 表结构、索引以及分区信息查询
    Java中的String,StringBuilder,StringBuffer三者的区别
  • 原文地址:https://www.cnblogs.com/yaoge/p/1824653.html
Copyright © 2020-2023  润新知