Mark Ku's Blog

Problem

We plan to launch a new computer case with a 4K touch screen. We intended to showcase product features in 3D, but we tried a lot of instructional video texture tutorials and none of them worked properly in iOS 16. 白色電腦機殼前螢幕顯示俄羅斯方塊遊戲

iOS has many limit. I tried many times and sorted out the key points

  • Using native html video outside of Three.js canvus
  • Video must be mutte
  • Disable auto play
  • playsInline
  • crossOrigin="anonymous"
  • display none
  • Video url must have full domain name with https

Source Code

Using native html video outside of Three.js canvus

<Canvas>
...
</Canvas>
  <video
                        id="video"
                        playsInline
                        webkit-playsinline
                        muted
                        loop
                        style={{ display: 'none' }}
                        crossOrigin="anonymous"
                    >
                        <source src={videoUrl} type="video/mp4"></source>
                    </video>

Using Video Texture


import { SHOW_ROOM_3D_URL } from '@/const/const-3d';
import { CanvasContext } from '@/lib/context/3d-showroom/canvas-context';
import { useGLTF, useTexture } from '@react-three/drei';
import React, { useContext } from 'react';
import * as THREE from 'three';
import { GLTF } from 'three-stdlib';

type GLTFResult = GLTF & {
    nodes: {
        Cube: THREE.Mesh;
    };
    materials: {
        ['default']: THREE.MeshStandardMaterial;
    };
};

type ContextType = Record<string, React.ForwardRefExoticComponent<JSX.IntrinsicElements['mesh']>>;

export function VideoCanvas(props: JSX.IntrinsicElements['group']) {
    const { nodes, materials } = useGLTF(SHOW_ROOM_3D_URL + 'y70/video-canvas.glb') as GLTFResult;

    const {
        videoPlay: { isPlaying },
    } = useContext(CanvasContext);

    const touchScreenImgTexture = useTexture(SHOW_ROOM_3D_URL + 'y70/hyte-y70-case-touch-screen.png');
    const video = document.getElementById('video');

    const VideoMaterial = () => {
        if (video instanceof HTMLVideoElement) {
            const texture = new THREE.VideoTexture(video);

            texture.wrapS = THREE.RepeatWrapping;
            texture.wrapT = THREE.RepeatWrapping;
            texture.repeat.x = -1; //  -1 為鏡像翻轉
            texture.flipY = true;

            texture.repeat.set(1, 1);

            return (
                <mesh
                    scale={[2.8, 2, 1]}
                    rotation={[0, -Math.PI / 4, 0]}
                    geometry={nodes.Cube.geometry}
                    material={materials.default}
                    castShadow
                >
                    <planeGeometry />
                    {isPlaying && <meshBasicMaterial side={THREE.FrontSide} map={texture} toneMapped={false} />}
                    {!isPlaying && (
                        <meshBasicMaterial side={THREE.FrontSide} map={touchScreenImgTexture} toneMapped={false} />
                    )}
                </mesh>
            );
        }
        return <></>;
    };

    return (
        <group {...props} dispose={null}>
            <mesh
                geometry={nodes.Cube.geometry}
                material={materials.default}
                position={[-0.114, 0.253, 0.1925]}
                rotation={[0, Math.PI / 4, 0]}
                scale={[0.0001, 0.175, 0.054]}
            >
                <VideoMaterial />
            </mesh>
        </group>
    );
}

useGLTF.preload(SHOW_ROOM_3D_URL + 'y70/video-canvas.glb');

Result

it's work for us. Hope it can help you too. 白色電競電腦機殼的3D模型與客製化介面

作者

Mark Ku

擁有 10+ 年經驗的資深軟體工程師,現為 AI 應用 Builder,專注於大型平台架構與簡化複雜系統設計,從電商系統到訂閱與收費平台,結合 AI Agent、AI 整合與自動化開發,打造高效率且可持續演進的產品技術基礎。閱讀更多

覺得這篇有幫助?

作者做的免費工具、每日 Podcast 與電子報,都在這裡。

Mark Ku · 本文採用 CC BY 4.0 授權,轉載請註明作者並附上原文連結。

留言

訂閱電子報

訂閱後即時收到新文章通知,不錯過任何技術分享。

提交即表示同意接收電子報,隨時可

熱門文章

View all
Mark Ku
··604

Oracle Cloud 永久免費方案 Linux 主機及固定 IP :0 元打造雲端解決方案

Oracle Cloud 永久免費方案 Linux 主機及固定 IP :0 元打造雲端解決方案
Mark Ku
··471

告別 Postman 收費陷阱!開源 Git 原生 API 測試神器 Bruno 實戰指南

告別 Postman 收費陷阱!開源 Git 原生 API 測試神器 Bruno 實戰指南
Mark Ku
··329

一款免費開源類似於 Notion 類知識庫系統 — Outline Wiki 佈署與備份全攻略

一款免費開源類似於 Notion 類知識庫系統 — Outline Wiki 佈署與備份全攻略
Mark Ku
··240

打造高效 API 管理平台:從 0 開始部署 Kong Gateway - Part 1

打造高效 API 管理平台:從 0 開始部署 Kong Gateway - Part 1
Mark Ku
··235

訓練自己的 AI 語音:硬體門檻、開源模型比較與 LoRA 微調

訓練自己的 AI 語音:硬體門檻、開源模型比較與 LoRA 微調
Mark Ku
··216

在 Ubuntu 上設置 Samba 來共享資料夾,讓 Windows 11 用戶可以存取

在 Ubuntu 上設置 Samba 來共享資料夾,讓 Windows 11 用戶可以存取