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

时间:2017-12-05 23:31:43

标签: javascript css animation ecmascript-6 transition

我正在构建一个转换,我希望在点击时缩放缩略图以填充视口。

目前我根据视口及其大小找到合适的缩放比例,但我在缩放/扩展后在视口中居中时遇到问题。

当我使用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 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 + ')';
});

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

最佳解决方案是获取所点击缩略图的当前位置(并非始终居中),并从该比例缩放以填充屏幕。但我不确定从哪里开始能够做到这一点。

1 个答案:

答案 0 :(得分:0)

这是你正在寻找的效果吗?

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