Is there a way to set the canvas size to match the exact window size in pixels without being affected by the browser's zoom factor?

I'm currently developing a website called sphere.mars2540.com.

Is there a way in JavaScript or CSS to maintain a fixed canvas size regardless of the zoom level of the page, ensuring it always aligns with the actual pixels on the screen (even with 4k resolution)? I've explored devicePixelRatio, but it doesn't seem to accurately reflect the ratio on my 4k screen.

Appreciate any assistance. Thank you.

Answer №1

In the world of webgl animation using THREE.js, I have discovered a clever solution to determine the zoom ratio for different devices:

function findZoomRatio() {
    var orientation = (screen.orientation || {}).type || screen.mozOrientation || screen.msOrientation;
    if ("userAgentData" in window.navigator && window.navigator.userAgentData.mobile && (orientation === "landscape-primary" || orientation === "landscape-secondary")) {
        return window.devicePixelRatio;
    } else if ("userAgentData" in window.navigator && !window.navigator.userAgentData.mobile && (orientation === "landscape-primary" || orientation === "landscape-secondary")) {
        return window.outerWidth / window.innerWidth;
    } else if (orientation === "portrait-secondary" || orientation === "portrait-primary") {
        return window.devicePixelRatio;
    } else {
        return Math.max(window.devicePixelRatio, window.outerWidth / window.innerWidth);
    }
}
var deviceZoomRatio = findZoomRatio();

After determining the zoom ratio, I then calculate the retina change using the following method:

var retinaChange = window.devicePixelRatio / deviceZoomRatio;

Finally, utilizing the THREE.js API, I adjust the canvas size accordingly, such as:

renderer.setSize(width * deviceZoomRatio * retinaChange, height * deviceZoomRatio * retinaChange);

With this approach, achieving maximum resolution becomes effortless!

Answer №2

As mentioned in this response, it appears that disabling page zooming is not achievable, which is acceptable. Instead, a more practical approach would be to adjust the canvas size to accommodate the current page zoom level (or maintain a consistent canvas size).

Implementing this is straightforward, simply incorporate window.devicePixelRatio into your canvas resizing calculations.

When there is no page zoom, the window.devicePixelRatio variable holds a value of 1 and adjusts accordingly with each zoom operation to reflect the current zoom percentage.

For instance, to always align with window dimensions, use:

function resizeToWindow() {
    canvas.width = window.innerWidth * window.devicePixelRatio;
    canvas.height = window.innerHeight * window.devicePixelRatio;
}

To match the size of the parent container, utilize:

function resizeToParent() {
    canvas.width = canvas.clientWidth * window.devicePixelRatio;
    canvas.height = canvas.clientHeight * window.devicePixelRatio;
}

Apply these or similar styles:

canvas {position: absolute; top: 0; left: 0; width: 100%; height: 100%}

The optimal approach to determine when to invoke the above functions and perform resizing is by leveraging requestAnimationFrame to compare the current canvas dimensions and devicePixelRatio value with those from the previous frame (conduct the comparison per frame but only resize if necessary).

Alternatively, consider utilizing the ResizeObserver API for more precise dimension retrieval through the devicePixelContentBoxSize property, although browser support for this feature remains quite limited at present.

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

Arrange data in JSON file based on job title (role name) category

My current code successfully outputs data from a JSON file, but I'm looking to enhance it by organizing the output based on the "Role Name". For example, individuals with the role of Associate Editor should have their information displayed in one sect ...

Strategies for implementing classes in Typescript

I've been working on incorporating more classes into my project, and I recently created an interface and class for a model: export interface IIndexClient { id?: number; name?: string; user_id?: number; location_id?: number; mindbody_id?: nu ...

Importing libraries in TypeScript and JavaScript are not done in the same manner

As I create my own library, I aim for it to be compatible with both javascript and typescript. tsconfig.json { "compilerOptions": { "target": "es2017", "module": "commonjs", &qu ...

Installing npm modules can be a time-consuming task when running docker-compose

I have been working on a project using Next.js and a PostgreSQL database in a Docker container. The setup of my project involves Docker Compose. However, I've noticed that when I run docker-compose up, the npm install command takes an incredibly long ...

Tips for utilizing browser cache in AJAX requests to prevent loading the refreshed JSON file

It may seem like a strange question, but I'm experiencing an issue with an AJAX call to a JSON file. Both the request and response headers do not indicate to not use cache, and in the browser settings, the Disable cache option is not checked. What mor ...

Extracting ng-template Content into a Variable from the Source

I am trying to save the contents of my template into a variable. Here is how my current code looks: HTML <script type="text/ng-template" id="a.html" src="templates/a.html"></script> JS vm.template = $templateCache.get('a.html'); c ...

Adjusting the dimensions of two pictures side by side using Bootstrap 3

I've been experimenting with Bootstrap to align two images side by side using different columns. I made sure they were aligned properly and even added some background colors for better visibility. However, when I tested the responsive design by chang ...

Is it possible to style a strikethrough item in a list using CSS?

Within this list, I want to use CSS to indent any list item that drops a line. I attempted to achieve this using the following CSS: li:not(::first-line) { text-indent: 15px; } Unfortunately, it doesn't seem to be working as expected. Here is an exa ...

JavaScript Nested Array Looping Script

I am currently working on a loop script for my application that checks for the full capacity of a user array and adds a user ID if there is space available. The data in my JSON file is structured around MongoDB and contains 24 entries (hours). Each entry ...

Achieving a customized CSS ribbon that displays exclusively on specific images sourced from a Django database

I am currently utilizing the Django framework for my project. I have implemented a CSS that applies a ribbon to an image, but I only want this ribbon to appear on certain images stored in the database. Within the HTML file for displaying product details, I ...

What is the best way to trigger an AJAX function every 15 seconds?

As part of my web application, I have implemented a JavaScript function that is triggered by the <body onload> event. Within this function, there is a while loop that continuously iterates until it receives the desired response from a PHP page. Unfo ...

Detecting if the request in Yii Framework 2.0 is coming from an AJAX GET call

While utilizing Yii framework 2.0, I have implemented an AJAX GET jQuery script that references a function within a controller class. $.get('localhost/website/index', {param: 'xxxx'}, function(returnedData){ // some code here..... ...

Combining Javascript and Django for a powerful web development solution

Having trouble setting up JS on my Django web app, despite reading through the documentation and previous queries. Using the Django dev server with the following file structure: mysite/ __init__.py MySiteDB manage.py settings.py ...

Chrome is where all the action happens, while Firefox prefers to keep things on the left

After a long break, I returned to designing my website and re-learning CSS. My approach involved creating a WordPress-integrated site with minimal HTML/PHP work, focusing more on utilizing the available CSS classes and IDs provided by a template theme (Bla ...

Creating stylish horizontal navigation menus using HTML

Is anyone else experiencing issues with a HTML navigation menu on a website using the standard UL LI approach? Whenever I resize the browser window, the menu gets resized as well and the menu items that are outside the viewable area shift downwards. Has an ...

Why won't angularjs interpret my object accurately?

Currently, I am in the process of developing an angularjs application and I have encountered a minor issue. The problem arises when I populate a list of projects and then apply filtering based on certain conditions. Visually, everything appears fine on the ...

There are no documents found with the specified UUID in MongoDB

I have been attempting to retrieve a specific document from MongoDB that includes the field "ownerId" containing a binary UUID. In the Mongo console, when I run the command db.dataset.find({ownerId: BinData(3,"ZQ6EAOKbQdSnFkRmVUUAAA==")}).pretty() The ou ...

I am attempting to monitor the addliquidity event on Uniswap's router02

I am currently attempting to monitor addliquidity events in order to extract data on newly added pairs const Web3 = require('web3'); const NODE_URL = "https://mainnet.infura.io/v3/d3c5832256754c85be86b4c97de2d3d3" const web3 = new We ...

Error occurs when trying to create or delete a folder in Express.js

Implement Folder Creation Code in index.js let companydir = './views/campaigns/' + companyname; if(!fs.existsSync(companydir, { recursive: true })) { fs.mkdirSync(companydir, { recursive: true }); } var dir = companydir + &apo ...

I am interested in developing a program using Javascript or JQuery that can effectively capture the anchor text within <a></a> link tags

I want to automatically capture the link on my website and create a system where, when users click on a specific link, it opens the captured link in a new tab without requiring browser permission and replaces the current tab with a different link. For exa ...