likes
comments
collection
share

GoView潜伏的另一隐患: 外层容器transform之后, 不同分辨率下, 内部组件存在拉伸问题前言 由于需要兼

作者站长头像
站长
· 阅读数 15

前言

由于需要兼容不同的屏幕分辨率, GoView在外层容器上设置了transform, 导致的后果是: 内部所有组件皆被拉伸, 这并不是用户希望看到的.

为了彻底解决该问题, 我决定删除该外层容器, 使用postcss-px-to-viewport解决不同屏幕分辨率下, 组件的宽高、位置等样式问题.

正文

引入postcss-px-to-viewport

在项目根目录下, 新增postcss.config.js文件, 其内容如下

module.exports = {
  plugins: {
    'postcss-px-to-viewport': {
      unitToConvert: 'px', // 需要转换的单位
      viewportWidth: 1920, // 设计稿的视口宽度
      unitPrecision: 5, // 转换后保留的小数位数
      propList: ['*'], // 需要进行转换的 CSS 属性,* 表示所有
      viewportUnit: 'vw', // 指定转换后的视口单位
      fontViewportUnit: 'vw', // 字体使用的视口单位
      selectorBlackList: ['.ignore'], // 指定不转换为视口单位的类
      minPixelValue: 1, // 小于或等于 1px 不进行转换
      mediaQuery: false, // 允许在媒体查询中转换 px
      exclude: [/node_modules\/(?!naive)/] // 忽略某些文件夹或文件
    }
  }
}

此处将viewportWidth设置为1920, 这并非意味着仅仅只能匹配1920宽度的分辨率, 相反postcss-px-to-viewport以此为基准, 在不同分辨率下, 做vw的自动转换.

举个简单的例子, 1920时, 你看到的字体大小为28px, 当为2880时, 字体大小会自动调整为42px

GoView潜伏的另一隐患: 外层容器transform之后,  不同分辨率下,  内部组件存在拉伸问题前言 由于需要兼

GoView潜伏的另一隐患: 外层容器transform之后,  不同分辨率下,  内部组件存在拉伸问题前言 由于需要兼

这种自动转换的前提是, 字体大小单位必须为vw.

修改vite.config.ts

vite.config.ts文件内, 增加如下配置

...
export default defineConfig(({ command, mode }) => {
  const env = loadEnv(mode, process.cwd())
  return {
      css: {
          ...
          postcss: './postcss.config.js'
      },
   }
})
        
  

将组件的lefttoppx转换为vwvh

我们只需处理预览页面下, 各个组件容器的位置、宽高.

let viewportWidth = window.innerWidth;
let viewportHeight = window.innerHeight;
let aspectRatio = viewportWidth / viewportHeight
// 设置位置
export const getComponentAttrStyle = (attr: AttrType, index: number) => {
  let h = 100 - (attr.h * aspectRatio / 1920) * 100
  h = h < 0 ? 0 : h
  const minTop = Math.min(h, (attr.y / 1080) * 100)
  const componentStyle = {
    zIndex: index + 1,
    left: pxToVw(attr.x),
    top: minTop + 'vh'
  }
  return componentStyle
}

上面的minTop是为了处理, 在3880*1080分辨率时, 处于底部的部分组件会存在显示不全的问题.

(attr.h * aspectRatio / 1920) * 100是为了处理长宽相同的组件, 位于页面底部时存在遮挡的问题. (attr.h / 1920) * 100是将当前组件的高度像素转换为vw, *aspectRatio是将vw转换为实际的vh值.

Math.min(h, (attr.y / 1080) * 100)从两者之间选取最小的top

GoView潜伏的另一隐患: 外层容器transform之后,  不同分辨率下,  内部组件存在拉伸问题前言 由于需要兼

我给红框组件单独设置了height: v-bind('pxToVw(h)');, 其他组件的高度默认使用vh. 因为若该组件的高度设置为vh, 则宽高会存在不一致的情况, 即在3880 * 1080的分辨率下时, 该组件会呈椭圆形, 为了保证组件宽高一致, 都需采用vw单位.

GoView潜伏的另一隐患: 外层容器transform之后,  不同分辨率下,  内部组件存在拉伸问题前言 由于需要兼

将组件内联样式里的px转换为vwvh

postcss-px-to-viewport只能处理静态文件里的px转换, 组件内联样式里的px或变量px需手动转换为vwvh, 代码如下所示

export function pxToVw(px: number) {
  return `${(px / 1920) * 100}vw`;
}
export function pxToVh(px: number) {
  return `${(px / 1080) * 100}vh`;
}
<template>
  <div class="tables-basic">
    <n-data-table
      size="small"
      :style="`
        width: ${pxToVw(w)};
        height: ${pxToVh(h)};
        font-size: ${pxToVw(option.style.fontSize)};
      `"
   </div>
</template>
<script setup lang="ts">
import { pxToVw, pxToVh } from '@/utils'
</script>
<style lang="scss" scoped>
@include deep() {
  .n-base-selection-label {
    height: v-bind('pxToVh(h)');
    display: flex;
    align-items: center;
  }

  .n-base-selection-tag-wrapper {
    padding: v-bind('`${pxToVh(paddingY)} ${pxToVw(paddingX)}`');
  }
}
</style>

尾声

经测试, 在不同的屏幕分辨率下, 各个组件皆能正常显示, 至此成功地解决了预览页面中组件的拉伸问题, 感兴趣的小伙伴们欢迎在下方留言、点赞或关注哦~

转载自:https://juejin.cn/post/7423582965215100963
评论
请登录