Guide on crafting a scrollable and touch-responsive grid using CSS and JavaScript

I am seeking guidance on creating a grid with a variable number of columns and rows. It should be contained within a separate div and should not interfere with other objects or alter the parent's size.

The grid needs to be square and I am currently utilizing Tailwind CSS, but I am open to transitioning to SCSS or plain CSS if necessary. Additionally, I would like it to be interactive, allowing users to touch and move it with a mouse on desktops and touch-enabled devices.

Could you provide suggestions on how to achieve this functionality?

Answer №1

Based on the question you've presented, here is a potential approach to solving it. While I have not yet tested this solution on a touch device, adapting it to handle touch events should not pose a significant challenge.

const elements = [
  ['x0', 'x1', 'x2'],
  ['y0', 'y1', 'y2'],
  ['z0', 'z1', 'z2']
];

let htmlContent = '';
for (let rowElements of elements) {
  htmlContent += '<div class="row">';
  for (let element of rowElements) {
    htmlContent += '<div class="element">';
    htmlContent +=   element;
    htmlContent += '</div>';
  }
  htmlContent += '</div>';
}

const viewContainer = document.querySelector('#view-container');
const outputContainer = document.querySelector('#output-container');
outputContainer.innerHTML = htmlContent;



let initialMousePosition = null;
let initialOffset = null;

outputContainer.addEventListener('mousedown', event => {
  outputContainer.classList.remove('animate');
  initialMousePosition = {
    x: event.clientX,
    y: event.clientY
  };
  initialOffset = {
    x: outputContainer.offsetLeft - viewContainer.offsetLeft,
    y: outputContainer.offsetTop - viewContainer.offsetTop
  };
});

window.addEventListener('mouseup', event => {
  initialMousePosition = null;
  initialOffset = null;

  outputContainer.classList.add('animate');
  const xOffset = -1 * Math.max(0, Math.min(Math.round((outputContainer.offsetLeft - viewContainer.offsetLeft) / -100), elements.length - 1));
  const yOffset = -1 * Math.max(0, Math.min(Math.round((outputContainer.offsetTop - viewContainer.offsetTop) / -100), elements[0].length - 1));
  outputContainer.style.left = `${xOffset * 100}px`;
  outputContainer.style.top = `${yOffset * 100}px`;  
});

window.addEventListener('mousemove', event => {
  if (initialMousePosition) {
    const xMovement = initialMousePosition.x - event.clientX;
    const yMovement = initialMousePosition.y - event.clientY;
    outputContainer.style.left = `${-1 * xMovement + initialOffset.x}px`;
    outputContainer.style.top = `${-1 * yMovement + initialOffset.y}px`;
  }
});
#view-container {
  width: 100px;
  height: 100px;
  overflow: hidden;
  
  border: 2px solid blue;
}

#output-container {
  position: relative;
}

.row {
  display: flex;  
}

.element {
  display: flex;
  min-width: 100px;
  width: 100px;
  height: 100px;
  box-sizing: border-box;
  
  justify-content: center;
  align-items: center;
  border: 1px solid red;
}

#output-container.animate {
  transition: left 1s ease 0s, top 1s ease 0s;
}
Drag the content within the box!<br/>
<br/>
<div id="view-container">
  <div id="output-container"></div>
</div>

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

Alignment of Bootstrap responsiveness shifted to the left rather than the center

My HTML Code: <div class="gridrow" id="eventsrow"> <div class="gridcard" id="eventcard" style="float:left;width:100%;height:100%;margin-bottom:0.5rem;background-color:white"> <div class="event container"> <div clas ...

Adjust the DIV shape to fit perfectly within the browser window without overlapping with any other elements

http://jsbin.com/iGIToRuV/1/edit Currently, I am working on developing a WYSIWYG website designer as part of an experimental project for various purposes. The ultimate goal is to ensure that it is both desktop and mobile-friendly. However, I have encount ...

JavaScript regex for the 'hh:mm tt' time format

I need to validate time in the format 'hh:mm tt'. Here is an example of what needs to be matched: 01:00 am 01:10 Pm 02:20 PM This is what I have tried so far: /^\d{2}:\d{2}:\s[a-z]$/.test('02:02 am') ...

What is the best way to create a sticky/fixed navbar that conceals the div above it while scrolling on the page?

When I am at the top of the page, I want to display the phone number and email above the navigation bar. However, as soon as I start scrolling down, I want the phone number and email to disappear and only show the navigation bar. I have attempted using fix ...

MongoDB table collections (table names in other databases)

After setting up my express server to connect to mongodb, I encountered an issue despite everything working fine initially. I created a collection in my mongodb called projects (plural form). In my project.model.js file, I defined the model as follows: c ...

Vue alert: Issue encountered in watcher 'childItems' callback - 'TypeError: Unable to access property 'tag' as it is undefined'

I am currently in the process of developing the Store page for a web application. I am utilizing Axios to retrieve product data and display it in a Vue template. While the backend functionality is working correctly and the frontend is rendering successfull ...

Display information from dynamically generated pages using Gatsby JS sourcing data from CSV files

I've been working on creating pages in Gatsby JS from a csv file and everything seemed to be going smoothly. However, when it comes to displaying the data on these generated pages, I keep running into issues with undefined variables and can't see ...

Sending a document through an ajax request from a bootstrap dialogue box

Trying to send a file to a server through a bootstrap modal using ajax. Here's the modal html: <div class="modal-body"> <div> <form class="form" role="form" id="attachform" enctype="multipart/form-data"> <input type="file" name= ...

Is QA supported by LG WebOS 3.5 through webdriver?

I've been experimenting with Javascript ( nodejs ) and have successfully automated browser operations using selenium-webdriver on a local server. However, I am facing challenges when trying to automate tasks on my LG WebOS 3.5 TV. Does anyone know how ...

Obtain the Present Controller Identity within AngularJS

Currently, I am working on developing a directive that can create a grid dynamically. The code I have written functions properly but there is one limitation where I need to explicitly mention the controller name 'DemoCtrl'. I am wondering if ther ...

Choosing a CSS selector for a class that does not have a specific ID

Looking for a way to select all elements with the class .tab-pane except for those with the id #home. I attempted using .tab-pane:not#home{...}, but it proved unsuccessful. Any ideas on how to achieve this? Sample HTML <div id="home" class="tab-pan ...

Using Laravel Eloquent to establish relationships through pivot tables

My experience with Eloquent is limited, especially when it comes to creating queries involving multiple tables and pivot tables. The tables I am working with are: https://i.sstatic.net/0MIwS.png The Models I have defined are: Player class Player exten ...

Position the Mui Card Action at the Upper Right corner

Struggling to align a checkbox within a MUI card to the top right? It has been a challenge for me as well. Here is an image of my current layout https://i.sstatic.net/BwH9o.png. I really want that button to be placed in the top right corner, even when the ...

Looking to utilize AngularJS validation in place of the default browser validation?

I am working on a form that contains two ng-forms for input validation. I have encountered two issues with my forms. 1) I am trying to implement a minlength validation for the Company input, but my current approach doesn't seem to be working. How can ...

Interactive button displaying modal for every row in b-table

I'm working with Laravel, Vue, and Bootstrap-Vue. Currently, I have developed a Vue component that showcases a table of elements (in this case, subnets). Each element in the table has an associated component called "modal_edit-subnet" which is intend ...

What is the best way to activate an @keyframe animation based on the scrolling action?

I am currently working on an @keyframe animation that rotates a circle along its x-axis, starting from 0 degrees to 90 degrees and then back to 0 degrees. My objective is to synchronize the rotation of the circle with the user's scrolling movement on ...

Revamp your code by utilizing ES6 class to replace multiple if statements in Javascript

Currently, my code is filled with numerous if statements and I am considering a switch to classes in ES6. However, Javascript isn't my strong suit... so PLEASE HELP ME..! Previous code: //example code function first(){ console.log('first sce ...

Ways to halt a script entirely once its tag has been eliminated

I have a script from a page tracker website that runs periodically. Occasionally I need to restart the script from the beginning. To do this, I typically remove the script tag from the DOM and then re-append it. However, because the script utilizes setInt ...

Utilizing model associations in Sails.js to populate an array

I am currently using "sails": "~0.10.0-rc5", "sails-mongo": "^0.10.0-rc3". I have two models: Invoice and Item. Invoice model Invoice: { name: 'sample 1', items: [1,2] // 1,2 are the ids of the Item model } Item model Item { id: 1 ...

Implementing the fetch API with radio buttons in a React Native application

I found a useful package for radio buttons called react-native-flexi-radio-button. Currently, I'm working on displaying API results within radio buttons. The API response provides 4 options, and my goal is to render text alongside the corresponding ra ...