0

I'm building a transition where I want to scale up a thumbnail to fill the viewport on click.

Currently I got the calculations right on finding the right scale ratio based on the viewport and it's size, but I'm having problems on centring the image in the viewport after it's scaled/expanded.

I only have the problem when I'm using transform-origin: center center; and the image is centered in a fixed full screen container. Here is a jsfiddle showing my problem.

I've also made a jsfiddle showing how it is without the centering. This is close to what I want, except I want to be able to transition the image from other positions rather than the top left corner.

Here is the code I have so far

// Helper fucntions
const getWindowWidth = () => {
    return Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
}

const getWindowHeight = () => {
    return Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
}

// Get element
const El = document.getElementById('test');

// Add listener
El.addEventListener('click', () => {
    // Viewport size
    const viewH = getWindowHeight();
    const viewW = getWindowWidth();

    // El size
    const elHeight = El.offsetHeight;
    const elWidth = El.offsetWidth;

    // Scale ratio
    let scale = 1;

    // Get how much element need to scale
    // to fill viewport
    // Based on https://stackoverflow.com/a/28475234/1719789 
    if ((viewW / viewH) > (elWidth / elHeight)) {
        scale = viewW / elWidth;
    } else {
        scale = viewH / elHeight;
    }

    // Center element
    const x = ((viewW - ((elWidth) * scale)) / 2);
    const y = ((viewH - ((elHeight) * scale)) / 2);

    // matrix(scaleX(),skewY(),skewX(),scaleY(),translateX(),translateY())
    El.style.transform = 'matrix(' + scale + ', 0, 0, ' + scale + ', ' + x + ', ' + y + ')';
});

And some css:

.Container {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

#El {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 50%;
  transform-origin: center center;
  transform: translate(-50%, -50%);
  transition: transform .3s ease-in-out;
}

The best solution would be getting the current position of the clicked thumbnail (not always centered) and from that scale it to fill the screen. But I'm not really sure where to start to be able to do that.

lassemt
  • 164
  • 1
  • 11

1 Answers1

0

Is this the effect you are looking for?

CSS:

.Container {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

#test {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 50%;
  transform: translate(-50%, -50%);
  transition: all 3.3s ease-in-out;
}

#test.rdy{
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}

JS:

// Helper fucntions
const getWindowWidth = () => {
    return Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
}
const getWindowHeight = () => {
    return Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
}

const El = document.getElementById('test');
El.addEventListener('click', () => {
    const viewH = getWindowHeight();
    const viewW = getWindowWidth();
    const elHeight = El.offsetHeight;
    const elWidth = El.offsetWidth;

    let scale = 1;

    if ((viewW / viewH) > (elWidth / elHeight)) {
        scale = viewW / elWidth;
    } else {
        scale = viewH / elHeight;
    }

    El.style.width = elWidth * scale + 'px';
    El.style.height = elHeight * scale + 'px';

    //Add .rdy class in case that position needs resetting :)
    document.getElementById('test').className += ' rdy';
});

//A hack to make height transition work :)
window.onload = function(){
    El.style.height = El.offsetHeight + 'px';
};
vicbyte
  • 3,690
  • 1
  • 11
  • 20
  • Thank you for your answer. This is kinda the effect I'm looking for, but I will need to maintain the proportions of the thumbnail that is being expanded. – lassemt Dec 06 '17 at 00:02
  • @lassemt Updated, lemme know if this is what youve been looking for :) – vicbyte Dec 07 '17 at 22:57
  • Sorry for the late answer, been busy with exams.. Your solution is working fine. I ended up using GSAP for scaling because I needed the library for something else as well. So that fixed my centring problem when using transforms instead of scaling the element using width and height. – lassemt Dec 09 '17 at 16:16