开源可视化引擎 Meta2d.js 实战 - 缩略图

一、缩略图的作用

缩略图,能够让创作者直观看到图纸的设计情况。通常有2个场景需要查看图纸缩略图:

  1. 设计窗口缩略图
  2. 缩略图形式的 文件列表

1.1 设计窗口缩略图

在创造设计时,当图纸尺寸比较大时,就需要使用到缩略图了。此功能,meta2d.js已经内置了功能。调用相关的函数即可实现。效果如下:

使用 meta2d的 showMap或hideMap方法即可实现。

说明:下面的所有代码中,engineObj 为meta2d的实例变量名

typescript 复制代码
if(engineObj.value.map.isShow) {
    engineObj.hideMap();
}else{
    engineObj.showMap();
}

这里主要说明第2个场景:文件列表的缩略图。

1.2 文件列表缩略图

看一下实际效果:

二、实现缩略图列表

以列表方式显示缩略图,需要考虑到现实布局、响应性显示等因素,这需要搞清楚2个问题:

  1. 如何生成缩略图
  2. 如何响应性的显示,以保持页面合理布局

2.1 生成缩略图

实际上,meta2d.js已经提供了生成缩略图的功能:

Meta2d.toPng(padding?: Padding, callback?: BlobCallback, containBkImg?: boolean, maxWidth?: number): string

可以看出,调用此函数,会返回一个字符串类型。

调用代码:

typescript 复制代码
 const image = engineObj.toPng();
 console.log('生成缩略图结果:', image);

实际的返回结果:

通过结果,可以看出 toPng方法返回的是一个base64编码的图片字符串。那么,显示此图片,只需要我们直接将此值放在image标签中的src即可。

2.2 显示自适应缩略图

原本说明生成缩略图时,就完成了本文主要的目的。之所以写这个部分,是因为我在开发中遇到了如何保持在不同分辨率下,缩略图都不会变形的问题。当然,这主要是由于我并非专业的前端,对css还不十分的熟悉,平时遇到问题更多的是通过查询来解决问题。我想,应该也会有开发者遇到这样的情况,因此分享一下。

2.2.1 自适应布局

我使用的是quasar框架中的布局组件,使用antd、elementUI或其他框架的原理都是一样的。

我们知道,这些UI框架,都把屏幕分为12或者24个栅格。这个数字是将屏幕横向平均切分的,因此,考虑不同分辨率缩略图不变形,我们无需关心宽度,只需把高度设定为动态的就好。

div动态高度的一种方法是:

  1. 设定div高度为0,
  2. 设置padding-top的值为百分比

实现如上面的文件列表缩略图所示,需要将2个div:

  1. 父div实现动态的宽高比,位置为相对路径
  2. 子div位置为绝对路径,对图片大小进行限制

在vue中模板代码主要如下:

html 复制代码
<div class="row q-col-gutter-lg">
  <div class="col-3 cursor-pointer" @click="newFile">
    <div class="q-pa-md flex items-center justify-center file-thumbnail-container">
      <div class="icon">
        <q-icon name="mdi-plus" size="60px" color="grey-6" />
      </div>
    </div>
    <div class="text-center q-mt-xs text-subtitle1">开始设计</div>
  </div>

  <!-- 循环最近的文件 start -->
  <template v-for="d in recentlyFiles" :key="d.id">
    <div class="col-3 cursor-pointer" @click="showDrawing(d)">
      <div class="q-pa-md flex items-center justify-center file-thumbnail-container">
        <div class="image">
          <q-img :src="((d.img) as string)" height="100%" fit="contain" />
        </div>
      </div>
      <div class="text-center q-mt-xs text-subtitle1">{{ d.name }}</div>
    </div>
  </template>

  <!-- 循环最近的文件 end -->
</div>

上面模板代码中,循环的列表对象的img属性,就是生成缩略图的base64图片的字符串,此处逻辑是从数据源读取后,循环显示而已。

关键的2个css定义如下:

scss 复制代码
<style lang="scss">
.file-thumbnail-container {
  position: relative;
  height: 0;
  padding-top: 62.5%;
  background-color: transparent;
  border: 1px solid $grey-4;
  border-radius: 8px;

  .icon {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    overflow: hidden;
  }

  .image {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    padding: 1rem;
  }

}
</style>

2.2.2 父div说明

如果想保持每个div在宽度固定的情况下,高度随不同分辨率自动调整,就必须以宽度为依据(此时,在当前屏幕分辨率下,父div宽度的1/4),将高度设置为宽度的固定百分比。

假设以分辨率1440*900为基准,高宽比则为: 900/1440 = 62.5% ,则padding-top就设置为62.5%,这就是上面file-thumbnail-container类中padding-top的计算逻辑。

2.2.3 子div说明

这里说的子div,指的是 image 类。主要就是规定了宽和高是父窗口的100%。

2.2.4 图片标签说明

在子div中,有一个q-img标签,这是quasar框架的图片组件,其他ui框架也有对应的,不再单独说明。

需要说明的是,此处有2个属性设定:

  1. 图片的高度必须设置成100%,即图片和其容器div的高度一致
  2. fit="contain" ,fit是q-img组件的一个属性,相当于在css中定义的object-fit属性,控制图片如何适应与容器。

至此,自适应的缩略图,就可以按我们设定的规则显示了。

相关推荐
Zero1017131 小时前
【详解pnpm、npm、yarn区别】
前端·react.js·前端框架
&白帝&2 小时前
vue右键显示菜单
前端·javascript·vue.js
Wannaer2 小时前
从 Vue3 回望 Vue2:事件总线的前世今生
前端·javascript·vue.js
羽球知道2 小时前
在Spark搭建YARN
前端·javascript·ajax
光影少年3 小时前
vue中,created和mounted两个钩子之间调用时差值受什么影响
前端·javascript·vue.js
青苔猿猿3 小时前
node版本.node版本、npm版本和pnpm版本对应
前端·npm·node.js·pnpm
一只码代码的章鱼3 小时前
Spring的 @Validate注解详细分析
前端·spring boot·算法
zimoyin4 小时前
Kotlin 协程实战:实现异步值加载委托,对值进行异步懒初始化
java·前端·kotlin
程序员与背包客_CoderZ5 小时前
Node.js异步编程——Callback回调函数实现
前端·javascript·node.js·web
非凡ghost6 小时前
Pale Moon:速度优化的Firefox定制浏览器
前端·firefox