Skip to content

做一个展厅大屏解决的一些问题

近期临时做了展厅大屏的前端玩具, 需求要求的比例为1080x1920,技术栈Vite+Vue3。

px to rem

简单起见,vite上直接引用了 vite-plugin-px-rem-vw, 简化屏幕适配。

相关代码解析: [vite-plugin-px-rem-vw使用原理]

js
import pxToRemOrVwPlugin from "vite-plugin-px-rem-vw" 

// vite.config.js/ts
import { defineConfig } from 'vite'
export default defineConfig({
  ...
  plugins: [
    pxToRemOrVwPlugin({
      type: 'rem',
      options: {
        rootValue: 108 
      }
    }),
  ],
  ...
import pxToRemOrVwPlugin from "vite-plugin-px-rem-vw" 

// vite.config.js/ts
import { defineConfig } from 'vite'
export default defineConfig({
  ...
  plugins: [
    pxToRemOrVwPlugin({
      type: 'rem',
      options: {
        rootValue: 108 
      }
    }),
  ],
  ...

背景大图的适配

  1. 文字段落背景,可以使用.bg-for-full, 让文本把背景图片撑开,背景图片可以适当缩放。
  2. 普通的背景图片,若显示不全也可以,可以使用 .bg-for-cover
css
.bg-for-full {
    background-repeat: no-repeat;
    background-size: 100% 100%;
    background-position: center center; /* 图片居中显示 */
}

.bg-for-cover {
    background-size: cover;
}
.bg-for-full {
    background-repeat: no-repeat;
    background-size: 100% 100%;
    background-position: center center; /* 图片居中显示 */
}

.bg-for-cover {
    background-size: cover;
}

参考: background-size - CSS:层叠样式表 | MDN

如何网页全屏

实现win系统点击F11 的效果:

js
let element = document.documentElement;
if (element.requestFullscreen) {
	element.requestFullscreen();
} else if (element.mozRequestFullScreen) {
	element.mozRequestFullScreen();
} else if (element.webkitRequestFullscreen) {
	element.webkitRequestFullscreen();
} else if (element.msRequestFullscreen) {
	element.msRequestFullscreen();
}
let element = document.documentElement;
if (element.requestFullscreen) {
	element.requestFullscreen();
} else if (element.mozRequestFullScreen) {
	element.mozRequestFullScreen();
} else if (element.webkitRequestFullscreen) {
	element.webkitRequestFullscreen();
} else if (element.msRequestFullscreen) {
	element.msRequestFullscreen();
}

如何实现打包后,点击index.html可以直接访问 (file://协议)

因为笔者要做的大屏无需访问网络,故可以让浏览器可以直接访问index.html,不再需要部署到nginx等环境。可以通过如下方式设置:

1. 打包设置为相对目录

vite.config.ts:

js
export default defineConfig({
    base: '', // or './'
    ...
}
export default defineConfig({
    base: '', // or './'
    ...
}

router调整为hash模式:

js
const router = createRouter({
    history: createWebHashHistory(), 
    routes: [
    ...
})
const router = createRouter({
    history: createWebHashHistory(), 
    routes: [
    ...
})
  1. 打包,浏览器直接打开index.html会报跨域问题。 原因是直接打开的本地文件(file://协议),不支持 type="module" 方式的script引入。如果引用了就报跨域(笔者认为不太合理,网上也有一段关于它的讨论 Suggestion: You should be able to load module-scripts in the file:// protocol. · Issue #8121 · whatwg/html),解决方式可以使用插件vite-plugin-make-offline (参考: How to use vite in file Protocol · vitejs/vite · Discussion #6676 )。

使用方式:

bash
import {makeOffline} from "vite-plugin-make-offline"; // TODO: 原理解析
export default defineConfig({
    base: '',
    plugins: [
        vue(),
        vueJsx(),
        // 设置支持打离线包,支持使用file访问
        makeOffline(),
        pxToRemOrVwPlugin({
            type: 'rem',
            options: {
                rootValue: 108
            }
        }),
    ]
    ...
})
import {makeOffline} from "vite-plugin-make-offline"; // TODO: 原理解析
export default defineConfig({
    base: '',
    plugins: [
        vue(),
        vueJsx(),
        // 设置支持打离线包,支持使用file访问
        makeOffline(),
        pxToRemOrVwPlugin({
            type: 'rem',
            options: {
                rootValue: 108
            }
        }),
    ]
    ...
})

这个插件代码实际非常简单,修改打包输出为iife: vite-plugin-make-offline/src/index.ts

经过一番改造,我可以直接把视频素材放到本地,读取相对路径的文件。

bash
  <video controls style="width: 100%;">
	<source :src="file" type="video/mp4">
	当前浏览器不支持播放该视频
  </video
  ...
  export default {
	  components: {
	    TopView,
	    BottomView
	  },
	  data() {
	    return {
	      // 生产环境使用 './assets/video.mp4' 
	      file: './assets/video.mp4'
	    }
	  }
  }
  <video controls style="width: 100%;">
	<source :src="file" type="video/mp4">
	当前浏览器不支持播放该视频
  </video
  ...
  export default {
	  components: {
	    TopView,
	    BottomView
	  },
	  data() {
	    return {
	      // 生产环境使用 './assets/video.mp4' 
	      file: './assets/video.mp4'
	    }
	  }
  }

如何实现写一个脚本,实现点击全屏

chrome上不允许JS直接调用requestFullscreen 方法,必须要用户手动触发。

由于设备是win系统的,这里使用vb脚本实现全屏效果,思考了两种方案

方式1: 使用kiosk 打开全屏的浏览器,缺点是要退出这个全屏页面比较难
方式2: 使用脚本打开浏览器页面,并用脚本点击F11,示例代码如下,仅供参考:

vb
' startWebView.vbs 
Dim delayer
Set delayer = CreateObject("WScript.Shell")

Dim fso, currentFolder
Set fso = CreateObject("Scripting.FileSystemObject")
currentFolder = fso.GetParentFolderName(WScript.ScriptFullName)
' 拼接目录:脚本文件下的 index.html文件
env = "file:///" & currentFolder & "/index.html"
' 打开对应页面并点击f11
Set objShell = CreateObject("WScript.Shell")
' 打开浏览器的对应页面
objShell.Run "chrome " & env

Wscript.Sleep 1000
' 点击F11
objShell.SendKeys "{F11}"

Set delayer = Nothing
WScript.quit
' startWebView.vbs 
Dim delayer
Set delayer = CreateObject("WScript.Shell")

Dim fso, currentFolder
Set fso = CreateObject("Scripting.FileSystemObject")
currentFolder = fso.GetParentFolderName(WScript.ScriptFullName)
' 拼接目录:脚本文件下的 index.html文件
env = "file:///" & currentFolder & "/index.html"
' 打开对应页面并点击f11
Set objShell = CreateObject("WScript.Shell")
' 打开浏览器的对应页面
objShell.Run "chrome " & env

Wscript.Sleep 1000
' 点击F11
objShell.SendKeys "{F11}"

Set delayer = Nothing
WScript.quit

如何实现开机启动脚本

将需要执行的脚本放到C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp目录下,即可实现开机自启。

因为需要依赖脚本所在目录,可以制作一个脚本的快捷方式,在把这个快捷方式放到StartUp目录中。

一键生成快捷方式的脚本如下(嗅到了GPT4的味道):

vb
Option Explicit

Dim objShell, objCurrentFolder, objShortcut, strCurrentPath, strTargetName
strTargetName = "startWebView.vbs" ' 需要创建快捷方式的目标脚本名

' 创建 Shell 对象
Set objShell = CreateObject("WScript.Shell")

' 获取当前目录的路径
strCurrentPath = objShell.CurrentDirectory

' 要创建快捷方式的完整路径
Dim strShortcutPath
strShortcutPath = strCurrentPath & "\startWebView.lnk" ' 快捷方式的名称

' 要创建快捷方式指向的目标路径
Dim strTargetPath
strTargetPath = strCurrentPath & "\" & strTargetName

' 创建快捷方式对象
Set objShortcut = objShell.CreateShortcut(strShortcutPath)

' 设置快捷方式的目标路径
objShortcut.TargetPath = strTargetPath

' 可选:设置快捷方式的工作目录
objShortcut.WorkingDirectory = strCurrentPath

' 保存快捷方式
objShortcut.Save
Option Explicit

Dim objShell, objCurrentFolder, objShortcut, strCurrentPath, strTargetName
strTargetName = "startWebView.vbs" ' 需要创建快捷方式的目标脚本名

' 创建 Shell 对象
Set objShell = CreateObject("WScript.Shell")

' 获取当前目录的路径
strCurrentPath = objShell.CurrentDirectory

' 要创建快捷方式的完整路径
Dim strShortcutPath
strShortcutPath = strCurrentPath & "\startWebView.lnk" ' 快捷方式的名称

' 要创建快捷方式指向的目标路径
Dim strTargetPath
strTargetPath = strCurrentPath & "\" & strTargetName

' 创建快捷方式对象
Set objShortcut = objShell.CreateShortcut(strShortcutPath)

' 设置快捷方式的目标路径
objShortcut.TargetPath = strTargetPath

' 可选:设置快捷方式的工作目录
objShortcut.WorkingDirectory = strCurrentPath

' 保存快捷方式
objShortcut.Save