该方法会根据 目标分辨率(options.width/height) 和 当前窗口尺寸(innerWidth/innerHeight) 计算缩放比例,并保持 等比例缩放Math.min(scaleX, scaleY)),确保内容不变形:

/*** 防抖函数* @param {Function} fn - 需要防抖的函数* @param {number} delay - 延迟时间(ms)* @returns {Function} 防抖后的函数*/
function debounce(fn, delay) {let timer = null;return function (...args) {if (timer) clearTimeout(timer);timer = setTimeout(() => {fn.apply(this, args);}, delay);};
}/*** 带滚动条支持的自适应缩放* @param {string|HTMLElement} target - 目标元素* @param {Object} config - 配置项* @param {number} config.designWidth - 设计稿宽度(如1920)* @param {number} config.designHeight - 设计稿总高度(如1080)* @param {number} [config.topOffset=60] - 顶部固定高度(如导航栏)* @param {boolean} [config.scrollable=true] - 是否启用垂直滚动*/
export function scrollableAutoScale(target, config) {const el = typeof target === 'string' ? document.querySelector(target) : target;if (!el) return () => { };const {designWidth = 1920,designHeight = 1080,topOffset1 = 0,topOffset2 = 0,scrollable = true} = config;// 1. 设备像素比检测和优化const dpr = window.devicePixelRatio || 1;const isRetina = dpr >= 1.5;const scalePrecision = isRetina ? 1000 : 400; // 视网膜屏使用更高精度// 2. 高清渲染样式优化Object.assign(el.style, {willChange: 'transform',backfaceVisibility: 'hidden',transformStyle: 'preserve-3d',textRendering: isRetina ? 'geometricPrecision' : 'optimizeLegibility',WebkitFontSmoothing: isRetina ? 'subpixel-antialiased' : 'antialiased',imageRendering: isRetina ? 'crisp-edges' : 'auto'});// 3. 创建外层容器(添加过渡效果、增加视网膜屏优化)const container = document.createElement('div');Object.assign(container.style, {position: 'fixed',top: `${topOffset2}px`,left: '0',width: '100vw',height: `calc(100vh - ${topOffset1 + topOffset2}px)`,overflow: 'hidden', // 默认隐藏,后面动态调整margin: '0',padding: '0',zIndex: '1',// 背景图优化backgroundImage: getComputedStyle(el).backgroundImage,backgroundPosition: getComputedStyle(el).backgroundPosition,backgroundRepeat: getComputedStyle(el).backgroundRepeat,backgroundSize: getComputedStyle(el).backgroundSize,imageRendering: isRetina ? 'crisp-edges' : 'auto',// 平滑过渡 滚动条出现/消失transition: 'overflow 0.2s ease-out'});el.style.backgroundImage = 'none';el.parentNode.insertBefore(container, el);container.appendChild(el);// 4. 目标元素样式(使用3D变换)Object.assign(el.style, {position: 'absolute',transformOrigin: 'top left',width: `${designWidth}px`,left: '0',right: '0',transformStyle: 'preserve-3d'});// 5. 增强版缩放计算let lastScale = 0;const calculate = () => {const viewportWidth = container.clientWidth;const viewportHeight = container.clientHeight;// 高精度缩放计算const rawScale = viewportWidth / designWidth;const scale = Math.round(rawScale * scalePrecision) / scalePrecision;const contentHeight = designHeight * scale;// 动态阈值(视网膜屏使用更敏感的阈值)const scaleThreshold = isRetina ? 0.001 : 0.0025;if (Math.abs(scale - lastScale) > scaleThreshold) {// 使用scale3d提升渲染质量el.style.transform = `scale3d(${scale}, ${scale}, 1)`;// 垂直居中优化if (!scrollable) {el.style.transform = `scale3d(${scale}, ${scale}, 1) translate3d(0, ${(viewportHeight - contentHeight) / 2}px, 0)`;}lastScale = scale;}// 滚动条缓冲(视网膜屏增加缓冲)const scrollBuffer = isRetina ? 5 : 2;container.style.overflowY = scrollable && (contentHeight > viewportHeight + scrollBuffer)? 'auto': 'hidden';};// 6. 高性能监听(双RAF防抖)使用requestAnimationFrame优化监听频率,避免高频触发计算导致性能问题。let rafId = null;const optimizedCalculate = () => {if (rafId) cancelAnimationFrame(rafId);rafId = requestAnimationFrame(() => {calculate();rafId = requestAnimationFrame(() => {calculate(); // 双RAF确保布局稳定rafId = null;});});};const observer = new ResizeObserver(debounce(optimizedCalculate, isRetina ? 30 : 50));observer.observe(container);// 7. 三重初始化保障requestAnimationFrame(() => {calculate();setTimeout(() => {requestAnimationFrame(calculate);}, 200);});return () => {observer.disconnect();if (rafId) cancelAnimationFrame(rafId);container.parentNode?.insertBefore(el, container);container.parentNode?.removeChild(container);};
}

react页面中的调用:

import React, { useEffect, useRef } from 'react';
import { optimizedAutoScale } from '../utils/optimizedAutoScale';const Index = () => {const containerRef = useRef(null);useEffect(() => {if (!containerRef.current) return;const destroy = scrollableAutoScale(containerRef.current, {designWidth: 1920,minHeight: 1080, // 设计稿总高度topOffset1: 53, // 动态获取顶部高度topOffset2: 42, // 动态获取顶部高度scrollable: true,    // 允许滚动});return () => {destroy();};}, []);return (<div ref={containerRef}>{/* 动态内容区域,高度会自动计算 */}</div>);
};export default Index;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/86820.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/86820.shtml
英文地址,请注明出处:http://en.pswp.cn/web/86820.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于IEC61499实现的工业机器视觉方案

1.什么是机器视觉 机器视觉就是赋予机器看懂图像的能力。它是一门涉及人工智能、计算机科学、图像处理、光学、机械工程和自动化的交叉技术领域。核心目标是&#xff1a;通过摄像头或其他成像设备获取图像或视频&#xff0c;然后利用计算机算法对这些图像进行分析和理解&#x…

机电一体化论文写作实战指南:从创新设计到工程验证的完整路径

机电论文的“技术-表达”鸿沟 某高校团队研发的智能抓取系统实物表现优异&#xff0c;却被审稿人质疑&#xff1a; “未说明机电耦合设计对性能的影响”——这揭示了机电一体化研究的核心痛点&#xff1a;强工程弱理论。本文基于217篇高影响力论文&#xff0c;拆解从技术到写作…

MySQL 配置参数调优:根据工作负载调整服务器设置

MySQL 数据库的默认配置参数是为了适应各种通用场景而设定的,它们通常无法最大化发挥服务器硬件的潜力,也无法完全匹配特定应用程序的工作负载。一个未优化的 MySQL 配置,在面对高并发、大数据量或特定查询模式时,很容易成为系统性能的瓶颈。 配置参数调优,就是根据你的服…

嵌入式Linux驱动开发基础-2 LED驱动

imx6ull中GPIO涉及寄存器 1&#xff1a;CCM寄存器 GPIOx 要用 CCM_CCGRy 寄存器中的 2 位来决定该组 GPIO 是否使能。哪组 GPIO 用哪个 CCM_CCGR 寄存器来设置。 CCM_CCGR 寄存器中某 2 位的取值含义如下&#xff1a; 00 &#xff1a;该 GPIO 模块全程被关闭 01 &…

深度解析】使用Go语言实现JWT:从原理到实践

JWT&#xff08;JSON Web Token&#xff09;已成为现代Web应用中身份验证的基石。本文深入剖析如何用Go语言实现JWT&#xff0c;从基础概念、底层机制到完整代码实践&#xff0c;助你全面掌握。 一、JWT概述 JWT是一种开放标准&#xff08;RFC 7519&#xff09;&#xff0c;用…

深入解读 DeepSeek-V3 架构及落地的挑战

从多专家架构&#xff08;MoE&#xff09;到模型落地实战的一线观察 一、引言&#xff1a;DeepSeek-V3 是什么&#xff1f; 在大模型百花齐放的今天&#xff0c;DeepSeek-V3 作为 DeepSeek 系列的第三代开源模型&#xff0c;不仅延续了高质量对话能力&#xff0c;还在架构上迈…

前端进阶之路-从传统前端到VUE-JS(第二期-VUE-JS框架结构分析)

经过上期内容的学习&#xff0c;我们已经可以构建一个VUE-CLI框架了&#xff0c;接下来我们分析一下这个框架&#xff0c;毕竟知己知彼&#xff0c;百战百胜 我们创建完成后可以看到以下内容 接下来我们分析一下他的文件结构 node_modules用于存放项目所依赖的第三方模块和包…

网络协议 / 加密 / 签名总结

加密方式&#xff1a; 对称加密&#xff1a;key 不可公开。 非对称加密&#xff1a;公钥加密的信息只有私钥能解密。私钥加密的信息只有公钥能解密&#xff0c;且公钥只能解密私钥加密的信息&#xff08;用于签名&#xff09;。 非对称加密应用&#xff1a; 签名&#xff1a…

集成学习基础:Bagging 原理与应用

本文由「大千AI助手」原创发布&#xff0c;专注用真话讲AI&#xff0c;回归技术本质。拒绝神话或妖魔化。搜索「大千AI助手」关注我&#xff0c;一起撕掉过度包装&#xff0c;学习真实的AI技术&#xff01; Bagging 介绍 1. 定义与全称&#xff1a; Bagging 是 Bootstrap Agg…

skiaSharp linux 上报错

The type initializer for SkiaSharp.SKImageInfo threw an exception 这个错误表明在 Linux 系统上初始化 SkiaSharp 的 SKImageInfo 类型时出现了问题。以下是完整的解决方案&#xff1a; 安装系统依赖&#xff1a; # Ubuntu/Debian sudo apt-get update sudo apt-get ins…

crawl4ai crawler.arun( 超时问题

delay_before_return_html500 # 单位&#xff1a;毫秒 会导致 crawler.arun 超时问题。按理说不应该 await crawler.arun( 1. 浏览器加载页面 ✅ 2. 页面DOM构建完成 ✅ 3. JavaScript执行完成 ✅ 4. 等待 delay_before_return_html 时间 ⏳ (500ms) 5. 返回最终HTML内容 &…

Linux Kernel下exFat使用fallocate函数不生效问题

1&#xff09;Linux驱动开发相关问题&#xff0c;分享给将要学习或者正在学习Linux驱动开发的同学。 2&#xff09;内容属于原创&#xff0c;若转载&#xff0c;请说明出处。 3&#xff09;提供相关问题有偿答疑和支持。 Linux下经常使用fallocate去预分配一个很大的文件空间…

大学专业科普 | 物联网、自动化和人工智能

在选择大学专业时&#xff0c;可以先从自身兴趣、能力和职业规划出发&#xff0c;初步确定几个感兴趣的领域。然后结合外部环境因素&#xff0c;如专业前景、教育资源和就业情况等&#xff0c;对这些专业进行深入的分析和比较。 物联网专业 课程设置 基础课程&#xff1a;包括…

人工智能-基础篇-7-什么是大语言模型LLM(NLP重要分支、Transformer架构、预训练和微调等)

大型语言模型&#xff08;Large Language Model&#xff09;。这类模型是自然语言处理&#xff08;NLP&#xff09;领域的一个重要分支&#xff0c;它们通过在大量文本数据上进行训练来学习语言的结构和模式&#xff0c;并能够生成高质量的文本、回答问题、完成翻译任务等。 1…

【赵渝强老师】基于PostgreSQL的分布式数据库:Citus

由于PostgreSQL具有强大的功能和良好的可扩展性&#xff0c;因此基于PostgreSQL很容易就可以实现分布式架构。Citus便是具体的一种实现方式。它以扩展的插件形式与PostgreSQL进行集成&#xff0c;且独立于PostgreSQL内核&#xff0c;部署也比较简单。Citus是现在非常流行的基于…

【赵渝强老师】OceanBase OBServer节点的接入层

OceanBase数据库代理ODP&#xff08;OceanBase Database Proxy&#xff0c;又称OBProxy&#xff09;是OceanBase数据库的接入层&#xff0c;负责将用户的请求转发到合适的OceanBase数据库实例上进行处理。ODP是独立的进程实例&#xff0c;独立于OceanBase数据库实例部署。ODP监…

ISP Pipeline(8): Color Space Conversion 颜色空间转换

Color Space Conversion&#xff08;颜色空间转换&#xff09; 是图像处理中的一个重要步骤&#xff0c;它将图像从一个颜色空间&#xff08;Color Space&#xff09;转换到另一个&#xff0c;以满足 显示、分析、压缩或算法需求。 为什么转换颜色空间&#xff1f; 应用场景…

Spring Web MVC ①

&#x1f680; 一、Spring MVC MVC三层 Controller&#xff1a;乐团指挥&#xff0c;接收请求→调用模型→选择视图&#xff08;Controller&#xff09; Model&#xff1a;乐手&#xff0c;处理业务逻辑与数据&#xff08;POJO对象&#xff09; View&#xff1a;舞台展示&…

【数据挖掘】贝叶斯分类学习—NaiveBayes

NaiveBayes 朴素贝叶斯的核心是贝叶斯定理&#xff0c;它描述了如何根据新证据更新事件的概率。 要求&#xff1a; 1、实现朴素贝叶斯分类算法&#xff0c;验证算法的正确性&#xff0c;并将算法应用于给定的数据集Data_User_Modeling数据集&#xff0c;选择一部分数据集作为已…

Java面试宝典:基础二

&#x1f512; 25. final vs abstract 关键字 关键字修饰对象作用规则final类禁止被继承final class MyClass { ... }方法禁止被子类重写public final void func()变量变为常量&#xff08;基本类型值不可变&#xff0c;引用类型地址不可变&#xff09;final int MAX 100;abs…