javascript – 从窗口中心缩放和平移图像到固定位置

huangapple go评论73阅读模式
英文:

javascript - Scale and translate image from center of window to fixed position

问题

我是新手JavaScript,正在创建一个技术演示网站来自学。我首先尝试制作一个闪屏和导航栏,但一直在努力使闪屏图像适当地转换到导航栏。

图像始于客户端窗口的中央,并且应平滑缩放和平移,使用用户的scrollY位置移动到窗口的左上角。一旦变换动画完成,图标应始终与屏幕边缘的顶部和左侧保持固定数量的像素,而不考虑窗口尺寸(变换函数应适应此情况)。

我已尝试多种方法来根据窗口的宽度和高度动态平移图像,但这是我能够做到的最接近的方式:https://codepen.io/Audity/pen/KKryrjV

const icon = document.querySelector(".icon");

// Set position dynamically on page load
window.addEventListener("load", () => {
    icon.style.left = window.innerWidth / 2 - icon.width / 2 + "px";
    icon.style.top = window.innerHeight / 2 - icon.height / 2 + "px";
});

// Scale and translate icon between center and top left
window.addEventListener("scroll", () => {
    let scale = 100 - window.scrollY / 5.75;
    let left = (window.innerWidth - icon.width) / 2 - (window.scrollY * window.innerWidth) / 2000;
    let top = (window.innerHeight - icon.height) / 2 - (window.scrollY * window.innerHeight) / 2000;

    if (window.scrollY <= 500) {
        console.log("transform: \nscale: " + scale + "%\nleft: " + left + "px\ntop: " + top + "px");
        // Scale and translate icon
        icon.style.transform = "scale(" + scale + "%)";
        icon.style.left = left + "px";
        icon.style.top = top + "px";
    }
});

图像始于屏幕中央并平滑缩放,但在尝试不同窗口尺寸时效果不如预期。

我搜索了这个问题的答案,但找不到符合特定要求的答案,ChatGPT 也没有提供特别有帮助的信息。感激任何帮助!

祝好,
亚当

英文:

I am new to javascript and making a tech demo site to teach it to myself. I started by trying to make a splash screen and navbar but have been struggling to have the splash screen image transform appropriately to the navbar.

The image starts in the center of the client window, and should scale and translate smoothly using the user's scrollY position to the top left of the window. Once the transform animation finishes, the icon should always be a fixed number of pixels from the top and left of the edge of the screen, regardless of the window dimensions (the transform function should adapt to this).

I have tried as many ways to dynamically translate the image according to the width and height of the window, but this was as close as I could get: https://codepen.io/Audity/pen/KKryrjV

const icon = document.querySelector(&quot;.icon&quot;);

// Set position dynamically on page load
window.addEventListener(&quot;load&quot;, () =&gt; {
    icon.style.left = window.innerWidth / 2 - icon.width / 2 + &quot;px&quot;;
    icon.style.top = window.innerHeight / 2 - icon.height / 2 + &quot;px&quot;;
});

// Scale and translate icon between center and top left
window.addEventListener(&quot;scroll&quot;, () =&gt; {
    let scale = 100 - window.scrollY / 5.75;
    let left = (window.innerWidth - icon.width) / 2 - (window.scrollY * window.innerWidth) / 2000;
    let top = (window.innerHeight - icon.height) / 2 - (window.scrollY * window.innerHeight) / 2000;

    if (window.scrollY &lt;= 500) {
        console.log(&quot;transform: \nscale: &quot; + scale + &quot;%\nleft: &quot; + left + &quot;px\ntop: &quot; + top + &quot;px&quot;);
        // Scale and translate icon
        icon.style.transform = &quot;scale(&quot; + scale + &quot;%)&quot;;
        icon.style.left = left + &quot;px&quot;;
        icon.style.top = top + &quot;px&quot;;
    }
});

The image starts in the center of the screen and scales smoothly, but misses the mark when tried with different window dimensions.

I searched for answers to this issue but couldn't find any which had these same particular requirements, and ChatGPT was not particularly helpful either. Would appreciate any help!

Cheers,
Adam

答案1

得分: 0

已经弄清楚了!问题出在从CSS中的.icon类中移除了transform-origin: top left标签,并稍微调整了平移值:

const icon = document.querySelector(".icon");

// 在页面加载时动态设置位置
window.addEventListener("load", () => {
    icon.style.left = window.innerWidth / 2 - icon.width / 2 + "px";
    icon.style.top = window.innerHeight / 2 - icon.height / 2 + "px";
});

// 在中心和左上角之间缩放和平移图标
window.addEventListener("scroll", () => {
    // 可以根据具体需求调整的巧妙数学运算
    let scale = 100 - window.scrollY / 6;
    // (window.innerWidth - icon.width) / 2 是初始位置(中心)
    // (window.scrollY * window.innerWidth) / 1000 平移到左上角
    // (window.scrollY / 100) * 10 确定边缘和图标之间的'padding'
    let left =
        (window.innerWidth - icon.width) / 2 -
        (window.scrollY * window.innerWidth) / 1000 +
        (window.scrollY / 100) * 10;
    let top =
        (window.innerHeight - icon.height) / 2 -
        (window.scrollY * window.innerHeight) / 1000 +
        (window.scrollY / 100) * 10;

    if (window.scrollY <= 500) {
        // 从中心变换到固定的左上角位置
        icon.style.transform = "scale(" + scale + "%)";
        icon.style.left = left + "px";
        icon.style.top = top + "px";
    } else {
        // 修复由于scrollY跳跃引起的变换不精确性
        // 下面的值与上面计算的值相同,
        // 但使用500替代window.scrollY进行解决和简化
        icon.style.top = 50 - icon.height / 2 + 'px';
        icon.style.left = 50 - icon.width / 2 + 'px';
        icon.style.transform = 'scale(17%)';
    }
});

如果需要交互式演示,同样的代码已经更新到这个CodePen中:https://codepen.io/Audity/pen/KKryrjV

英文:

Figured it out! Came down to removing the transform-origin: top left tag from the .icon class in css, and playing with the translation values a bit:

const icon = document.querySelector(&quot;.icon&quot;);
// Set position dynamically on page load
window.addEventListener(&quot;load&quot;, () =&gt; {
icon.style.left = window.innerWidth / 2 - icon.width / 2 + &quot;px&quot;;
icon.style.top = window.innerHeight / 2 - icon.height / 2 + &quot;px&quot;;
});
// Scale and translate icon between center and top left
window.addEventListener(&quot;scroll&quot;, () =&gt; {
// Hacky math that can be adjusted to fit specific needs
let scale = 100 - window.scrollY / 6;
// (window.innerWidth - icon.width) / 2 is the initial position (center)
// (window.scrollY * window.innerWidth) / 1000 translates to the top left corner
// (window.scrollY / 100) * 10 determines the &#39;padding&#39; between the edges and the icon
let left =
(window.innerWidth - icon.width) / 2 -
(window.scrollY * window.innerWidth) / 1000 +
(window.scrollY / 100) * 10;
let top =
(window.innerHeight - icon.height) / 2 -
(window.scrollY * window.innerHeight) / 1000 +
(window.scrollY / 100) * 10;
if (window.scrollY &lt;= 500) {
// Transform from center to fixed top left position
icon.style.transform = &quot;scale(&quot; + scale + &quot;%)&quot;;
icon.style.left = left + &quot;px&quot;;
icon.style.top = top + &quot;px&quot;;
} else {
// Fix transform inaccuracies caused by scrollY jumps
// The values below are the same as the calculated values above,
// but solved and simplified with 500 in place of window.scrollY
icon.style.top = 50 - icon.height / 2 + &#39;px&#39;;
icon.style.left = 50 - icon.width / 2 + &#39;px&#39;;
icon.style.transform = &#39;scale(17%)&#39;;
}
});

The same codepen has also been updated with this solution in case an interactive demo is desired: https://codepen.io/Audity/pen/KKryrjV

huangapple
  • 本文由 发表于 2023年7月11日 12:06:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/76658650.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定