移动和扩展图像以填充视口过渡

Move and expand image to fill viewport transition

我正在构建一个过渡,我想在其中放大缩略图以在单击时填充视口。

目前,我在根据视口及其大小找到合适的比例方面进行了正确的计算,但是在 scaled/expanded 之后,我在将图像置于视口中心时遇到了问题。

我只有在使用 transform-origin: center center; 并且图像位于固定全屏容器的中心时才会遇到问题。 Here is a jsfiddle showing my problem.

我还制作了一个 jsfiddle 来展示没有居中的情况。这接近我想要的,除了我希望能够从其他位置而不是左上角转换图像。

这是我目前的代码

// 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  
    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 + ')';
});

还有一些 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;
}

最好的解决方案是获取所单击缩略图的当前位置(并不总是居中),然后按比例缩放以填满屏幕。但我不确定从哪里开始才能做到这一点。

这是您想要的效果吗?

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';
};