What methods can be used to dynamically pan the entire picture in a programmatic way?

I have a massive div measuring 11500x11500 pixels that contains 400 images, causing it to overflow the viewport.

My goal is to programmatically pan across the entire div.

I'm aiming to create an animation that pans the entire div from top to bottom, left to right by the end of the animation.

Currently, I am dividing my 11500x1500 div into tiles, with each tile's maximum width and height matching that of the viewport.

After storing the coordinates of each tile, I randomly select one, pan it from left to right, and then proceed to the next tile.

My main queries are:

  1. Whether my method is correct or if there are any optimizations I could make in my calculations/approach to ensure that I'm panning the entire div accurately.
  2. Whether it's possible to make the panning effect feel more natural and organic. My current approach involves panning each tile from left to right sequentially, which feels rigid and formal. Is there a way to introduce randomness or angles in the panning motion while still ensuring complete coverage of the div?

Thanks in advance for any assistance.

This is the jsfiddle and here is the code snippet (each "image" is actually a div containing its index as text for testing purposes):

function forMs(time) {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve()
    }, time)
  })
}

let container = document.getElementById('container')

let {
  width,
  height
} = container.getBoundingClientRect()

let minLeft = window.innerWidth - width
let minTop = window.innerHeight - height

let i = 0
while (i < 400) {
  // adding "image" to the container
  let image = document.createElement('div')

  // add some text to the "image" 
  // to know what we're looking at while panning
  image.innerHTML = ''
  let j = 0
  while (j < 100) {
    image.innerHTML += ` ${i + 1}`
    j++
  }

  container.appendChild(image)

  i++
}

let coords = []
let x = 0
while (x < width) {
  let y = 0
  while (y < height) {
    coords.push({
      x,
      y
    })
    y += window.innerHeight
  }
  x += window.innerWidth
}

async function pan() {
  if (!coords.length) {
    return;
  }

  let randomIdx = Math.floor(Math.random() * coords.length)
  let [randomCoord] = coords.splice(randomIdx, 1);

  console.log(coords.length)

  container.classList.add('fast')

  // update style in new thread so new transition-duration is applied
  await forMs(10)

  // move to new yet-unpanned area
  container.style.top = Math.max(-randomCoord.y, minTop) + 'px'
  container.style.left = Math.max(-randomCoord.x, minLeft) + 'px'

  // wait (approx.) for transition to end
  await forMs(2500)

  container.classList.remove('fast')

  // update style in new thread so new transition-duration is applied
  await forMs(10)

  //pan that area
  let newLeft = -(randomCoord.x + window.innerWidth)

  if (newLeft < minLeft) {
    newLeft = minLeft
  }

  container.style.left = newLeft + 'px'

  // wait (approx.) for transition to end
  await forMs(4500)

  // move on to next random area
  await pan()
}

pan()
html,
body {
  position: relative;
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  overflow: auto;
}

* {
  margin: 0;
  padding: 0;
}

#container {
  position: absolute;
  top: 0;
  left: 0;
  text-align: left;
  width: 11500px;
  height: 11500px;
  transition: all 4s ease-in-out;
  transition-property: top left;
  font-size: 0;
}

#container.fast {
  transition-duration: 2s;
}

#container div {
  display: inline-block;
  height: 575px;
  width: 575px;
  border: 1px solid black;
  box-sizing: border-box;
  font-size: 45px;
  overflow: hidden;
  word-break: break-all;
}
<div id="container"></div>

Answer №1

Here are some suggestions for improvements:

  • Implement hiding overflow on html and body to prevent users from scrolling and disrupting the layout.
  • Calculate minLeft and minTop dynamically to adjust for window resizing. Consider using ResizeObserver for recalculating values.
  • Extend transition times to reduce the risk of Cybersickness. To avoid long movements in a short time frame, consider zooming out, moving, then zooming in, or following a serpentine path for shorter jumps.

For performance enhancements:

  • Utilize transforms instead of top and left for animations.
  • Apply will-change: transform; to specify to the browser what to optimize. Refer to will-change.
  • Use translate3D() over translate(). See this reference.
  • Opt for requestAnimationFrame instead of setTimeout and setInterval.


Take a look at this informative article:


Revamped code using transform:

(JavaScript code snippet)
(CSS code snippet)
(HTML code snippet)


Note that not all features have been implemented in the above snippet.

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

dealing with a problem with the bootstrap navigation bar concept

I’ve been struggling to align the menu and company name in a single row. Initially, I tried setting the company name followed by some spaces before adding the menu items, but it didn't work out as expected. I've been spending the last couple of ...

retrieve data from the API response using a node request

I initiated an API request using the request method. Everything seems to be functioning properly, but I am encountering difficulty extracting the results from the response. The snippet of my code in question is as follows: app.get('/events/:query&a ...

An issue related to AngularJS and the injection of ui-bootstrap components has been encountered

I'm encountering an issue with injection errors in my code, and unfortunately, the debugger in Firefox isn't providing much help. Here are snippets of the code: This is the Controller file causing the error: App.controller('ModalInstanceCt ...

Is it possible to vertically resize just one of three divs to match the size of the window?

I'm facing a challenge in creating a responsive webpage with multiple divs. Here is the structure I am trying to achieve: <div id="container"> maximum width of 1200 and height of 1000 <div id="vertically-static-top">20 pixels high< ...

What is the maximum width that can be set for an HTML input control

I'm working on a web page with a row that contains three controls. SomeText Input Button It looks something like this <div> SomeText <Input/> <img> </div> The image is currently floating to the right. ...

Utilizing Bootstrap 4 to seamlessly transition the navbar-brand image to overlap on larger screens, and shrink-to-fit on smaller screens

I have a challenge that I'm working on. My goal is to make the navbar-brand image overlap with the navbar without changing its height, as the navbar itself has a fixed height of 80px. The current solution kinda works, but I am facing an issue ...

What is the best way to initialize a value asynchronously for React context API in the latest version of NextJS, version

Currently, I'm working on implementing the React context API in my NextJS e-commerce application to manage a user's shopping cart. The challenge I'm facing is how to retrieve the cart contents from MongoDB to initiate the cart context. This ...

Button Fails to Respond on Second Click

I have a button that triggers a JavaScript function. This function, in turn, initiates two sequential AJAX calls. Upon completion of the first call, it performs some additional tasks before proceeding to the second AJAX call. The button functions correctl ...

"After the document is fully loaded, the Ajax post function is failing to work

I am looking to trigger an Ajax call once my document has finished loading. Here is the code I currently have: <script> $(window).bind("load", function () { getCategories(); }); </script> <script> ...

Checking for disconnection in Vue.js

On my Laravel / Vue.js website, I'm trying to figure out how to detect when the connection to the server is lost and display a warning message on the front end. I've come across using axios for this purpose, but I'm unsure of where exactly ...

Tips for dynamically generating ng-change within ng-repeat

I am facing an issue with a repeated div that contains a dropdown menu with three options: 'single', 'double', and 'matrix'. Depending on the selected value, the corresponding div should be displayed. However, when the ng-repe ...

Are the orders of events maintained when emitted using an event emitter?

I have a simple query regarding the event emitter, which is crucial for my program's logic. Currently, I am utilizing an external library that triggers events that I'm listening to. These events consist of 'data' and 'error'. ...

Changing the visual appearance of an alert in JavaScript and HTML

My knowledge in JavaScript is limited, but I have a script that retrieves a query from a Python service to a Mongodb database. The query is returned in the following format: [{CHAIN: "STREET ELM, ELMER", CODE: "1234"}, {CHAIN: "STREET LM, LMAO", CODE: ...

Error: The term "Worker" is undefined in a new Nextjs project

I'm currently looking into an issue where I am attempting to import a webpacked javascript file into a NextJS project that utilizes Worker, but I keep encountering the error message ReferenceError: Worker is not defined. I've simplified it down t ...

Guide on accessing Azure Configuration Application settings in a Node application with JavaScript

Currently, I have a node.js application named "myClient" deployed on Azure as an App Service. Within this setup, I utilize several configuration files that contain specific values tailored to their respective runtime environments: appconfig.json is used f ...

What is the process for removing the highlighted border from a navigation menu in ASP.NET?

I am currently utilizing the navigation menu in the ASP.NET toolbox, but I am struggling to remove an unwanted golden border. Despite my efforts, I have not been able to find any information on how to resolve this issue. The golden border only appears when ...

What mistakes am I making in including/injecting functions in AngularJS controllers and factories?

I'm encountering an issue in Angular where I am struggling to inject my factory into my controller. The error message I'm receiving is "Cannot read property 'validar' of undefined". In my project, I have two files - ServiceUtil.js which ...

Learn how to retrieve images from the web API at 'https://jsonplaceholder.typicode.com/photos' and showcase them on a webpage using Angular10

Using the API "https://jsonplaceholder.typicode.com/photos", I have access to 5 properties: albumId: 1 id: 1 thumbnailUrl: "https://via.placeholder.com/150/92c952" title: "accusamus beatae ad facilis cum similique qui sunt" url: "https://via.placeh ...

Is the setInterval function in JavaScript only active when the browser is not being used?

I am looking for a way to ensure proper logout when the browser is inactive using the setInterval() function. Currently, setInterval stops counting when the browser is active, but resumes counting when the browser is idle. Is there a way to make setInterv ...

Why am I unable to utilize an array in this manner in JavaScript, and what is the method for accessing the array using a calculated number?

var nodesXY = ['15% 15%','30% 16%','19% 42%','39% 80%',]; var number = ["0","1","2","3","4","0","0","0"]; //some loop AccesNodes(number[1]); function AccesNodes(number){ console.log(number); // ...