'button appearing on android but not ios
I am playing around with a three.js AR build (using a platform called 8th Wall).
I have a button that turns the volume on my video object on and off. It works fine on android but on iOS it is nowhere to be seen. Any thoughts on why this may be happening?
Here is the HTML with styling:
<!-- The main canvas used for drawing by the app. -->
<h2 style="
position: absolute;
text-align: center;
width: 100vw;
bottom: 0;
left: 50%;
transform: translateX(-50%);
font-family: Menlo, monospace;
text-shadow: 2.5px 2.5px #ff3b30;
font-weight: bold;
letter-spacing: 2px;
font-size: 4.5vw;
color: white;
z-index: 2;"
>8th Wall - Depthkit - three.js</h2>
<style>
.button {
border: none;
color: white;
padding: 10px 10px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
position: fixed;
margin: 0 auto;
cursor: pointer;
}
.button1 {background-color: darkblue;}
</style>
<canvas id="camerafeed"></canvas>
<button class="button button1" id="unmuteButton">UNMUTE</button>
<script src = "threejs-scene-init.js"> </script>
And here is the javascript file, possibly all of which can be ignored for the purposes of this question, except for the button function at the very bottom.
There are more files to this app, but I feel like the problem likely lies between these two files, since these are the two I have modified to add the button.
// Define an 8th Wall XR Camera Pipeline Module that adds a cube to a three scene on startup.
export const initScenePipelineModule = () => {
let depthkit
let character
const capture = 'dk_single'
// Populates a cube into an XR scene and sets the initial camera position.
const initXrScene = ({scene, camera, renderer}) => {
// Add some light to the scene.
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5)
directionalLight.position.set(5, 10, 7)
directionalLight.castShadow = true
scene.add(directionalLight)
depthkit = new Depthkit()
depthkit.meshScalar = 8.0
depthkit.name = 'dk'
depthkit.load(require(`./capture-data/${capture}.txt`),
require(`./assets/captures/${capture}.mp4`),
(dkCharacter) => {
character = dkCharacter
// Position and rotation adjustments
dkCharacter.position.set(0, 2.1, -0.5)
dkCharacter.rotation.set(0.2, -0.1, 0)
dkCharacter.scale.set(1.0, 1.0, -1.0)
// Depthkit video playback control
depthkit.video.muted = 'muted' // Necessary for auto-play in chrome now
depthkit.setLoop(true)
depthkit.setVolume(1)
depthkit.play()
// depthkit.video.muted = false
// Add the character to the scene
scene.add(character)
})
// Add a blob shadow.
const geometry = new THREE.CircleGeometry(1, 32)
const texture = new THREE.TextureLoader().load(require('./assets/shadow.png'))
const material = new THREE.MeshBasicMaterial({map: texture, transparent: true, opacity: 0.4})
const circle = new THREE.Mesh(geometry, material)
circle.rotation.set(-Math.PI / 2, 0, Math.PI / 4)
circle.scale.set(1, 0.8, 1)
scene.add(circle)
// Set the initial camera position is relative to the scene we just laid out. This must be at a
// height greater than y=0.
camera.position.set(0, 2, 2)
}
// Return a camera pipeline module that adds scene elements on start.
return {
// Camera pipeline modules need a name. It can be whatever you want but must be unique within
// your app.
name: 'threejsinitscene',
// onStart is called once when the camera feed begins. In this case, we need to wait for the
// XR8.Threejs scene to be ready before we can access it to add content. It was created in
// XR8.Threejs.pipelineModule()'s onStart method.
onStart: ({canvas}) => {
const {scene, camera, renderer} = XR8.Threejs.xrScene() // Get the 3js scene from XR8.Threejs
initXrScene({scene, camera, renderer}) // Add objects set the starting camera position.
// Sync the xr controller's 6DoF position and camera paremeters with our scene.
XR8.XrController.updateCameraProjectionMatrix(
{origin: camera.position, facing: camera.quaternion}
)
// prevent scroll/pinch gestures on canvas.
canvas.addEventListener('touchmove', event => event.preventDefault())
// Recenter content when the canvas is tapped.
canvas.addEventListener(
'touchstart', (e) => {
if (e.touches.length === 1) {
XR8.XrController.recenter()
}
}, true
)
const btn = document.getElementById("unmuteButton");
btn.addEventListener("click", ()=>{
if(btn.innerText === "UNMUTE"){
btn.innerText = "MUTE"
depthkit.video.muted = false
}else{
btn.innerText= "UNMUTE";
depthkit.video.muted = 'muted'
}
})
},
}
}
Solution 1:[1]
In terms of styling UI elements, it's best to use position: absolute
with a combination of top
, right
, bottom
and right
values. You should also adjust the z-index
to a positive value so it doesn't get hidden behind the camera feed.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Evan Carlson |