Enhancing 2D video viewing with Threejs interactivity

I want to create an interactive 2D video using three.js and maintain the aspect ratio of the video when resizing the browser window.

Here is the code I am currently using:

var camera, scene, renderer;

var texture_placeholder,
  distance = 500;

init();
render();

function init() {
  var container, mesh;
  container = document.getElementById('container');
  camera = new THREE.PerspectiveCamera(90, 1, 0.1, 50000);
  camera.target = new THREE.Vector3(0, 0, 0);
  scene = new THREE.Scene();
  var videoRatio = 16 / 9;
  var geometry = new THREE.PlaneBufferGeometry(1.7, 1);
  var video = document.createElement('video');
  video.width = 960;
  video.height = 540;
  video.autoplay = true;
  video.loop = true;
  video.mute = true;
  video.setAttribute('crossorigin', 'anonymous');
  video.src = "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"
  var texture = new THREE.VideoTexture(video);
  texture.minFilter = THREE.LinearFilter;
  texture.format = THREE.RGBFormat;

  var material = new THREE.MeshBasicMaterial({
    map: texture
  });

  video.onplay = function() {
    onWindowResize();
  }

  mesh = new THREE.Mesh(geometry, material);

  scene.add(mesh);

  renderer = new THREE.WebGLRenderer({
    depth: true
  });
  renderer.setPixelRatio(window.devicePixelRatio);
  renderer.setSize(window.innerWidth, window.innerHeight);
  container.appendChild(renderer.domElement);

  window.addEventListener('resize', onWindowResize, false);

  var playBtn = document.getElementById("play_btn").onclick = function() {
    console.log("[DEBUG] play button clicked");
    video.play();
    renderer.setSize(window.innerWidth, window.innerHeight);
  }
}

function onWindowResize() {

  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  console.log("[DEBUG] onWindowResize");
}

function render() {
  requestAnimationFrame(render);
  update();
}

function update() {
  camera.updateProjectionMatrix();
  camera.position.z = 0.5;
  renderer.setSize(window.innerWidth, window.innerHeight);
  renderer.render(scene, camera);
}
<script src="//cdnjs.cloudflare.com/ajax/libs/three.js/109/three.js"></script>
<button id="play_btn">play</button>
<div id="container"></div>

Check out the Codepen demo here: https://codepen.io/mr1985/pen/OJVOKgY

I am currently using an iframe to solve the issue with maintaining aspect ratio, but I would prefer to handle it directly with three.js. Here is the code for my iframe for reference:

<style>
  .iframe-container {
    overflow: hidden;
    padding-top: 56.25%;
    position: relative;
  }

  .iframe-container iframe {
    border: 0;
    height: 100%;
    left: 0;
    position: absolute;
    top: 0;
    width: 100%;
  }

</style>
<div class="iframe-container">
  <iframe width="960" height="540" src="http://localhost:8000/mini_player.html" frameborder="0" allowfullscreen scrolling="no"</iframe>
</div>

Any assistance on this matter would be greatly appreciated.

Answer №1

After deleting the specified code snippet, the issue was resolved in the desktop browser:

video.width = 960;
video.height = 540; 

However, the incorrect aspect ratio still persists on mobile devices. In order to prevent the video from playing in fullscreen mode on mobile, I included the following line of code:

video.setAttribute('playsinline', ''); 

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Identify the moment when the SPAN element reappears in sight

I have a question that may have been asked before, but I haven't found a satisfactory answer yet. Within my HTML code, I have a SPAN element with an onclick event, like so: <span onclick='loadDiv()'>Text</span> When a user cli ...

Creating a li active shape involves defining styles for the active state of

I'm having trouble creating a shape in the menu header to show that it's selected with an active class. I've been struggling to bring the shape up and align it properly. Here is what I have attempted: HTML <li class="active"&g ...

How to redirect to a different page within the same route using Node.js

When attempting to access the redirect on the login route using the same route, I first call the homeCtrl function. After this function successfully renders, I want to execute res.redirect('/login'). However, an error occurs: Error: Can't ...

The Animation effect of jQuery Making an Element Move Down

After playing around with a jsFiddle, I'm faced with a dilemma. When I try to animate a "drawer" using jQuery, my text mysteriously jumps down a few pixels during the slide animation. It's puzzling me and I'm struggling to pinpoint the cause ...

Tips for modifying the icon of a div with a click event using vanilla JavaScript

My goal is to create a functionality where clicking on a title will reveal content and change the icon next to the title. The concept is to have a plus sign initially, and upon clicking, the content becomes visible and the icon changes to a minus sign. C ...

Troubleshooting Query Param Problems in EmberJS Route Navigation

("ember-cli": "2.2.0-beta.6") A search page on my website allows users to look for two different types of records: Users or Organizations. The URL for this search page is /search and I have implemented query parameters to maintain the state and enable ba ...

What's the best way to pass parameters through Higher-Order Components in React?

my custom component App import React, { Component } from "react"; import City from "./City"; import withDataLoader from "./withDataLoader"; const MyApp = () => { const MyCity = withDataLoader( City, "https://5e5cf5eb97d2ea0014796f01.mockapi ...

Change the value of the checked property to modify the checked status

This is a miniCalculator project. In this mini calculator, I am trying to calculate the operation when the "calculate" button is pressed. However, in order for the calculations to run correctly in the operations.component.ts file, I need to toggle the val ...

Chrome users may encounter difficulty grabbing the horizontal textarea scrollbar if a border-radius has been applied

Check out this JSFiddle for more information <textarea wrap="off" rows="5" style="border-radius: 4px">aaaaaaaaaaa aaaaaaaaaaa aaaaaaaaaaa aaaaaaaaaaabbbbbbbbbaaaaaaaaaaabbbbbbbbbaaaaaaaaaaabbbbbbbbbaaaaaaaaaaabbbbbbbbbaaaaaaaaaaabbbbbbbbb aa ...

Is there a way to prevent inheriting width properties? Or perhaps how can one revert back to the original width value

After installing the Thank you plugin, I noticed that the button on my test site appears to be strange. Upon further investigation, I discovered that it is inheriting #commentform textarea { width: 45%; } from my theme. While removing the width in the CSS ...

"click on the delete button and then hit the addButton

I have created a website where users can save and delete work hours. I am facing an issue where I can save the hours at the beginning, but once I delete them, I cannot save anything anymore. Additionally, when I reload the page, the deleted data reappears. ...

Retrieve the associative array from the user input by utilizing jQuery

How can I create an associative array from a form containing multiple text inputs using jQuery (or directly in JS)? Here's an example of the form: <form> <input type="text" name="name[13]" value="test 1" /> <input type="text" name="nam ...

How can you stop queuing animations and timeouts in jQuery?

I'm facing a seemingly simple problem that I need help with. On my website, there's a hidden div.notification bar at the top. This bar can be displayed by adding either the success or warning class to it. There are two scenarios: either a messa ...

When using Vue computed, an error is thrown stating "Issue in rendering: 'InternalError: too much recursion'" if the same key is referenced in computed

As a newcomer to Vue, I wanted to track how many times a function in the computed section gets called. To achieve this, I created the following component: const ComputedCounter = { name: "ComputedCounter", template: ` <span>{{ value } ...

Automating image uploads with Selenium and Python even when the element appears hidden

Recently, I've encountered an issue while trying to upload photos using Selenium with Python. The input element appears to be hidden on the page, causing errors when using the .sendkeys method. Here is the HTML code for the input element: <div d ...

Error: Required variable missing in AJAX Post request

When making an ajax call, I use the following code: o.open("POST",q,true); o.setRequestHeader("Content-type","application/x-www-form-urlencoded"); o.setRequestHeader("Content-length",p.length); o.setRequestHeader("Connection","close"); Here, q represent ...

Is there a solution to resolving the type error that I am unable to identify?

I am attempting to implement a custom cursor feature in Vue 3, but unfortunately my code is not functioning as expected. Below you can find the code snippet I have been working on: <template> <div id="cursor" :style="cursorPoi ...

HTML and CSS are distinct entities with their own individual purposes and

Can you create custom entities? For example: &longline; --> ----------------------------- and then incorporate it in HTML code: <div> &longline; bla bl bla </div> ...

Accordion styling using CSS

My current issue lies with setting the style for the contents of an accordion. The problem arises when the styles defined in a CSS file do not take effect on the content of my accordion when using the following code along with a separate CSS file: <scr ...

Switching up the styles in PHP-embedded HTML by tweaking the CSS

I used PHP to create HTML elements by echoing them out, but I ran into an issue when trying to change the CSS for those HTML elements. Can you help me figure out how to do this? The PHP } else { include("steamauth/SteamCo ...