jjzjj

多屏幕适配方案

麦西的西 2023-03-28 原文

在大屏开发中,最常遇到的就是多屏幕适配了。这里提供两套简单实用的方案。

一. 最外层元素增加 scale

这里的最外层元素指的是能包含所有页面的元素。我们可以给最外层元素设置固定的宽高,比如 1920 * 1080。一旦大屏的尺寸跟设定的不符合,则通过缩放相应的倍数来适配大屏。
具体代码如下:

// 获取缩放倍率
getScale = () => {
    const  [width, height] = [1920, 1080];
    let widthScale = window.innerWidth / width;
    let heightScale = window.innerHeight / height;
    return [widthScale, heightScale];
};

// 设置缩放倍率
setScale = () => {
    const [widthScale, heightScale] = this.getScale();
    let containerDom = document.getElementById('container');
    containerDom.style.transform = `scale(${widthScale}, ${heightScale})`;
    containerDom.style.transformOrigin = 'left top';
};

componentDidMount() {
    this.setScale();
    this.windowResizeListener = window.addEventListener('resize', this.setScale);
}
componentWillUnmount() {
    window.removeEventListener('resize', this.windowResizeListener);
}

具体效果如下:

这样处理,无论什么样的大屏,都可以通过缩放来达到适配。缺点是,如果大屏宽高比与设定尺寸宽高比不一致,则会变形。当遇到极端的宽高比可能会变形严重。

有个折中的处理办法,当宽的缩放跟高的缩放比率在某个区间时 (这里我们取[0.7, 1.428]) ,正常缩放;不然就去小的那个倍率缩放。这样处理能够保证变形不严重,但是会空出一部分空白空间。代码如下:

setScale = () => {
  const [widthScale, heightScale] = this.getScale();
  let containerDom = document.getElementById('container');
  // 如果屏幕缩放变形不是太严重,则直接缩放
  const rate = widthScale / heightScale;
  if (rate >= 0.7 && rate <= 1.428) {
    containerDom.style.transform = `scale(${widthScale}, ${heightScale})`;
  } else {
    // 否则取最小的倍率缩放
    const scale = widthScale > heightScale ? heightScale : widthScale;
    containerDom.style.transform = `scale(${scale})`;
  }
  containerDom.style.transformOrigin = 'left top';
};

二. rem 配合 postcss-pxtorem 实现

rem 是根元素字体大小。根据屏幕尺寸大小动态调整 rem 的大小,即可实现多屏幕适配。代码如下:

// rem.js
function setRem() {
  // 基准大小
  const baseSize = 100;
  let vW = window.innerWidth; // 当前窗口的宽度
  let basePc = baseSize / 1920;
  let rem = vW * basePc; // 以默认比例值乘以当前窗口宽度,得到该宽度下的相应font-size值
  document.documentElement.style.fontSize = rem + 'px';
}
// 初始化
setRem();
// 改变窗口大小时重新设置 rem
window.addEventListener('resize', () => {
  setRem();
});

但是开发的时候,写样式用 rem 比较费时费力。最好的方式是正常用 px 写样式,通过 postcss-pxtorem 插件自动完成 px 到 rem 的转变。具体处理如下:

1. 安装 postcss-loader 与 postcss-pxtorem

npm install postcss-loader postcss-pxtorem --save-dev

安装后,可能会遇到postcss-pxtorem requires PostCSS 8的问题,这是由于pxtorem的版本过高导致的,降低pxtorem的版本即可解决。具体可参考文章:PostCSS plugin postcss-pxtorem requires PostCSS 8 问题解决办法

2. 配置

pxtorem 是 postcss 的一个插件,我们在 postcss.config.js 中配置它。代码如下:

// postcss.config.js
module.exports = {
    plugins: [
        require('postcss-pxtorem')({
            rootValue: 100,
            propList: ['*'],
            exclude: /node_modules/  //这里表示不处理node_modules文件夹下的内容
        })
    ]
}

然后我们在 webpack 中配置 postcss-loader,代码如下:

// ...
rules:[
        {
            test: /\.css$/,
            use: [
                MiniCssExtractPlugin.loader,
                "css-loader",
                "postcss-loader"
            ],
        },
        {
            test: /\.less$/,
            use: [
                MiniCssExtractPlugin.loader,
                "css-loader",
                "postcss-loader",
                "less-loader"
            ],
        },
    ]
// ...

其中, postcss-loader 是对 css 进行处理的, 因此放在 less 之前。
通过postcss-pxtorem处理后,所有的px都会被自动转成rem。
我们配置的样式:



浏览器中的样式:



可以看到我们配置的样式从px转换成了rem。

三、两种方式对比

scale 的方式,使用简单,但当目标屏幕与设置屏幕宽高比差距比较大的时候,使用 scale 缩放会导致字体、图片变形。如图:


rem 不会变形,但完全按照屏幕宽度缩放的,有时候可能底部空间剩余较多,或者底部空间不足出现滚动条。如图:


参考资料:
前端大屏项目的屏幕适配方案
webpack配置postcss-pxtorem
PostCSS plugin postcss-pxtorem requires PostCSS 8 问题解决办法

有关多屏幕适配方案的更多相关文章

  1. ruby - 在 jRuby 中使用 'fork' 生成进程的替代方案? - 2

    在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',

  2. 屏幕录制为什么没声音?检查这2项,轻松解决 - 2

    相信很多人在录制视频的时候都会遇到各种各样的问题,比如录制的视频没有声音。屏幕录制为什么没声音?今天小编就和大家分享一下如何录制音画同步视频的具体操作方法。如果你有录制的视频没有声音,你可以试试这个方法。 一、检查是否打开电脑系统声音相信很多小伙伴在录制视频后会发现录制的视频没有声音,屏幕录制为什么没声音?如果当时没有打开音频录制,则录制好的视频是没有声音的。因此,建议在录制前进行检查。屏幕上没有声音,很可能是因为你的电脑系统的声音被禁止了。您只需打开电脑系统的声音,即可录制音频和图画同步视频。操作方法:步骤1:点击电脑屏幕右下侧的“小喇叭”图案,在上方的选项中,选择“声音”。 步骤2:在“声

  3. Ruby 守护进程和 JRuby - 备选方案 - 2

    我有一个应用程序正在从Ruby迁移到JRuby(由于需要通过Java提供更好的Web服务安全支持)。我使用的gem之一是daemons创建后台作业。问题在于它使用fork+exec来创建后台进程,但这对JRuby来说是禁忌。那么-是否有用于创建后台作业的替代gem/wrapper?我目前的想法是只从shell脚本调用rake并让rake任务永远运行......提前致谢,克里斯。更新我们目前正在使用几个与Java线程相关的包装器,即https://github.com/jmettraux/rufus-scheduler和https://github.com/philostler/acts

  4. ruby-on-rails - 我应该使用哪个适用于 Ruby 的 CouchDB 适配器? - 2

    一些我找到的选项是ActiveCouchCouchRESTCouchPotatoRelaxDBcouch_foo我更喜欢GitHub上的项目,因为这让我更容易fork和推送修复。所有这些都符合该要求。我习惯了Rails,所以我喜欢像ActiveRecord模型一样工作的东西。另一方面,我也不希望我和Couch之间太多--毕竟我使用它作为我的数据库是有原因的。最后,它们似乎都得到了相当积极的维护(couch_foo可能是个异常(exception))。所以我想这归结为(不可否认和不幸的)主观:有没有人对他们有过好的或坏的经历? 最佳答案

  5. ruby-on-rails - 能够处理 rar/tar/zip/7z 的 Ruby/rubyzip 替代方案? - 2

    关闭。这个问题不符合StackOverflowguidelines.它目前不接受答案。要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于StackOverflow来说是偏离主题的,因为它们往往会吸引自以为是的答案和垃圾邮件。相反,describetheproblem以及迄今为止为解决该问题所做的工作。关闭9年前。Improvethisquestion我想知道是否有人知道Ruby的ruby​​zip替代品,它可以处理各种格式,特别是zip/rar/7z?我知道libarchive,但它对我的目的来说并不完整(它是一个很好的gem)。(澄清一下,libarchive-对我不起作用-因为

  6. ruby-on-rails - 对于 Ruby 应用程序,是否有比 Sanitize 更好的替代方案? - 2

    我爱Sanitize.这是一个了不起的实用程序。我遇到的唯一问题是,它需要永远准备一个开发环境,因为它使用Nokogiri,这对编译时间来说是一种痛苦。是否有任何程序可以在不使用Nokogiri的情况下执行Sanitize的操作(如果没有别的,只是温和地执行它的操作)?这将以指数方式提供帮助! 最佳答案 Rails有自己的SanitizeHelper。根据http://api.rubyonrails.org/classes/ActionView/Helpers/SanitizeHelper.html,它将Thissanitizehe

  7. ruby-on-rails - 具有六边形架构和 DCI 模式的框架和数据库适配器 - 2

    我尝试用Ruby设计一个基于Web的应用程序。我开发了一个简单的核心应用程序,在没有框架和数据库的情况下在六边形架构中实现DCI范例。核心六边形中有小六边形和网络,数据库,日志等适配器。每个六边形都在没有数据库和框架的情况下自行运行。在这种方法中,我如何提供与数据库模型和实体类的关系作为独立于数据库的关系。我想在将来将框架从Rails更改为Sinatra或数据库。事实上,我如何在这个核心Hexagon中实现完全隔离的rails和mongodb的数据库适配器或框架适配器。有什么想法吗? 最佳答案 ROM呢?(Ruby对象映射器)。还有

  8. ruby-on-rails - rails3 中 cron 作业的解决方案 - 2

    我尝试每天在我的Rails应用程序中自动记录一些数据。我想知道是否有人知道一个好的解决方案?我找到了https://github.com/javan/whenever,但我想确保在选择之前了解所有选项。谢谢!艾略特 最佳答案 我真的很喜欢whenever-这是一个很棒的Gem,我已经在生产中使用了它。关于它还有一个很好的Railscasts插曲:http://railscasts.com/episodes/164-cron-in-ruby 关于ruby-on-rails-rails3中c

  9. ruby-on-rails - 使用 PostgreSQL 适配器限制 ActiveRecord 迁移 5.0 中的文本列 - 2

    我的迁移看起来像这样classCreateQuestionings现在,当我运行$rakedb:migrate:reset时,在我的db/schema.rb中看不到限制:create_table"questionings",force::cascadedo|t|t.text"body",null:falseend我做错了吗还是这是一个错误?顺便说一下,我使用的是rails5.0.0.beta3和ruby​​2.3.0p0。 最佳答案 t.text在PostgreSQL和textdoesn'tallowforsizelimits中生成

  10. ruby-on-rails - 与 Authlogic 一起使用的一些好的角色授权解决方案是什么? - 2

    我正在寻找一个很好的基于角色的授权解决方案来与Authlogic一起使用。有人有什么好的建议吗?如果可能,请根据您的经验列出一些优缺点。 最佳答案 Acl9与AuthLogic配合得很好:http://github.com/be9/acl9/tree/master 关于ruby-on-rails-与Authlogic一起使用的一些好的角色授权解决方案是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.c

随机推荐