Skip to content
Go back

用 36 张图片实现可滑动的车型全景展示

车型外观很难由单张图片完整表达。用户希望从侧面、正面和车尾连续观察一辆车,但在小程序中直接引入复杂三维渲染,资源成本和运行成本都不低。

一种更直接的方案是准备一组按角度拍摄的车辆图片。例如一圈提供 36 张图片,每张对应 10 度角度;用户左右滑动时,页面按照滑动距离切换当前展示帧,在视觉上形成围绕车辆转动的效果。

这套方案没有真正改变模型视角,但在图片质量和交互节奏处理合适时,能够以比较稳定的方式提供全景浏览体验。

将手势距离映射成图片帧

实现的核心是建立滑动距离与帧序号之间的关系:

36 张图片 = 360 度每切换一帧 = 10 度视觉变化用户每横向移动一定像素 = 切换一帧

在小程序组件中可以保存起始触点和当前帧:

Component({  properties: {    frames: Array  },  data: {    currentFrame: 0  },  lifetimes: {    attached() {      this.startX = 0;      this.startFrame = 0;      this.pixelsPerFrame = 8;    }  },  methods: {    handleTouchStart(event) {      this.startX = event.touches[0].clientX;      this.startFrame = this.data.currentFrame;    },    handleTouchMove(event) {      const currentX = event.touches[0].clientX;      const delta = currentX - this.startX;      const movedFrames = Math.round(delta / this.pixelsPerFrame);      const nextFrame = this.normalizeFrame(this.startFrame - movedFrames);      if (nextFrame !== this.data.currentFrame) {        this.setData({ currentFrame: nextFrame });      }    },    normalizeFrame(frame) {      const total = this.data.frames.length;      return (frame % total + total) % total;    }  }});

这里需要使用循环索引:从第 35 帧继续向右拖动时,应当自然回到第 0 帧,而不是突然停止。

帧切换密度影响操作手感

pixelsPerFrame 太小,手指轻微移动就会快速跳过许多图片,用户会感觉画面失控;数值太大,拖动半个屏幕仍然只变化很小角度,车辆又会显得转不动。

这个参数需要结合屏幕宽度和图片数量调整。也可以限制单次移动触发的更新频率,避免高频 touchmove 带来不必要的视图更新:

handleTouchMove(event) {  if (this.updating) return;  this.updating = true;  requestAnimationFrame(() => {    this.updateFrameByTouch(event);    this.updating = false;  });}

具体平台对动画回调的支持和表现需要验证;原则是同一帧内不反复执行无价值更新。

图片没有准备好,交互就会闪烁

如果用户第一次拖动时才加载下一张图片,效果通常会变成空白和闪烁交替出现。因此,进入展示区域前需要预取关键帧。

比较实用的策略是分批加载:

  1. 首先加载默认角度及相邻若干帧,让首屏尽快可用。
  2. 首屏展示完成后,再补齐其余帧。
  3. 用户开始交互前,如果完整帧还未准备好,给出加载反馈。

在模板层可以仅显示当前图片,同时利用隐藏图片或平台图片缓存能力预热其他资源:

<view class="car-view" bindtouchstart="handleTouchStart" bindtouchmove="handleTouchMove">  <image class="car-view__current" src="{{frames[currentFrame]}}" mode="widthFix" /></view>

36 张图的体积不能忽略。图片尺寸应贴合实际显示区域,并根据展示质量选择合理压缩等级,否则一个看似简单的交互会明显拖慢首屏和消耗流量。

需要处理手势冲突

车型展示通常嵌在可上下滚动的页面中。用户手势略微倾斜时,需要判断当前操作更像横向旋转还是纵向浏览页面:

const horizontal = Math.abs(deltaX);const vertical = Math.abs(deltaY);if (horizontal > vertical && horizontal > threshold) {  // 接管为车型旋转交互}

只有横向意图比较明确时才阻止页面滚动,能避免用户经过展示区域时页面突然无法上下浏览。

图片帧方案与三维渲染的边界

图片帧方案的优点很清楚:

它也有明显限制:用户只能沿预设角度浏览,不能自由改变视角或光照,图片数量增加后资源体积也会扩大。后续使用三维模型渲染可以获得更自然的视角变化和更强的交互表现,但会带来模型资源、渲染性能和设备兼容性的新问题。

对于需要快速提供车辆环绕观察能力的小程序页面,36 帧图片是一套实用而有效的折中方案。它的难点不在于显示一张图片,而在于把预加载、触摸判断、切帧节奏与资源体积共同控制好。


Share this post on: