Silverlight Blend动画设计系列十二:三角函数(Trigonometry)动画之自由旋转(Free-form rotation)...

  说到对象的旋转,或许就会联想到对象角度的概念。对象的旋转实现实际上就是利用对象的角度改变来实现的位置变换,在《Silverlight & Blend动画设计系列二:旋转动画(RotateTransform)》一文中有对对象的不同角度变换的实现介绍,本篇要介绍的自由旋转(Free-form rotation)将借助《Function Silverlight 3 Animation》一书中的示例项目介绍,详细敬请阅读本文。

 

  要实现自由旋转其实非常简单,需要特别注意的有四点,既旋转对象、旋转中心点、旋转角度及旋转焦点。可以简单理解为当点击对象上的某一点可以对对象实现其以某一中心点为准的不等角度旋转。为了方便控制通常会将旋转焦点设计为相对突出的UI呈现,如下图示:

        

 

   上图的UI外观设计为一个独立的UserControl,对应的xaml定义如下:

<UserControl x:Class="ImageRotate.RotateItem"
    xmlns
="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml" 
    Width
="320" Height="240">
    
<Canvas x:Name="ItemCanvas" Width="320" Height="240" Canvas.Left="77" Canvas.Top="57" Background="#FFFFFFFF" 
    RenderTransformOrigin
="0.5,0.5">
        
<Canvas.RenderTransform>
            
<TransformGroup>
                
<RotateTransform x:Name="RotateItemCanvas" Angle="0"/>
            
</TransformGroup>
        
</Canvas.RenderTransform>        
        
<Image x:Name="Image" Width="300" Height="220" Canvas.Left="10" Canvas.Top="10" Source="" Stretch="Fill"/>
        
<Ellipse x:Name="Handle" Width="15" Height="15" Fill="#FFEAFF00" Stroke="#FF000000" Canvas.Left="313" Canvas.Top="233"/>
    
</Canvas>
</UserControl>

 

  分析上面的xaml可以知道,整个界面通过基于坐标的Canvas进行布局,默认设置布局容器的旋转角度为0度,在Canvas里面放置了一个图片作为可旋转的对象外观呈现,一个圆形作为旋转焦点。最终实现旋转功能的就是鼠标在Ellipse对象上的事件应用,通过事件处理函数来改变整个布局容器的旋转角度(Angle)。 

private bool IsMouseCaptured;
private Point MousePosition;
private Point LastPosition;
public Point CanvasCenter;
private double LastAngle;
private double CurrentAngle;
private double AngleDelta;

public RotateItem()
{
    InitializeComponent();
    
//注册Ellipse对象的鼠标事件
    Handle.MouseLeftButtonDown += new MouseButtonEventHandler(Handle_MouseLeftButtonDown);
    Handle.MouseLeftButtonUp 
+= new MouseButtonEventHandler(Handle_MouseLeftButtonUp);
    Handle.MouseMove 
+= new MouseEventHandler(Handle_MouseMove);
}

private void Handle_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
    FrameworkElement Item 
= sender as FrameworkElement;
    Item.ReleaseMouseCapture();
    IsMouseCaptured 
= false;
    Item.Cursor 
= null;
}

private void Handle_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    FrameworkElement Item 
= sender as FrameworkElement;
    Item.CaptureMouse();
    Item.Cursor 
= Cursors.Hand;
    IsMouseCaptured 
= true;
    LastPosition 
= e.GetPosition(null);
}

 

  最关键的就是MouseMove事件了,在MouseMove事件处理函数中,通过计算鼠标点下时的坐标和当前所在的坐标进行弧度转化角度的计算,将得到的角度值设置为Canvas的旋转角度就达到了实现对象的自由旋转功能。

        

 

  以下为弧度转化为角度的计算公式以及MouseMove事件算法实现:

/// <summary>
/// 弧度转化为角度
/// </summary>
/// <param name="Radians"></param>
/// <returns></returns>
private double RadiansToDegrees(double Radians)
{
    
return Radians * 180 / Math.PI;
}

 

private void Handle_MouseMove(object sender, MouseEventArgs e)
{
    MousePosition 
= e.GetPosition(null);

    
if (IsMouseCaptured)
    {
        LastAngle 
= Math.Atan2(LastPosition.Y - CanvasCenter.Y, LastPosition.X - CanvasCenter.X);
        CurrentAngle 
= Math.Atan2(MousePosition.Y - CanvasCenter.Y, MousePosition.X - CanvasCenter.X);
        AngleDelta 
= CurrentAngle - LastAngle;
        RotateItemCanvas.Angle 
+= RadiansToDegrees(AngleDelta);
        LastPosition 
= MousePosition;
    }
}

 

ExpandedBlockStart.gif可旋转UserControl完整代码
public partial class RotateItem : UserControl
{
    
private bool IsMouseCaptured;
    
private Point MousePosition;
    
private Point LastPosition;
    
public Point CanvasCenter;
    
private double LastAngle;
    
private double CurrentAngle;
    
private double AngleDelta;

    
public RotateItem()
    {
        InitializeComponent();
        Handle.MouseLeftButtonDown 
+= new MouseButtonEventHandler(Handle_MouseLeftButtonDown);
        Handle.MouseLeftButtonUp 
+= new MouseButtonEventHandler(Handle_MouseLeftButtonUp);
        Handle.MouseMove 
+= new MouseEventHandler(Handle_MouseMove);
    }

    
private void Handle_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
        FrameworkElement Item 
= sender as FrameworkElement;
        Item.ReleaseMouseCapture();
        IsMouseCaptured 
= false;
        Item.Cursor 
= null;
    }

    
private void Handle_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        FrameworkElement Item 
= sender as FrameworkElement;
        Item.CaptureMouse();
        Item.Cursor 
= Cursors.Hand;
        IsMouseCaptured 
= true;
        LastPosition 
= e.GetPosition(null);
    }

    
private void Handle_MouseMove(object sender, MouseEventArgs e)
    {
        MousePosition 
= e.GetPosition(null);

        
if (IsMouseCaptured)
        {
            LastAngle 
= Math.Atan2(LastPosition.Y - CanvasCenter.Y, LastPosition.X - CanvasCenter.X);
            CurrentAngle 
= Math.Atan2(MousePosition.Y - CanvasCenter.Y, MousePosition.X - CanvasCenter.X);
            AngleDelta 
= CurrentAngle - LastAngle;
            RotateItemCanvas.Angle 
+= RadiansToDegrees(AngleDelta);
            LastPosition 
= MousePosition;
        }
    }

        
    
/// <summary>
    
/// 弧度转化为角度
    
/// </summary>
    
/// <param name="Radians"></param>
    
/// <returns></returns>
    private double RadiansToDegrees(double Radians)
    {
        
return Radians * 180 / Math.PI;
    }
}

 

  使用也是非常简单的,动态创建上面所创建的UserControl然后将其添加到主容器控件中就可以了,如下演示代码:

 

public partial class MainPage : UserControl
{
    
public MainPage()
    {
        InitializeComponent();

        var Picture1 
= new RotateItem();
        Picture1.Image.Source 
= new BitmapImage(new Uri("Marigold.jpg", UriKind.Relative));
        Picture1.SetValue(Canvas.LeftProperty, 
100.00);
        Picture1.SetValue(Canvas.TopProperty, 
100.00);
        Picture1.CanvasCenter.X 
= (double)Picture1.GetValue(Canvas.LeftProperty) + Picture1.Width / 2;
        Picture1.CanvasCenter.Y 
= (double)Picture1.GetValue(Canvas.TopProperty) + Picture1.Height / 2;
        Picture1.RotateItemCanvas.Angle 
= -15;
        LayoutRoot.Children.Add(Picture1);
    }
}

 

         

 

  推荐资源:

  Silverlight & Blend动画设计系列文章

  《Function Silverlight 3 Animation》----本篇中使用的示例素材选自此书

 

    

版权说明

  本文属原创文章,欢迎转载且注明文章出处,其版权归作者和博客园共有。  

  作      者:Beniao

 文章出处:http://beniao.cnblogs.com/  或  http://www.cnblogs.com/

 

转载于:https://www.cnblogs.com/beniao/archive/2010/06/20/1735898.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/495871.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vscode 调试 C++/JavaScript

Microsoft Visual Studio Code&#xff1a;https://blog.csdn.net/freeking101/article/details/86715578 IntelliJ IDEA&#xff1a;https://www.jetbrains.com/products/ 在调试 JavaScript 代码时&#xff0c; 其中 三种 比较 简单&#xff1a; 1.使用 Chrome 等 浏览器 调…

美国三院院士「迈克尔•乔丹」长文论述:为什么说「人工智能革命」尚未发生...

作者&#xff1a;Michael Jordan雷克世界」编译&#xff1a;嗯~是阿童木呀、KABUDA、EVA人工智能&#xff08;AI&#xff09;是当前时代的颂歌。这句话是由技术人员、学者、记者和风险投资家一致提出且真诚赞扬的。就像其他许多从技术学术领域跨越到通用领域的短语一样&#xf…

网络爬虫干货总结!

转载&#xff1a;https://cloud.tencent.com/developer/article/1366434 bilibili 视频 - 聊聊 Python 的应用 - 健壮高效的网络爬虫&#xff1a;https://www.bilibili.com/video/av34379204/ 昨天的时候我参加了掘金组织的一场 Python 网络爬虫主题的分享活动&#xff0c;主要…

GAN 的发展对于研究通用人工智能有什么意义?

作者&#xff1a;Lyken 来源&#xff1a;知乎GAN对于人工智能的意义&#xff0c;可以从它名字的三部分说起&#xff1a;Generative Adversarial Networks。为了方便讲述&#xff0c;也缅怀过去两周在某论坛上水掉的时间&#xff0c;我先从Networks讲起。Networks&#xff1a…

AlldayTest 产品使用--文件

“文件”一栏&#xff0c;可实现新建/打开项目、导入&#xff08;出&#xff09;项目、配置信息等功能。 1、新建项目 运行AlldayTest&#xff0c;点击&#xff1a;“文件”-->“新建”&#xff0c;在出现的窗体内输入新创建项目的名称&#xff0c;选择路径保存即可。Allday…

移动端 爬虫工具 与 方法 介绍

From&#xff1a;https://www.cnblogs.com/zyfd/p/9681080.html 本文主要介绍了移动端爬虫的工具与方法&#xff0c;作为一个入门的大纲。没有详细介绍的也给出了本人学习过程中借鉴的资料的链接&#xff0c;适合对移动端爬虫感兴趣的同学入门。 一、抓包模拟 基本原理&#xf…

“芯痛”之下阿里苦心研发NPU AI芯片究竟哪款PU更厉害?

来源&#xff1a;OFweek人工智能网4月19日&#xff0c;有消息称&#xff0c;阿里巴巴达摩院正在研发一款神经网络芯片——Ali-NPU&#xff0c;主要运用于图像视频分析、机器学习等AI推理计算。按照设计&#xff0c;这款芯片性能将是目前市面上主流CPU、GPU架构AI芯片的10倍&…

(转)Windows 批处理实现 定时打开IE 延时一段时间后 关闭IE

要求实现一个定时器&#xff1a;如题 1、首先建立一个bat文件 内容如下&#xff1a; echo offrem 关闭回显命令 cd C:\Program Files\Internet Explorer\rem 改变当前目录到IE所在目录 start iexplore.exe "http://192.168.0.106:29101/LoadMemoryDB?typeMT&commande…

POE API 驱动 OpenAI API 依赖服务

本文主要是介绍了如何利用 POE 提供的 API 服务来驱动原来依赖 OpenAI 的 API 服务 AIGC 的大模型已经火了很久&#xff0c;但是众所周知的原因 OpenAI 的服务订阅对于大陆用户很不友好。而另一个 AIGC 聚合平台 POE 则对大陆用户比较友好&#xff0c;招行的 VISA 和 Master 卡…

深度分析:基站+光通信+手机都用到了哪些美国芯片?有何替代?

来源&#xff1a;21ic电子网摘要&#xff1a;2016年3月8日&#xff0c;美国商务部由于中兴通讯涉嫌违反美国对伊朗的出口管制政策&#xff0c;中兴实行禁运。丨事件&#xff1a;2018年04月16日&#xff0c;美国商务部发布对中兴通讯出口权限禁令&#xff0c;禁止美国企业向其出…

AirtestIDE 教程 — 5分钟上手自动化测试

AirtestIDE 教程 — 5分钟上手自动化测试&#xff1a;&#xff1a;http://airtest.netease.com/tutorial/Tutorial.html AirtestIDE 官方文档&#xff1a;http://airtest.netease.com/docs/docs_AirtestIDE-zh_CN/index.html AirtestProject 官方文档&#xff1a;https://air…

全面超越 Appium,使用 Airtest 超快速开发 App 爬虫

From&#xff1a;https://segmentfault.com/a/1190000017982620 https://www.kingname.info/2019/01/19/use-airtest 在 Airtest 中如何正确使用无线模式控制手机&#xff1a;https://juejin.im/post/5c4f12b0e51d453f45614bbb 使用 python poco 夜神模拟器 进行 自动化测…

Nature:“解构”母爱

来源&#xff1a;生物360一篇论文报告称&#xff0c;小鼠下丘脑视前区相当于一个集成中心&#xff0c;汇集育儿行为相关的大量信息。具体而言&#xff0c;研究人员发现视前区表达甘丙肽的神经元会协调育儿行为的运动、动机、激素和社会因素。相关成果近日 发表 于《自然》。育儿…

重磅!不止是芯片!半导体全产业链分析

来源&#xff1a;杨明辉电子&#xff08;ID&#xff1a;gh_e6a65dbbbff9&#xff09;作者&#xff1a;光大电子团队周期性波动向上&#xff0c;市场规模超4000亿美元半导体是电子产品的核心&#xff0c;信息产业的基石。半导体行业因具有下游应用广泛、生产技术工序多、产品种类…

adb(Android debug bridge)命令

From&#xff1a;https://www.cnblogs.com/huanyou/p/5133737.html ADB 用法大全&#xff1a; github 地址&#xff1a;https://github.com/mzlogin/awesome-adb adb 官网链接&#xff08; 国内想访问&#xff0c;你懂得&#xff01;&#xff01;&#xff01; &#xff09;&am…

预计2024年全球医疗AI市场超100亿美元

来源&#xff1a;新浪医药摘要&#xff1a;随着人们对这些技术所带来的好处日益了解&#xff0c;AI在医疗领域的应用正越来越广泛&#xff0c;例如药物研发和医学影像学等方面。高昂的初始资本需求和维护维修费用以及AI可能扰乱行业并导致大规模失业的担忧&#xff0c;阻碍了AI…

分享自己写的一个贪吃蛇的游戏(Linux)

作者: dave_cn 发表于 2010-07-18 21:20 原文链接 阅读: 148 评论: 2转载请注明出处。http://www.cnblogs.com/dave_cn/本程序需要ncurses库&#xff0c;ubuntu下安装ncurses可以执行下面命令&#xff1a;sudo apt-get install libncurses5-dev 关于ncurses的用法&#xff0c;读…

Linux 的 diff 命令

读懂 diff&#xff1a;http://www.ruanyifeng.com/blog/2012/08/how_to_read_diff.html 菜鸟教程&#xff1a;https://www.runoob.com/linux/linux-comm-diff.html diff 命令详解&#xff1a;https://www.cnblogs.com/wf-linux/p/9488257.htmlhttp://man.linuxde.net/diffhttp…

机器人大潮中暗藏多少伪命题

来源&#xff1a;中国青年报摘要&#xff1a;伴随着巨大的产业浪潮&#xff0c;一种担忧在人群中弥漫&#xff0c;即机器人的“步伐”如此之快&#xff0c;未来究竟会否抢走人类的饭碗&#xff0c;和人类之间爆发一场就业战争&#xff0c;进而夺走人类的一切&#xff1f;2018 R…

哈佛医学院解析:触发医学深度学习系统受到「对抗攻击」的诱因有哪些?

原文来源&#xff1a;arXiv作者&#xff1a;Samuel G. Finlayson、Isaac S. Kohane、Andrew L. Beam「雷克世界」编译&#xff1a;EVA对抗样本的发现引起了人们对深度学习系统的实际部署的关注。在本文中&#xff0c;我们认为&#xff0c;就货币激励和技术脆弱性&#xff08;mo…