自如-黄进 | 作者

承香墨影 | 编辑

https://juejin.cn/post/6989227733410644005 | 原文

Hi,大家好,这里是承香墨影!

说到裸眼 3D 效果,最先想到的就是利用 MR 实现的虚拟增强技术,例如下图就流传甚广。

但这种效果,通常需要通过 AI 或者使用 MR 再加上后期特效渲染而成。

那么有没有更简单的实现裸眼 3D 的效果呢?

自然是有。裸眼 3D 最基础的原理,就是利用「视觉差」,我们只需要让大脑误认为有层次有景深的感觉,就可以模拟出 3D 的效果。

比如一些常见的 Gif 图,就是利用 2 条辅助线,制造出裸眼 3D 的效果。

比如:

比如:

比如:

既然是利用「视觉差」可以模拟出裸眼 3D 效果,那么我们可以将 UI 视图分层,然后将不同层次的元素,按照不同的速率运动,造成伪立体的感觉,就是一种裸眼 3D 的效果。

这有点像前几年知乎 App 在启动 Banner 里实现的「视差动画」,只是它利用的是 UI 的滚动来带动元素的视差移动,而要实现裸眼 3D 还需要借助传感器,利用 SensorManager 获取到的数据,来偏移某些图层上的元素。

今天推荐一个来自自如大前端研发中心-黄进的一篇文章,讲述他在自如 App 中如何将裸眼 3D 效果应用在首页 Banner 上。

按照惯例,先上效果。

背景

移动端界面设计如此火热的今天,各类大厂的设计规范和设计语言,已经非常的成熟,我们想做一些在这套成熟的设计规范之外的尝试和创新,所以有别于传统的 Banner 交互形式,成为了我们的发力点。

设计理念

由于 App 版面空间有限,除了功能导向、阅读习惯和设计美观外,自如想在既定的框下,做一下不同的设计尝试,哪怕这种尝试只能提升用户 1% 的观感。

可能租了几年自如的房子,用了几年自如客 App,你可能也不会注意到一些小的细节。但如果哪天,作为用户的你突然发现了这个隐藏的 “彩蛋”,看到了自如在这些小细节上的用心,我相信那天你将会对自如这个品牌有更深层次的认识和理解。

裸眼 3D 技术,一般都是应用在裸眼 3D 大屏、全息投影等等比较常见的场景中。在 APP 的 Banner 上应用,的确也是一次全新的尝试。

我们通过借助移动设备上的传感器、以及自身的屏显清晰度、画面呈现,将 2D 影像转化为景深效果,以呈现出不用 "3D" 眼镜就可看到的 3D 效果。

实现方式

以下以 Android 为例,介绍一下该效果的实现方式。

分层

自如客 App 的 Banner 其实一直在创新当中,有专门注意过的同学可能知道,在裸眼 3D 效果之前,自如客 App 其实就已经实现了分层。

当时为了实现更加自然和精致的切换效果:在每个 Banner 滑入滑出的时候,底部其实会在原地进行渐显渐隐,内容会跟随手势滑入滑出。

此次为了实现 3D 效果,我们在以前分层的基础上加了一层中景,将原有的前景拆分为前景和中景。

上图的 sl_bg 为背景,pv_middle 为中景,sl 为前景。

由于切换的交互,实际上 Banner 使用了两个 ViewPager 进行了联动。背景在最底层的 ViewPager 里面,中景和前景在另外一个 ViewPager 里。

跟手位移

打开自如客 App 后,用户操作设备可以明显感受到画面的错位移动,造成视觉上的景深效果。这种错位移动,其实就是借助设备本身的传感器来实现的,具体实现方式,是我们让中景始终保持不动,同时从设备传感器获取当前设备对应的倾斜角,根据倾斜角计算出背景和前景的移动距离,然后执行背景和前景移动的动作。

如下图所示:

为了使用的方便,我们封装了一个 SensorLayout,专门用于根据设备的倾斜角执行内容的位移;SensorLayout 内部的主要实现:

注册对应的传感器

mSensorManager = (SensorManager) getContext().getSystemService(Context.SENSOR_SERVICE);mAcceleSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);mMagneticSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);mSensorManager.registerListener(this, mAcceleSensor, SensorManager.SENSOR_DELAY_GAME);
mSensorManager.registerListener(this, mMagneticSensor, SensorManager.SENSOR_DELAY_GAME);

计算偏转角度

if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {mAcceleValues = event.values;
}
if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {mMageneticValues = event.values;
}float[] values = new float[3];
float[] R = new float[9];
SensorManager.getRotationMatrix(R, null, mAcceleValues, mMageneticValues);
SensorManager.getOrientation(R, values);values[1] = (float) Math.toDegrees(values[1]);values[2] = (float) Math.toDegrees(values[2]);

通过重力传感器和地磁场传感器,获取设备的偏转角度

根据偏转角度执行滑动

if (mDegreeY <= 0 && mDegreeY > mDegreeYMin) {hasChangeX = true;scrollX = (int) (mDegreeY / Math.abs(mDegreeYMin) * mXMoveDistance*mDirection);
} else if (mDegreeY > 0 && mDegreeY < mDegreeYMax) {hasChangeX = true;scrollX = (int) (mDegreeY / Math.abs(mDegreeYMax) * mXMoveDistance*mDirection);
}
if (mDegreeX <= 0 && mDegreeX > mDegreeXMin) {hasChangeY = true;scrollY = (int) (mDegreeX / Math.abs(mDegreeXMin) * mYMoveDistance*mDirection);
} else if (mDegreeX > 0 && mDegreeX < mDegreeXMax) {hasChangeY = true;scrollY = (int) (mDegreeX / Math.abs(mDegreeXMax) * mYMoveDistance*mDirection);
}
smoothScrollTo(hasChangeX ? scrollX : mScroller.getFinalX(), hasChangeY ? scrollY : mScroller.getFinalY());

mDegreeX 即为第二部中获取的偏转角度,mDegreeXMinmDegreeXMax 为 X 轴可发生偏转位移的角度的最大值和最小值,mYMoveDistance 即为 Y 轴上的最大偏移距离(围绕 X 轴发生旋转,视图会沿 Y 轴上发生位移);Y 轴上的偏转同理;就算好 X 轴和 Y 轴的偏移距离后,使用 scroller 进行滑动;

实现总结

读到这里,相信大家已经基本了解了这套 Banner 的实现方案。

Android 端在布局上进行了分层,中景位置不变,借助重力传感器和地磁场传感器获取偏转角度,根据角度使背景和前景进行错位移动。iOS 端的实现原理也基本一致,不再赘述。

墨影小结

正如文章开头讲的,利用「视觉差」实现裸眼 3D 效果,最重要的就是 2 点:

  • UI 视图分层;

  • 利用传感器(SensorManager)让不同层次的元素,规律移动;

关键代码已经在文内展示,有兴趣的可以自己动手实现。再给自己加一个新的封装要求就更好了。例如何封装不同图层元素显式位置的规则,以适应设计师频繁的替换元素而无需修改代码。

-- End --

本文对你有帮助吗?留言、转发、点好看是最大的支持,谢谢!

推荐阅读:

百度技术:“App 优化网络,先从 HTTPDNS 开始” | 原理到实战

Android 架构,拒绝生搬硬套!

Android 的 Window 如何理解?Dialog 到底是不是子窗口?

设计师:裸眼 3D 效果,你们客户端实现很难吗?相关推荐

  1. Android OpenGL 仿自如 APP 裸眼 3D 效果

    概述 之前看到 自如团队 发布的 自如客APP裸眼3D效果的实现 ,非常有趣,不久后,社区内 Android 的开发者们陆续提供了 Flutter. Android 原生 .Android Jetpa ...

  2. 卷起来了!Android OpenGL仿自如APP裸眼3D效果

    /   今日科技快讯   / 近日,"乘联会"微信公众号发布消息,2021年12月新能源乘用车市场多元化发力,厂商批发销量突破万辆的企业有14家,较前期大幅增多,其中:比亚迪933 ...

  3. 怎么设置ppt页面的长度和宽度_在PPT中将照片变裸眼3D效果怎样操作?分享技巧,帮你快速实现...

    PPT的使用相信大家都不陌生,使用最多的就是制作PPT对工作进行汇报,对新项目进行展开讨论.其实在PPT中还可以设计海报,制作高逼格封面以及将照片变为3D效果等偏设计类的操作.今天将以如何把照片变为3 ...

  4. 投影仪的裸眼3D效果

    裸眼3D是指在看投影仪投出来的画面时,不需要戴3D眼镜就能看到立体效果的技术.裸眼3D投影仪通常使用两个投影仪同时投出左右眼图像,利用人眼视差原理来产生立体效果.这种方式看起来比较自然,但是画面质量通 ...

  5. 裸眼 3D 是什么效果?

    作者:沙因,腾讯 IEG 前端开发工程师 介绍一种裸眼 3D 的实现方式,代码以 web 端为例. 平常我们都是戴着 3D 眼镜才能感受 3D 效果,那裸眼能直接看 3D 么?可以看看下面这个视频: ...

  6. 如何让视频产生裸眼3D的效果

    要使视频产生裸眼3D效果,可以使用视差技术或立体投影技术.这需要通过制作两个不同的视频或图像来模拟左眼和右眼的视线,然后使用特殊的投影器或显示器进行投影或显示.

  7. 基于android的裸眼3d,午诺裸眼3D原理其实并不复杂

    午诺裸眼3D原理其实并不复杂 其实同样是裸眼3D手机,可能其中含有的技术却大不相同.午诺P8采用的是国内领先3D光学厂商康得新提供的柱状光栅技术,屏幕通过特殊处理给左右眼的图像是不一样的,消费者面对手 ...

  8. 户外LED显示屏如何实现裸眼3D显示效果:创造逼真立体体验的新视界

    随着科技的不断进步,户外LED显示屏已成为现代广告和娱乐领域中不可或缺的元素.而在这个数字化时代,人们对于视觉体验的要求也越来越高.裸眼3D效果作为一种引人注目的显示技术,为户外LED显示屏注入了全新 ...

  9. 成都太古里,溢出屏幕的裸眼3d

    在成都太古里和春熙路交界处有一块裸眼3D屏,早在十月份的时候就凭借一段酷炫真实的外星飞碟裸眼3d视频登上热搜,刷爆朋友圈,让本就是打卡圣地的太古里再一次上升成为一个网红打卡必经之地. 数字平原有幸参与 ...

最新文章

  1. usaco Prime Palindromes
  2. 未找到要求的 from 关键字_莫纳什大学要求
  3. java jdbc datetime_Java JDBC 操作二进制数据、日期时间
  4. topics in innovation management
  5. 隐藏Android下的虚拟按键
  6. 专题导读:大数据整理
  7. Qt组件中的双缓冲无闪烁绘图
  8. LeetCode 769. Max Chunks To Make Sorted
  9. 简单的机器学习程序_发那科机器人编写简单的程序教程
  10. 【npm】伙计,给我来一杯package.json!不加糖
  11. java 毫秒数一天_java用毫秒数做日期计算的一个踩坑记录
  12. Samba结合Windows AD
  13. springboot 中的 文件、短信、邮件、token 工具类
  14. 机械键盘和普通键盘打字哪个舒服
  15. Python函数里的爱情故事
  16. python3.4勾股定理代码_使用有序数组来解决勾股定理(Python)
  17. Chromium的启动流程
  18. 遇到问题之-cacti监控网卡流量traffic
  19. 阿里云服务器建站教程(5分钟网站上线)
  20. win11 电脑无法连接 win10 USB共享打印机

热门文章

  1. 天翼云应知应会认证重点知识手册
  2. 原创短视频的美好时代,美拍连出两招加速达人变现
  3. 微服务中自定义gateway网关过滤器
  4. 程序员为维持游戏开发被迫炒股,一年内反赚1600万;雷军退任天星银行董事会主席;华为开源Karmada将捐赠CNCF...
  5. 吐槽微软,远离微软!
  6. 天地图卫星地图在OpenLayers中的应用示例源码
  7. unix系统编程c语言,关于unix系统编程的一个小问题
  8. effective C++条款四十三解读
  9. google autoaugment
  10. 中国电子学会和nct哪个证书好,适合报名哪一个呢?