I'm learning three.js, and I'm implementing it in my angular 11 project, I made a very simple demo using a SphereBufferGeometry, and I deployed it to github pages, when I'm browsing it on an android phone, it's working normally, but when I open it on an iphone (safari), all the UI disappear and all I see is a grey background
this is my component ts file:
import { Component, OnInit } from '@angular/core';
import * as THREE from 'three'
import * as dat from 'dat.gui'
@Component({
selector: 'app-three-c',
templateUrl: './three-c.component.html',
styleUrls: ['./three-c.component.css']
})
export class ThreeCComponent implements OnInit {
constructor() { }
ngOnInit(): void {
this.initThreeComponent()
}
initThreeComponent() {
// const gui = new dat.GUI()
//loading
const textureLoader = new THREE.TextureLoader();
const normalTexture = textureLoader.load('assets/images/NormalMap.png')
normalTexture.minFilter = THREE.LinearFilter;
// Canvas
const canvas = document.querySelector('canvas.webgl')
// Scene
const scene = new THREE.Scene()
// Objects
const geometry = new THREE.SphereBufferGeometry(.5, 64, 64);
// Materials
const material = new THREE.MeshStandardMaterial()
material.metalness = 0.7
material.roughness = 0.2
material.normalMap = normalTexture
material.color = new THREE.Color(0x292929)
// Mesh
const sphere = new THREE.Mesh(geometry, material)
scene.add(sphere)
// Lights
const pointLight = new THREE.PointLight(0xffffff, 0.1)
pointLight.position.x = 2
pointLight.position.y = 3
pointLight.position.z = 4
scene.add(pointLight)
//Red light
const pointLight2 = new THREE.PointLight(0xff0000, 2)
pointLight2.position.set(-1.86,1,-1.65)
pointLight2.intensity = 10
scene.add(pointLight2)
// const redlightGUI = gui.addFolder('Red Light')
// redlightGUI.add(pointLight2.position, 'y').min(-3).max(3).step(0.01)
// redlightGUI.add(pointLight2.position, 'x').min(-6).max(6).step(0.01)
// redlightGUI.add(pointLight2.position, 'z').min(-3).max(3).step(0.01)
// redlightGUI.add(pointLight2, 'intensity').min(0).max(10).step(0.01)
// const pointLight2color = {
// color: 0xff0000
// }
// redlightGUI.addColor(pointLight2color, 'color')
// .onChange(()=>{
// pointLight2.color.set(pointLight2color.color)
// })
//Light Helper
// const pointelighthelper1 = new THREE.PointLightHelper(pointLight2, 1)
// scene.add(pointelighthelper1)
//Blue light
const pointLight3 = new THREE.PointLight(0x96ff, 2)
pointLight3.position.set(2.15,-1.56,-1.65)
pointLight3.intensity = 10
scene.add(pointLight3)
// const bluelightGUI = gui.addFolder('Blue light')
// bluelightGUI.add(pointLight3.position, 'y').min(-3).max(3).step(0.01)
// bluelightGUI.add(pointLight3.position, 'x').min(-6).max(6).step(0.01)
// bluelightGUI.add(pointLight3.position, 'z').min(-3).max(3).step(0.01)
// bluelightGUI.add(pointLight3, 'intensity').min(0).max(10).step(0.01)
// const pointLight3color = {
// color: 0x96ff
// }
// bluelightGUI.addColor(pointLight3color, 'color')
// .onChange(()=>{
// pointLight3.color.set(pointLight3color.color)
// })
//Light Helper
// const pointelighthelper2 = new THREE.PointLightHelper(pointLight3, 1)
// scene.add(pointelighthelper2)
/**
* Sizes
*/
const sizes = {
width: window.innerWidth,
height: window.innerHeight
}
window.addEventListener('resize', () => {
// Update sizes
sizes.width = window.innerWidth
sizes.height = window.innerHeight
// Update camera
camera.aspect = sizes.width / sizes.height
camera.updateProjectionMatrix()
// Update renderer
renderer.setSize(sizes.width, sizes.height)
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
})
/**
* Camera
*/
// Base camera
const camera = new THREE.PerspectiveCamera(75, sizes.width / sizes.height, 0.1, 100)
camera.position.x = 0
camera.position.y = 0
camera.position.z = 2
scene.add(camera)
// Controls
// const controls = new OrbitControls(camera, canvas)
// controls.enableDamping = true
/**
* Renderer
*/
const renderer = new THREE.WebGLRenderer({
canvas: canvas,
alpha: true,
})
// renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(sizes.width, sizes.height)
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
/**
* Animate
*/
document.addEventListener('mousemove', onDocumentMouseMove)
let mouseX = 0;
let mouseY = 0;
let targetX = 0;
let targetY = 0;
const windowX = window.innerWidth / 2;
const windowY = window.innerHeight / 2;
function onDocumentMouseMove(event) {
mouseX = (event.clientX - windowX)
mouseY = (event.clientY - windowY)
}
const updateSphere = (event)=>{
sphere.position.y = window.scrollY * .001
}
window.addEventListener('scroll', updateSphere )
const clock = new THREE.Clock()
const tick = () => {
targetX = mouseX * .001
targetY = mouseY * .001
const elapsedTime = clock.getElapsedTime()
// Update objects
sphere.rotation.y = .50 * elapsedTime
sphere.rotation.y = .5 * (targetX - sphere.rotation.y)
sphere.rotation.x = .05 * (targetY - sphere.rotation.x)
sphere.position.z = -.5 * (targetY - sphere.rotation.x)
// Update Orbital Controls
// controls.update()
// Render
renderer.render(scene, camera)
// Call tick again on the next frame
window.requestAnimationFrame(tick)
}
tick()
}
}
this is my component's html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ThreeJS Starter</title>
</head>
<body>
<div class="container">
<div class="h-100 row align-items-center">
<h1 class="col">Feel The Sphere</h1>
</div>
</div>
<canvas class="webgl"></canvas>
<section></section>
</body>
</html>
and please find below a link to my web app: https://paul-obd.github.io/3D-p1/
Note that I'm using Angular 11.2.8 and ThreeJS 0.136.0
Found the solution in this discussion , and all I did was changing "buildOptimizer"
to false
in angular.json file.