我是个新手,正在制作一个让我自学的技术演示站点.我开始try 制作闪屏和导航栏,但一直在努力将闪屏图像适当地转换为导航栏.

图像从客户端窗口的中心开始,并应使用用户在窗口左上角的滚动位置进行平滑zoom 和平移.变换动画完成后,无论窗口大小如何(变换函数应适应这一点),图标应始终是屏幕边缘顶部和左侧的固定像素数.

我try 了尽可能多的方法来根据窗口的宽度和高度动态转换图像,但这是我能得到的最接近的方法: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";
    }
});

图像从屏幕中心开始,zoom 平稳,但在try 使用不同的窗口尺寸时会错过标记.

我搜索了这个问题的答案,但找不到任何具有相同特定需求的答案,而ChatGPT也没有特别的帮助.会很感激大家的帮助的!

嘿,干杯, 那个男人.

推荐答案

想明白了!归根结底,就是从css的.icon类中删除transform-origin: top left标记,并稍微调整一下翻译值:

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", () => {
    // 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 'padding' 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 <= 500) {
        // Transform from center to fixed top left position
        icon.style.transform = "scale(" + scale + "%)";
        icon.style.left = left + "px";
        icon.style.top = top + "px";
    } 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 + 'px';
        icon.style.left = 50 - icon.width / 2 + 'px';
        icon.style.transform = 'scale(17%)';
    }
});

同样的代码也已使用此解决方案进行了更新,以防需要交互演示:https://codepen.io/Audity/pen/KKryrjV

Javascript相关问答推荐

如何计算数组子级的深度- Vue.js

导入图像与内联包含它们NextJS

如何在react-Router-dom 6中Forking 路由?

为什么子组件没有在reaction中渲染?

如何从对象嵌套数组的第二级对象中过滤出键

容器如何更改默认插槽中子项的显示?

一次仅播放一个音频

如何在不分配整个数组的情况下修改包含数组的行为主体?

D3多线图显示1线而不是3线

Vue:ref不会创建react 性属性

提交表格后保留Web表格中的收件箱值?

Exceljs:我们在file.xlsx(...)&#中发现了一个问题'"" 39人;

更改JSON中使用AJAX返回的图像的路径

如何在bslib nav_insert之后更改导航标签的CSS类和样式?

为什么我的自定义元素没有被垃圾回收?

获取';无法解决导入和导入";slick-carousel/slick/slick-theme.css";';错误

在Odoo中如何以编程方式在POS中添加产品

无法设置RazorPay订阅API项目价格

将Auth0用户对象存储在nextjs类型脚本的Reaction上下文中

如何使用Reaction路由导航测试挂钩?