Tips on easily toggling between transform-origin and scroll bars

On my website, I have a code snippet that toggles between using CSS transform-origin and scale to utilizing CSS width and scrollbars.

This switch is necessary because I have implemented pinch-to-zoom functionality for a specific DIV element on my site.

To achieve a smoother pinch zoom experience, I am currently using CSS translateX, translateY, and Scale. However, after the zoom operation, I need to revert back to the default width and scrollbar settings so that users can navigate through the layout easily.

I have included an example below showcasing how I am handling this switch, but I am encountering some issues with setting the top margin correctly. What would be the best approach to address this?

// JavaScript code to toggle between origin and scroll
var isOrigin = false;
        var originX = 500;
        var originY = 200;
        var scale = 1.5;
        var deltaX = 0;
        var deltaY = 0;

 // Function to switch from origin to scroll
        var from_origin_to_scroll = function () {
            if (isOrigin) { from_scroll_to_origin(); return; }

            var wrap = $('.containter .wrap');

            // Reset scroll position
            const el = document.scrollingElement || document.documentElement;
            $('.containter')[0].scrollLeft = 0;
            el.scrollTop = 0;

            wrap.css({
                transformOrigin: originX + "px " + originY + "px",
                transform: "translate3d(" + deltaX + "px," + deltaY + "px, 0) " +
                              "scale3d(" + scale + "," + scale + ", 1) ",
                width: 100 + '%'
            });

            isOrigin = true;

            $('.info').html('layout set by origin and scale');
        }

// Function to switch from scroll to origin
        var from_scroll_to_origin = function () {
            var wrap = $('.containter .wrap');

            wrap.css({
                transformOrigin: originX + "px " + originY + "px",
                transform: "translate3d(" + 0 + "px," + 0 + "px, 0) " +
                              "scale3d(" + 1 + "," + 1 + ", 1) ",
                width: (100 * scale) + '%'
            });

            $('.containter')[0].scrollLeft = originX * (scale - 1);

            const el = document.scrollingElement || document.documentElement;
            el.scrollTop = originY * (scale - 1);

            isOrigin = false;

            $('.info').html('layout set by width and scroll');
        }
// CSS Styles
body {
            margin: 0;
            padding: 0;
            overflow-x: auto;
            -webkit-overflow-scrolling: touch;
            width:100vw;
        }

        .top{
            position: fixed;
            width: 100%;
            background-color: #333;
            line-height: 40pt;
            text-align: center;
            color: #f1f1f1;
            font-size: 20pt;
            left: 0;
            top: 0;
            z-index: 10;
        }

        .top .info{

        }
        
        .header_content
        {
          background-color: #e1e1e1;
          line-height:130pt;
        }

        .containter {
            width:100%;
            box-sizing: border-box;
            overflow: auto;
            -webkit-overflow-scrolling: touch;
        }

        .containter .wrap {
            display: flex;
            flex-direction: column;
            width: 100%;
        }

        .containter .wrap img {
            width: 100%;
            margin-top: 30pt;
        }
// HTML Markup including script and content
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="top">
        <div class="info" onclick="from_origin_to_scroll()">click to switch</div>
    </div>
    <div class="header_content">
    this is a header content - needs to be added to overall calculation
    </div>
    <div class="containter">
        <div class="wrap">
            <img src="https://thumb7.shutterstock.com/display_pic_with_logo/91858/594887747/stock-photo-dreams-of-travel-child-flying-on-a-suitcase-against-the-backdrop-of-sunset-594887747.jpg" />
            <img src="https://thumb9.shutterstock.com/display_pic_with_logo/1020994/556702975/stock-photo-portrait-of-a-happy-and-proud-pregnant-woman-looking-at-her-belly-in-a-park-at-sunrise-with-a-warm-556702975.jpg" />
            <img src="https://thumb7.shutterstock.com/display_pic_with_logo/234100/599187701/stock-photo-funny-little-girl-plays-super-hero-over-blue-sky-background-superhero-concept-599187701.jpg" />
            <img src="https://thumb1.shutterstock.com/display_pic_with_logo/1316512/661476343/stock-photo-funny-pineapple-in-sunglasses-near-swimming-pool-661476343.jpg" />
            <img src="https://thumb1.shutterstock.com/display_pic_with_logo/2114402/689953639/stock-photo-adult-son-hugging-his-old-father-against-cloudy-sky-with-sunshine-689953639.jpg" />
            <img src="https://thumb7.shutterstock.com/display_pic_with_logo/172762/705978841/stock-photo-businessman-looking-to-the-future-for-new-business-opportunity-705978841.jpg" />
        </div>
    </div>

Answer №1

If you're facing this issue, one potential solution is to differentiate between when the user intends to zoom and when they are simply scrolling.

const $container = $(".container");
$container.on('touchstart', function (e) {
  if (e.touches.length > 1){
    //Detects multiple fingers on the screen,
    //switches mode to transform-origin
    from_scroll_to_origin()
  }
});

$container.on('touchend', function (e) {
  //Switches mode back to scrollbars
  from_origin_to_scroll()
});

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

Serve static assets files based on the route path instead of using absolute paths

Within Express, I have set up the following route: app.get('/story/:username', function(req, res){ res.render('dashboard.ejs'); }); Prior to that, I am serving any static files located in /public: app.use(express.static(__dirname ...

The hide-columns feature in Ng-table does not allow for manual column hiding from the controller

I've configured ng-table with checkboxes to toggle column visibility, and it's functioning smoothly. Here's the HTML: // Switchers to show/hide columns <div style="margin-bottom: 20px"> <label class="checkbox-inline" ng-repeat= ...

Is there a way to dynamically count the length of an element or class in realtime using JavaScript?

If there are currently 5 divs with the class name "item" and a new unknown number of divs with the same class name "item" are dynamically added in real time, I want my result to display the total number of divs present at that moment (i.e., 5 + n). Note: ...

"Combining the power of Next.js with a hybrid single-page

My current challenge involves a public section that requires server-side rendering (SSR) for SEO purposes. However, there is also an application within the website where SEO is not a priority and a single-page application (SPA) would be more suitable. I am ...

JQuery Function for Repeatedly Looping through Div Elements

I've been experimenting with creating a loop that alternates the fade-in and fade-out effects for different elements. This is what I have so far: setInterval(function() { jQuery(".loop").each(function(index, k) { jQuery(this).delay(1200 ...

What is the process for consumers to provide constructor parameters in Angular 2?

Is it possible to modify the field of a component instance? Let's consider an example in test.component.ts: @Component({ selector: 'test', }) export class TestComponent { @Input() temp; temp2; constructor(arg) { ...

What is the method of invoking the HTML5 form.checkValidity function within a WebForms form.onSubmit event?

When trying to integrate HTML5 input types into an ASP.net WebForms website, how can one extend or override the standard WebForms WebForm_OnSubmit JavaScript function? Most user-agents (e.g. Chrome, IE, Firefox) are already equipped to handle tasks like d ...

Are you seeing empty squares in place of Font Awesome icons?

If the Font Awesome icons are displaying as blank squares in all browsers despite correctly linking the stylesheet and attempting to install the package through npm which results in a npm ERR! code E401, it can be frustrating. Even after checking the brows ...

Can you please explain why I am unable to remove the item in my code using Node.js and Express?

Currently, I am in the process of learning NodeJS and working on an application that involves adding Bicicleta objects. However, I have encountered an issue where I am unable to delete these objects successfully. Even though the POST request for deletion r ...

I can't figure out why this error keeps popping up in React JS: "You are attempting to use withTheme(Component) with a component that is undefined."

https://i.sstatic.net/CSxtJ.png Ever since I installed some "material-ui" packages, I've been encountering this annoying error. I've attempted various solutions but to no avail. Can anyone lend a hand? ...

What seems to be the issue with the data initialization function not functioning properly within this Vue component?

In my Vue 3 component, the script code is as follows: <script> /* eslint-disable */ export default { name: "BarExample", data: dataInitialisation, methods: { updateChart, } }; function dataInitialisation() { return { c ...

Update button text using Ajax and Jquery after a successful request

I have a situation where I want to change the text on a button after a user clicks it and an ajax call is made to a web service. I've experimented with saving the original value of the button before the ajax call, passing it as a variable, and attempt ...

Transforming the format of w2ui cells

I've been attempting to modify the background color of a specific cell to green using w2ui, but the code I have doesn't seem to be working. I've searched through the documentation, demos, and comments related to the style property without an ...

Steps for creating a table with a filter similar to the one shown in the image below

https://i.sstatic.net/zR2UU.png I am unsure how to create two sub-blocks within the Business A Chaud column and Potential Business Column. Thank you! I managed to create a table with input, but I'm struggling to replicate the PUSH & CtoC Column for ...

Implementing a node.js application deployment with pm2 to ensure zero downtime

While there are countless tutorials on developing chat applications using socket.io and node.js, the event-driven advantage of Node is undeniable for building chat apps. However, a recent thought crossed my mind - how can I ensure the sustainability of my ...

Employing the include functionality within PHP

Currently, I am in the process of developing an eCommerce website and have my own host/domain. To ensure security, I understand that it is advisable to store PHP files in a location separate from public_html. The index.html file is located in /home/user/pu ...

Adding Metadata to an Azure Blob Using JavaScript

While I have come across examples for setting metadata in c#, I am struggling to find information on how to implement it in JavaScript. How can I set metadata for a blob using JavaScript? const metadata = {name, selection} await blockBlobClient.upload(fil ...

Show a button using CSS when the cursor is hovering

Expressing my gratitude to everyone! I need assistance with implementing a function in reactJS where the <button /> remains hidden during page loading and reveals itself when hovered over. Despite trying various methods, I have been unable to resolve ...

Sending data from a web page to a server using the Ajax

After going through some tutorials, I realized that my script is not working as expected. To address this issue, I am trying to implement the functionality of inserting data into my database using a PHP file named shoutboxform.php. However, since I intend ...

Guide to using jQuery to input a multi-line text into a field

Dealing with a value that spans multiple lines obtained from PHP has been challenging due to the structure of textareas. The standard method of inserting it into the textarea is not feasible in this case. I resorted to using jQuery for this purpose, but ...