在iOS利用动画实现全景视图
来源:互联网 发布:乐乎社区是什么意思 编辑:程序博客网 时间:2024/06/05 22:52
干货,干货,这个绝对是干货,研究了很久,参考了网上的代码,终于明白了如何利用CATransform3D实现一个全景的观看模式。
整个全景类的项目有两个难点,一是搭建一个正方体的场景,二是通过滑动改变观看的视角
如何搭建一个正方体的场景呢,我们使用CATransform3D里面的透视动画制作
代码如下:
//image1(前) //获取一个标准默认的CATransform3D仿射变换矩阵CATransform3D transform3D = CATransform3DIdentity; //image与六面体中心的角度为(0,0)(hAngel为点与水平位置的角度,vAngle为点与竖直位置的角度。CGFloat tempHAngle=_hAngle;CGFloat tempVAngle=_vAngle; //初始化transform3D = CATransform3DIdentity; //透视效果 /* CGFloat m11(x缩放), m12(y切变), m13(旋转), m14(); CGFloat m21(x切变), m22(y缩放), m23(), m24(); CGFloat m31(旋转), m32(), m33(), m34(透视效果,要操作的这个对象要有旋转的角度,否则没有效果。正直/负值都有意义); CGFloat m41(x平移), m42(y平移), m43(z平移), m44(); m34的默认值是0,我们可以通过设置m34为-1.0 / d来应用透视效果,d代表了想象中视角相机和屏幕之间的距离 */ transform3D.m34 = 1 / -_zoomFactor; //_referenceSide中心点size /* 对于tz来说,值越大,那么图层就越往外(接近屏幕),值越小,图层越往里(屏幕里)。 CATransform3D CATransform3DTranslate (CATransform3D t, CGFloat tx, CGFloat ty, CGFloat tz); 在某个transform3D变换的基础上进行平移变换,t是上一个transform3D,tx,ty,tz对应x,y,z轴的平移 */ //(obj,-referenceSide,0,0),平移transform3D=CATransform3DTranslate(transform3D, _referenceSide*sin(-tempHAngle), -_referenceSide*cos(-tempHAngle)*sin(-tempVAngle), -(_referenceSide*cos(-tempHAngle)*cos(-tempVAngle)-_zoomFactor) ); /* angle参数是旋转的角度,为弧度制 0-2π x,y,z决定了旋转围绕的中轴,取值为-1——1之间,例如(1,0,0),则是绕x轴旋转(0.5,0.5,0),则是绕x轴与y轴中间45度为轴旋转,依次进行计算 CATransform3D CATransform3DMakeRotation (CGFloat angle, CGFloat x, CGFloat y, CGFloat z); 在一个transform3D的基础上进行旋转变换,其他参数如上 CATransform3D CATransform3DRotate (CATransform3D t, CGFloat angle, CGFloat x, CGFloat y, CGFloat z); */ //绕y轴旋转0度transform3D=CATransform3DRotate(transform3D, tempHAngle, 0, 1, 0); if (_imageOver1.image != nil) _imageOver1.layer.transform=CATransform3DRotate(transform3D, tempVAngle, cos(tempHAngle), 0, sin(tempHAngle)); //将3D信息赋值给image_image1.layer.transform=CATransform3DRotate(transform3D, tempVAngle, cos(tempHAngle), 0, sin(tempHAngle)); //iamge2(右) //image2与六面体中心的角度为(-PI/2,0)(hAngel为点与水平位置的角度,vAngle为点与竖直位置的角度。tempHAngle=_hAngle-(M_PI/2);tempVAngle=_vAngle;transform3D = CATransform3DIdentity; transform3D.m34 = 1 / -_zoomFactor; //(obj,referenceside,0,0)transform3D=CATransform3DTranslate(transform3D, _referenceSide*sin(-tempHAngle), -_referenceSide*cos(-tempHAngle)*sin(-tempVAngle), -(_referenceSide*cos(-tempHAngle)*cos(-tempVAngle)-_zoomFactor) ); //绕y轴旋转-90度transform3D=CATransform3DRotate(transform3D, tempHAngle, 0, 1, 0); if (_imageOver2.image != nil) _imageOver2.layer.transform=CATransform3DRotate(transform3D, tempVAngle, cos(tempHAngle), 0, sin(tempHAngle));_image2.layer.transform=CATransform3DRotate(transform3D, tempVAngle, cos(tempHAngle), 0, sin(tempHAngle)); //image3(后) //image3与六面体中心的角度为(-PI,0)(hAngel为点与水平位置的角度,vAngle为点与竖直位置的角度。tempHAngle=_hAngle-(M_PI);tempVAngle=_vAngle;transform3D = CATransform3DIdentity; transform3D.m34 = 1 / -_zoomFactor;transform3D=CATransform3DTranslate(transform3D, _referenceSide*sin(-tempHAngle), -_referenceSide*cos(-tempHAngle)*sin(-tempVAngle), -(_referenceSide*cos(-tempHAngle)*cos(-tempVAngle)-_zoomFactor) );transform3D=CATransform3DRotate(transform3D, tempHAngle, 0, 1, 0); if (_imageOver3.image != nil) _imageOver3.layer.transform=CATransform3DRotate(transform3D, tempVAngle, cos(tempHAngle), 0, sin(tempHAngle));_image3.layer.transform=CATransform3DRotate(transform3D, tempVAngle, cos(tempHAngle), 0, sin(tempHAngle)); //image4(左) //image4与六面体中心的角度为(-3*PI/2,0)(hAngel为点与水平位置的角度,vAngle为点与竖直位置的角度。 tempHAngle=_hAngle-(3*M_PI/2);tempVAngle=_vAngle;transform3D = CATransform3DIdentity; transform3D.m34 = 1 / -_zoomFactor;transform3D=CATransform3DTranslate(transform3D, _referenceSide*sin(-tempHAngle), -_referenceSide*cos(-tempHAngle)*sin(-tempVAngle), -(_referenceSide*cos(-tempHAngle)*cos(-tempVAngle)-_zoomFactor) ); //绕y轴旋转180transform3D=CATransform3DRotate(transform3D, tempHAngle, 0, 1, 0); if (_imageOver4.image != nil) _imageOver4.layer.transform=CATransform3DRotate(transform3D, tempVAngle, cos(tempHAngle), 0, sin(tempHAngle));_image4.layer.transform=CATransform3DRotate(transform3D, tempVAngle, cos(tempHAngle), 0, sin(tempHAngle)); //image5(上) //image5与六面体中心的角度为(0,-PI/2)(hAngel为点与水平位置的角度,vAngle为点与竖直位置的角度tempHAngle=_hAngle;tempVAngle=_vAngle-(M_PI/2);transform3D = CATransform3DIdentity; transform3D.m34 = 1 / -_zoomFactor;transform3D=CATransform3DTranslate(transform3D, 0, -_referenceSide*sin(-tempVAngle), -(_referenceSide*cos(-tempVAngle)-_zoomFactor) );transform3D=CATransform3DRotate(transform3D, tempVAngle, 1,0,0); if (_imageOver5.image != nil) _imageOver5.layer.transform=CATransform3DRotate(transform3D, tempHAngle, 0, 0, 1);_image5.layer.transform=CATransform3DRotate(transform3D, tempHAngle, 0, 0, 1); //image6(下) //image6与六面体中心的角度为(0,PI/2)(hAngel为点与水平位置的角度,vAngle为点与竖直位置的角度 tempHAngle=_hAngle;tempVAngle=_vAngle+(M_PI/2);transform3D = CATransform3DIdentity; transform3D.m34 = 1 / -_zoomFactor;transform3D=CATransform3DTranslate(transform3D, 0, -_referenceSide*sin(-tempVAngle), -(_referenceSide*cos(-tempVAngle)-_zoomFactor) );transform3D=CATransform3DRotate(transform3D, tempVAngle, 1,0,0); if (_imageOver6.image != nil) _imageOver6.layer.transform=CATransform3DRotate(transform3D, -tempHAngle, 0, 0, 1);_image6.layer.transform=CATransform3DRotate(transform3D, -tempHAngle, 0, 0, 1);
这样就能够通过透视动画搭建一个正方体了(里面基本都是用的三角函数的知识)
下一步是怎么实现物体能够随手势进行平移
#pragma mark GestureRecognizers//平移手势- (void)didPan:(UIPanGestureRecognizer *)gestureRecognizer { if (gestureRecognizer.state==UIGestureRecognizerStateBegan) { if (_delegate && _delegateBeginPan) { [_delegate panoViewWillBeginPanning:self]; }}if (gestureRecognizer.state==UIGestureRecognizerStateBegan ||gestureRecognizer.state==UIGestureRecognizerStateChanged) {CGPoint translation=[gestureRecognizer translationInView:self];CGFloat newHAngle = self.hAngle-(translation.x/(_zoomFactor/1.5));CGFloat newVAngle = self.vAngle+(translation.y/(_zoomFactor/1.5));if (newHAngle>0 && _rightLimit!=0) {if (newHAngle>_rightLimit) {newHAngle=_rightLimit;}}else if (newHAngle<0 && _leftLimit!=0) {// negative angle to the left, but limit is always positive (absolute value)if (newHAngle<(-_leftLimit)) {newHAngle=-_leftLimit;}}if (newVAngle>0 && _upLimit!=0) {if (newVAngle>_upLimit) {newVAngle=_upLimit;}}else if (newVAngle<0 && _downLimit!=0) {// negative angle to the bottom, but limit is always positive (absolute value)if (newVAngle<(-_downLimit)) {newVAngle=-_downLimit;}}_hAngle=newHAngle;_vAngle=newVAngle;[self render];[gestureRecognizer setTranslation:CGPointZero inView:self]; if (_delegate && _delegateDidPan) { [_delegate panoViewDidPan:self]; }} if (gestureRecognizer.state==UIGestureRecognizerStateEnded) { if (_delegate && _delegateEndPan) { [_delegate panoViewDidEndPanning:self]; }}}
至于捏合,放大手势就自己写吧,如果想要完整的代码,我近期会上传到github上面的。
这个透视原理不难,最恶心的还是三角函数的计算。。。
0 0
- 在iOS利用动画实现全景视图
- unity3d利用pano2VR实现全景视图效果
- unity3d利用pano2VR实现全景视图效果
- iOS全景视图
- 利用OpenGL实现IOS上VR全景图
- IOS视图切换实现简单动画
- IOS 利用UIImageView实现加载动画
- iOS利用UIView实现渐变动画
- ios视图缩放动画
- ios视图缩放动画
- iOS视图动画效果
- iOS视图切换动画
- iOS 视图抖动动画
- iOS 在TabBarController视图切换的时候添加动画
- 利用threejs实现3D全景图
- iOS -UI-视图创建及动画的实现
- iOS项目开发实战——实现视图切换动画
- 实现视图的动画
- Linux安全漏洞审计工具Lynis
- OpenCV图像数据类型Mat不再陌生
- JavaScript异步处理
- DDS信号发生器的实现(内含代码资料)
- Linux kernel oops panic 调试技巧
- 在iOS利用动画实现全景视图
- 如何获取.JTL文件
- canvas渐变圆动画
- 大数据职业规划的N种正确姿势
- 滑动窗口
- Problem loading url: http://chrome-devtools-frontend.appspot.com 问题的解决方案
- caffe中各种cblas的函数使用总结
- supervisor运行golang守护进程
- STM32命名方法