Issue encountered with updating canvas texture twice in A-Frame and pdf.js while operating in virtual reality mode

Using the power of A-Frame and pdf.js, I embarked on a quest to build an incredible VR application for viewing PDF files. Everything seemed to be working seamlessly on my desktop - flipping through PDF pages, rendering them onto a canvas, it was a sight to behold.

However, the real challenge arose when I attempted to run the application in a VR-enabled browser, specifically on my trusty Quest 2. The first attempt went swimmingly, but when it came to rendering the second page of another document onto the canvas... well, let's just say things took a mysterious turn. The new image refused to show up until I decided to exit VR mode, at which point it magically appeared, much to my bewilderment.

I delved deep into the trenches, tirelessly setting the material map.needsUpdate again and again in an A-Frame component tick loop, only to be met with no avail. As I continued my experimentation, I made a curious observation - trying to render a new page of a PDF a second time and then attempting for a third time (taking the adventurous leap of advancing by two pages while in VR), only to find that upon exiting VR mode, the texture from the second attempt was the only one that stuck. It seemed like the data from the third render had vanished into thin air. I began to ponder if these anomalies were somehow interlinked to the core issue at hand.

For those brave souls who wish to venture forth, a snippet of code for a scaled-down demonstration is provided below. And should you dare to take on the challenge yourself, a live version awaits your exploration at . Feel free to scrutinize the example in desktop mode - advance to the next page by unfurling the browser JavaScript console and entering testBook.nextPage();, and witness the ever-changing images in all their glory. Should you dare to don your VR gear and take the plunge with a Quest headset, a simple press of the A button shall guide you to the next page.

And so, the burning question lingers in the air like a mist in the night - how does one triumphantly render multiple pages of a PDF document onto the same canvas, time and time again, whilst ensnared in the enigmatic realm of VR mode within the illustrious plane of A-Frame?

Answer №1

Discovered a solution here:

Issue with requestAnimationFrame not triggering in WebXR

This is significant because pdf.js utilizes requestAnimationFrame as the default method for rendering images on the canvas.

However, there is an option to toggle this behavior - the pages render function contains an option intent, which is later used to decide whether to employ requestAnimationFrame.


The sources being referenced may be slightly different (possibly older?), but if you focus on creating the InternalRenderTask in the render function of the ProxyPDFPage - everything is outlined there:

const internalRenderTask = new InternalRenderTask({
  callback: complete,
  params: {
    canvasContext,
    viewport,
    transform,
    imageLayer,
    background
  },
  objs: this.objs,
  commonObjs: this.commonObjs,
  operatorList: intentState.operatorList,
  pageIndex: this._pageIndex,
  canvasFactory: canvasFactoryInstance,
  webGLContext,
  useRequestAnimationFrame: renderingIntent !== "print",
  pdfBug: this._pdfBug
});

You can adjust the intent to print within your renderContext object:

// 'interactive-pdf'.render()
const renderContext = {
          canvasContext: context,
          viewport: pageViewport,
          intent: "print"
};
const renderTask = page.render(renderContext);

And it appears to be functioning correctly:

https://i.sstatic.net/xI337.gif

There may be potential unforeseen consequences when setting the intent to print (as it impacts other settings), so disabling useRequestAnimationFrame in the source code also resolves the issue.

Explore the version with the 'print' intent, or the one with the adjusted pdfjs source code.

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

Feed information into a Select element from the Material UI version 1 beta

Having trouble populating data from a < Select > component in Material UI version 1.0.0.0 beta. Snippet of my code: This section is located inside the render() method. <Select value={this.state.DivisionState} onChange={this.handleChang ...

Having trouble with rendering prop values in Vue.js?

Struggling to develop an ajax form component in vuejs within a Laravel 5.3 application. It seems I am facing some challenges with displaying the form fields. Can someone lend me a hand? Here is the front end code for rendering the form: <ajax-form ...

What is a more efficient method for obtaining the current URL in isomorphic React applications that works on both the client and server side?

Currently, I am working on developing an app utilizing a React Redux boilerplate that can be found here. One of the components requires access to the current URL upon mounting in order to generate a shareable link for social media. This component is acces ...

The HTMLElement type does not include the Ionic typescript property

I am currently using Ionic v3 with TypeScript. My goal is to store the file_url in an array after checking if its width is equal to twice its height. However, I am encountering an error: The 'name_array' property does not exist on the ' ...

Using JQuery to create an animated slideToggle effect for a multicolumn list

I have a large list where each li element has a width of 33%, resulting in 3 columns: computers monitors hi-fi sex-toys pancakes scissors Each column contains a hidden UL, which is revealed through slideToggle on click. JQuery $('.subCate ...

Leveraging PHP JSON responses for decision-making in jQuery/JavaScript

Recently, a friend shared the following code snippet with me: json : { result: true } success function(data){ if(data.result) { //do something here } else { //do something here } } I'm curious how I can integrate that ...

Refresh the Data Displayed Based on the Information Received from the API

As someone who is relatively new to React, I have been making progress with my small app that utilizes React on the frontend and a .NET Core API on the server-side to provide data. However, I have encountered a problem that I've been grappling with fo ...

Discovering the lengthiest strings in a multi-dimensional array using JavaScript

let lists = ["Grocery", "Clothing", "Furniture"]; let items = [ [ "tomatoes", "cheese", "bread", "ham" ], [ "shirt", "jacket", "jeans" ], [ "sofa", "carpet", "bed" ] ]; These two arrays are connected in ...

The React form is only transmitting a single property from the state instead of the complete state

My current challenge involves sending form data from my react client to my nodejs server. The issue I am facing is that only the last property of the state gets sent to the server upon form submission. This problem seems to be occurring on the client side, ...

Are DOM Events compatible with ajax-loaded content that cannot be unloaded?

How should events be managed with ajax-loaded content that can be hidden or displayed? I have created a sidebar in HTML that toggles visibility on click, along with two pages that are loaded using ajax. When the sidebar is hidden or displayed, I need to ...

The People and Groups selection dialog is displaying incorrectly in IE 10

I've been working on a Sharepoint web application and have created a site column of type “People or Group”. This should be automatically associated with a user selection dialog as shown below: However, as you can see in the image above, the users ...

Vue struggles to handle data coming from a composable function

For my specific case, I need to verify whether the user has subscribed to my product through both Stripe and Firebase. To accomplish this, I created a composable function that checks for the current subscription in the Firebase collection. If the user cur ...

Incorporate functionality into a button using jQuery

I am working on a table that displays data in different levels (Parent, Child, Grandson). When I click on the parent row, it expands to show new rows related to the child level. Similarly, clicking on a child row reveals a third level known as the grandson ...

Issue with pushing inner list<object> in Knockout version 3.2.0

Currently, I am working with knockout.js on an ASP application. The issue I am facing involves a list of objects returned by the controller action to the view, where the objects in the list point to another list of objects. My struggle lies in adding new o ...

Creating audio streams using react-player

I am currently working on integrating the react-player component from CookPete into my website. However, I am facing a challenge in setting up multiple audio streams. Additionally, I want to include both DASH and HLS video streams but adding them as an arr ...

What are some effective solutions for resolving design problems in Isotope?

When I append the ajax coding, the data is coming fine. However, when I append this style="position: absolute; left: 468px; top: 0px;" css to the new appended data, it is not working. How can I achieve this? Below is my ajax code. Please provide suggestion ...

using database URL as an AJAX parameter

I am currently working on a Python CherryPy controller that needs to validate a database URL by attempting a connection. However, I am facing challenges with passing the parameter to the method. Below is my AJAX call: $.ajax({ async: false, ty ...

What could be causing the issue with my custom AlloyEditor UI extension?

After following the instructions in this guide to integrate alloyeditor as a WYSIWYG editor into Contentful, I successfully added the extension to my contentful staging space. However, despite copying the html page from the github repository and includin ...

Adding a plane to a Three.js scene

When attempting to introduce a plane into the scene, I noticed that nothing is added when checking the children's scene. var newPlane = new THREE.Mesh( new THREE.PlaneGeometry( 2000, 2000, 8, 8 ), new THREE.MeshBasicMaterial( { color: 0xffff00, opaci ...

What is the reason behind the significant 80% reduction in PNG files by grunt-contrib-imagemin compared to the minimal reduction of less than 0.1%

Just getting started with Grunt here. Recently, I've been experimenting with grunt-contrib-imagemin. When it comes to compressing PNG files, it does an impressive job. It typically reduces the size by around 80%. However, I'm finding that the ...