通通玩blend美工(5)——旋转木马,交互设计
晓晓 2018-03-16 来源 :网络 阅读 509 评论 0

摘要:这一篇偏向于逻辑的比较多,放在这个系列里会不会欠妥呢?在中国交互性设计也是美工的份内职责哦~

这一篇偏向于逻辑的比较多,放在这个系列里会不会欠妥呢?在中国交互性设计也是美工的份内职责哦~

  所以没有blend基础的人也可以看懂这篇文章,不过要用到初中的几何知识哦~亲

 

  相信很多人都在手机或者网页上或者KTV的点歌系统里看到过旋转木马的目录导航,这个是如何做的呢??  

改变左上角的数据,会有意想不到的效果哟~

(特别鸣谢烤地瓜的答疑,和地瓜村众人的热心帮助)

 

1.总体思路


分析上面效果:一排方块在转圈,点击的块跑到最近的位置

  圈:其实就是一个椭圆,只不过人的近大远小的逻辑思维,大脑根据常识把它装换成了一个空间。

  最近的位置:其实就是椭圆的最下面,块变得最大,所以感觉最近。

 

2.设计过程


  首先我们来实现让这堆块围绕成一个椭圆。

step.1 椭圆是这样来产生滴~!↓

通通玩blend美工(5)——旋转木马,交互设计 


  我以我微薄的几何知识用blend画出了上图,右上角看到我们久违的椭圆公式。第一个公式当把y单独提到等号一边时发现是要开根号的这样,就如图所看到的,一个x对应着两个y值还得去判断正负号显得麻烦了,就用第二个公式吧。其中a为x半轴,b为y半轴,d为角度。只需要一个角度d就可以确定出这个椭圆中的所有点了。

首先写出变换块位置的方法:


private void SetPosition(Grid item, double degree)         
    {             
        TransformGroup myTG = item.RenderTransform as TransformGroup;             
        TranslateTransform myTT = myTG.Children[0] as TranslateTransform;//位置变换             
        myTT.X = a * Math.Cos(degree);//计算x坐标             
        myTT.Y = b * Math.Sin(degree);//计算y坐标             
        item.Tag = degree;              
        ScaleTransform myST = myTG.Children[1] as ScaleTransform;//大小变换
              myST.ScaleX = myST.ScaleY = (1 - scale) / b * myTT.Y + scale;
              Canvas.SetZIndex(item, (int)(myTT.Y + 2 * b));//层次变换为Y轴的位置                   
    }

 

step.2 跟随鼠转标起来吧  
  这样传入需要变换的块和事先计算的该块的位置所在就角度就可以确定该块的位置、大小、层次了。单mousemove的时候,只要给每一个块都重新定位,把鼠标的移动距离装换为块组需要旋转的角度。
private void LayoutRoot_MouseMove(object sender, MouseEventArgs e)//鼠标移动时转动
         {
            if (isPress)//如果当前为按住鼠标的状态
             {
                 foreach (Grid item in LayoutRoot.Children)//遍历所有的Grid
                 {
                     SetPosition(item, (double)item.Tag + (startPoint.X - e.GetPosition(this).X) * 0.005);//变换位置
                 }
                 startPoint.X = e.GetPosition(this).X;//把但前位置赋给开始位置
             }
         }


我把每个Grid的Tag用来存储自己当前所在的角度。


step.3 点击就转到前面来啊,亲~

  接下来制作点击块转动的动画,即点击块后更具该块所在的位置,计算出旋转到90'时需要旋转的角度,然后所有块都转这个角度(为什么是90°呢?应该是270°啊~因为wpf中的位移动画,Y轴移动向下是为正,向上为负,这样就刚好和我们课堂上通用的坐标系刚好上下翻转了)


void newGrid_MouseUp(object sender, MouseButtonEventArgs e)//单击其中一块转正
         {
             double nowAngle = (double)((sender as Grid).Tag);//根据当前的块的角度
             double needAngle = Math.PI / 2 - nowAngle % (Math.PI * 2);//换算出把改块转正整体需要转动的角度
              foreach (Grid item in LayoutRoot.Children)//为每一个块都添加动画
             {
                 degree = (double)item.Tag;//获取各个块的角度
                 TransformGroup myTG = item.RenderTransform as TransformGroup; 
                 TranslateTransform myTT = myTG.Children[0] as TranslateTransform;//位置变换
                 Storyboard sb = new Storyboard();
                 sb.Duration = new Duration(TimeSpan.FromMilliseconds(Duration));
                 DoubleAnimation xAnimation = new DoubleAnimation();
                 xAnimation.To = a * Math.Cos(degree + needAngle);//计算x坐标
                 xAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(Duration));
                 sb.Children.Add(xAnimation);
                 Storyboard.SetTarget(xAnimation, myTT);
                 Storyboard.SetTargetProperty(xAnimation, new PropertyPath("X"));
                 DoubleAnimation yAnimation = new DoubleAnimation();
                 yAnimation.To = b * Math.Sin(degree + needAngle);//计算x坐标
                 yAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(Duration)); 
                 sb.Children.Add(yAnimation); 
                 Storyboard.SetTarget(yAnimation, myTT);
                 Storyboard.SetTargetProperty(yAnimation, new PropertyPath("Y"));
                 ScaleTransform myST = myTG.Children[1] as ScaleTransform;//大小变换
                 DoubleAnimation xScaleAnimation = new DoubleAnimation();
                 DoubleAnimation yScaleAnimation = new DoubleAnimation();
                 xScaleAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(Duration));
                 yScaleAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(Duration));
                 if (LayoutRoot.Children.IndexOf(item) == 0)//只添加一次动画完成后遍历控件改变位置
                 {
                     yScaleAnimation.Completed += new EventHandler((s, events) =>//动画结束后把整体的位置调整为动画结束时的位置
                     {
                         foreach (Grid item1 in LayoutRoot.Children)
                         {
                             SetPosition(item1, (double)item1.Tag);
                         }
                     });
                 }
                 yScaleAnimation.To = xScaleAnimation.To = (1 - scale) / b * yAnimation.To + scale;
                 sb.Children.Add(xScaleAnimation); 
                 Storyboard.SetTarget(xScaleAnimation, myST); 
                 Storyboard.SetTargetProperty(xScaleAnimation, new PropertyPath("ScaleX"));    
                 sb.Children.Add(yScaleAnimation);
                 Storyboard.SetTarget(yScaleAnimation, myST);
                 Storyboard.SetTargetProperty(yScaleAnimation, new PropertyPath("ScaleY"));
                 sb.Begin();//开始动画
                 item.Tag = degree + needAngle;//记录最后的角度
                                              }
          }

step.4 最靠近下面的要自动对正哦~

  OK,接下来还差最有一点就是自动对正了,即当拖动时把最接近最近位置的块自定定位到最近。

  原理就是遍历所有块的但前位置,角度越接近90°的就模拟一下它的单击


 private void LayoutRoot_MouseUp(object sender, MouseButtonEventArgs e)//当鼠标弹起时判断最近的块,自动转正
         {
             double minNear = 100;
             Grid nearGrid = null;
             foreach (Grid item in LayoutRoot.Children)//找出最近的Grid
             {
                 double near = Math.Abs(Math.PI / 2 - (double)item.Tag % (Math.PI * 2));
                 if (near < minNear)
                 {
                     minNear = near;
                     nearGrid = item;
                 }
             }
             newGrid_MouseUp(nearGrid, null);//模拟最近的块被点了一次
             isPress = false;
         }


  做完收工。 

  

 下面是我修改左上角的参数实现的几个比较好看的效果

通通玩blend美工(5)——旋转木马,交互设计

 

通通玩blend美工(5)——旋转木马,交互设计通通玩blend美工(5)——旋转木马,交互设计

 

效率也是很不错的,上面的100个块在我i7的电脑上一点都不卡哦。


  大家如果调出什么好看的效果可以交流下。


  我把核心代码都讲了遍,如果还是有不懂的,可以给我留言。当然了这个silverlight版只是作为演示用得第一版,有很多细节方面我没处理。至于源码,因为我做的这个原版是WPF程序作为商用,所以经过多番考虑我还是不公布源码了。


本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标设计创作之交互设计频道!


本文由 @晓晓 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程