View 随着手指的移动而放大和旋转
2015-09-22 11:47
483 查看
一、效果
如上图,手指头放在mExpendItemView,当手指头移动的时候,mTouchImageView随着mExpendItemView的移动而缩放和旋转
二、关键源码
入口是touchExpandView, 需要监听OnTouchListener,然后在onTouch执行touchExpandView。
三、原理
1、小图标mExpendItemView的移动
简单的数学知识:
mCorrectionX = event.getRawX() - v.getX();
这个mCorrectionX就是touch点和mTouchImageView左上角的X坐标的距离。这个值在移动的过程中是不变的。
所以,移动的时候,v的x坐标就是:
v.getX() = event.getRawX() - mCorrectionX.
就是上面代码中的函数getDistanceX
2、mTouchImageView的缩放和旋转
很重要的一点,缩放和旋转都是相对于原始大小和角度的。坐标是相对于mTouchImageView的中心点。
所以,先记录原始大小和角度:initAttribute()
缩放的倍数,就是缩放后的半径除以原始大小的半径。半径的算法就是勾股定理。
旋转的角度,就是上图的a2 - a1.
a2和a1的算法就是tan a = y / x.
如上图,手指头放在mExpendItemView,当手指头移动的时候,mTouchImageView随着mExpendItemView的移动而缩放和旋转
二、关键源码
private void initAttribute() { mCenterX = mTouchImageView.getX() + mTouchImageView.getWidth() / 2; mCenterY = mTouchImageView.getY() + mTouchImageView.getHeight() / 2; mOriginX = mTouchImageView.getX() + mTouchImageView.getWidth() - mCenterX; mOriginY = mTouchImageView.getY() + mTouchImageView.getHeight() - mCenterY; ma1 = (float) (Math.atan2(mOriginY, mOriginX) * 180 / Math.PI); } private void touchExpandView(View v, MotionEvent event) { switch (event.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: mCorrectionX = event.getRawX() - v.getX(); mCorrectionY = event.getRawY() - v.getY(); initAttribute(); break; case MotionEvent.ACTION_MOVE: v.setX(getDistanceX(event)); v.setY(getDistanceY(event)); setScaleAndRotate(event); break; } } private float getDistanceX(MotionEvent event) { return event.getRawX() - mCorrectionX; } private float getDistanceY(MotionEvent event) { return event.getRawY() - mCorrectionY; } private void setScaleAndRotate(MotionEvent event) { float x2 = mExpendItemView.getX() + INT_EXPAND_WIDTH / 2 - mCenterX; float y2 = mExpendItemView.getY() + INT_EXPAND_HEIGHT / 2 - mCenterY; float a2 = (float) (Math.atan2(y2, x2) * 180 / Math.PI); mTouchImageView.setRotation(a2 - ma1); float r1 = (float) Math.sqrt(mOriginX * mOriginX + mOriginY * mOriginY); float r2 = (float) Math.sqrt(y2 * y2 + x2 * x2); float scale = r2 / r1; mTouchImageView.setScaleX(scale); mTouchImageView.setScaleY(scale); }
入口是touchExpandView, 需要监听OnTouchListener,然后在onTouch执行touchExpandView。
三、原理
1、小图标mExpendItemView的移动
简单的数学知识:
mCorrectionX = event.getRawX() - v.getX();
这个mCorrectionX就是touch点和mTouchImageView左上角的X坐标的距离。这个值在移动的过程中是不变的。
所以,移动的时候,v的x坐标就是:
v.getX() = event.getRawX() - mCorrectionX.
就是上面代码中的函数getDistanceX
2、mTouchImageView的缩放和旋转
很重要的一点,缩放和旋转都是相对于原始大小和角度的。坐标是相对于mTouchImageView的中心点。
所以,先记录原始大小和角度:initAttribute()
缩放的倍数,就是缩放后的半径除以原始大小的半径。半径的算法就是勾股定理。
旋转的角度,就是上图的a2 - a1.
a2和a1的算法就是tan a = y / x.
相关文章推荐
- dyld: Library not loaded: @rpath/QtWidgets.framework/Versions/5/QtWidgets
- 打印到类阵列的给定序列的所有排列的n皇后问题
- 2015 Objective-C 三大新特性
- 查阅参考资料的技巧
- C#/Net代码精简优化技巧(3)
- Spring MVC POST中文乱码解决方案
- Django搭建简单网页的学习笔记 之三(View)
- 【设计模式】——依赖倒转原则
- Android 搜索 把软键盘上的回车键改为搜索
- from声明
- javascript三级联动效果实现2
- 如何使用HibernateTemplate进行分页功能
- Maven搭建SpringMVC+Mybatis项目详解
- libevent之event_base
- ORACLE随机数DBMS_RANDOM包
- [Leetcode]Binary Tree Inorder Traversal
- 同一Activity实例被多次重复创建的解决方法
- C++ 引用
- JSP入门教程之客户端验证、常用输出方式及JSTL基本用法
- 物理引擎中velocity的单位是个什么鬼?