使用 Babylon.js 开发时如何通过 CSS 实现 UI 自适应

        本文将介绍如何在 Babylon.js 开发中,通过预先定义的 CSS 文件实现 UI 的自适应布局,确保 UI 能够根据 Canvas 元素的尺寸动态调整。

场景描述

        假设我们已经使用 HTML 和 CSS 构建了 Babylon.js 的 UI 界面,并且所有样式都定义在 CSS 文件中。现在,我们需要让这些 UI 元素能够根据 Canvas 的尺寸动态调整,以实现自适应的效果。

解决方案

1. 使用 CSS 变量(推荐)

        CSS 变量(Custom Properties)是 CSS3 引入的特性,允许我们定义可动态更新的变量。通过结合 JavaScript,我们可以根据 Canvas 的尺寸动态调整 CSS 变量,从而实现 UI 的自适应。

1.1 在 CSS 文件中定义变量

        首先,在 CSS 文件中定义一些变量,用于控制 UI 元素的尺寸、位置等属性。

:root {--ui-width: 100px; /* 默认宽度 */--ui-height: 50px; /* 默认高度 */--ui-font-size: 16px; /* 默认字体大小 */
}.ui-element {width: var(--ui-width);height: var(--ui-height);font-size: var(--ui-font-size);background-color: rgba(255, 255, 255, 0.8);text-align: center;padding: 10px;position: absolute;top: 10%;left: 10%;
}
1.2 在 JavaScript 中动态更新 CSS 变量

        接下来,通过 JavaScript 监听 Canvas 的尺寸变化,并动态更新 CSS 变量。

const canvas = document.getElementById("renderCanvas");// 监听 Canvas 尺寸变化
const observer = new ResizeObserver(entries => {for (let entry of entries) {const { width, height } = entry.contentRect;updateUIStyle(width, height);}
});
observer.observe(canvas);// 更新 CSS 变量
function updateUIStyle(width, height) {const root = document.documentElement;root.style.setProperty('--ui-width', `${width * 0.8}px`); // 80% 的 Canvas 宽度root.style.setProperty('--ui-height', `${height * 0.1}px`); // 10% 的 Canvas 高度root.style.setProperty('--ui-font-size', `${height * 0.02}px`); // 字体大小随高度变化
}// 初始设置
window.addEventListener('load', () => {updateUIStyle(canvas.width, canvas.height);
});
1.3 优点
  • 代码简洁:通过 CSS 变量,可以轻松实现样式的动态调整。
  • 易于维护:所有样式定义在 CSS 文件中,JavaScript 只负责更新变量。

2. 使用类名切换(备选)

        如果不想使用 CSS 变量,可以通过动态添加或切换类名来实现自适应。

2.1 在 CSS 文件中定义不同尺寸的类

        在 CSS 文件中定义多个类,分别对应不同的 Canvas 尺寸。

.ui-element {background-color: rgba(255, 255, 255, 0.8);text-align: center;padding: 10px;position: absolute;top: 10%;left: 10%;
}/* 小尺寸 */
.ui-element.small {width: 100px;height: 50px;font-size: 12px;
}/* 中尺寸 */
.ui-element.medium {width: 200px;height: 100px;font-size: 16px;
}/* 大尺寸 */
.ui-element.large {width: 300px;height: 150px;font-size: 20px;
}
2.2 在 JavaScript 中动态切换类名

        根据 Canvas 的尺寸动态切换 UI 元素的类名。

const canvas = document.getElementById("renderCanvas");
const uiElement = document.querySelector('.ui-element');// 监听 Canvas 尺寸变化
const observer = new ResizeObserver(entries => {for (let entry of entries) {const { width, height } = entry.contentRect;updateUIClass(width, height);}
});
observer.observe(canvas);// 根据尺寸切换类名
function updateUIClass(width, height) {if (width < 600) {uiElement.classList.remove('medium', 'large');uiElement.classList.add('small');} else if (width < 1024) {uiElement.classList.remove('small', 'large');uiElement.classList.add('medium');} else {uiElement.classList.remove('small', 'medium');uiElement.classList.add('large');}
}// 初始设置
window.addEventListener('load', () => {updateUIClass(canvas.width, canvas.height);
});
2.3 优点
  • 兼容性好:适用于不支持 CSS 变量的旧版浏览器。
  • 灵活性高:可以通过定义多个类实现复杂的自适应逻辑。

补充一个最近开发时的案例

css文件参考:

body{background-color:#000723;
}canvas{width: 100%; height: 100%; position:absolute;top:0px;left:0px;background-color: #000723;z-index: -100;
}#containerSel3DIcon {position: absolute; /* 或者使用 relative/fixed */top: 0;left: 0;width: 100%;height: 100%;pointer-events: none;overflow: hidden;
}
.Sel3DIcon{position: absolute;text-align: left;vertical-align: top;pointer-events: auto;cursor: pointer;z-index: -99;
}
.Sel3DIcon img{width: 32px;height: 32px;
}
.Sel3DIcon span{font-size: 18px;color: #fff;text-align: left;vertical-align: top;text-shadow: 2px 2px 2px rgba(0, 0, 0, 0.9);
}

js文件中UI自适应部分的代码参考:

function AdaptiveStyles(){const styleSheets = document.styleSheets;const iconSize = Math.round(canvas.height * 0.026);const contentSize = Math.round(canvas.height * 0.016);for (let i = 0; i < styleSheets.length; i++) {const styleSheet = styleSheets[i];const rules = styleSheet.cssRules;for (let j = 0; j < rules.length; j++) {const rule = rules[j];if (rule.selectorText === '.Sel3DIcon img') {console.log("img");rule.style.width = `${iconSize}px`;rule.style.height = `${iconSize}px`;}else if (rule.selectorText === '.Sel3DIcon span') {console.log("span");rule.style.fontSize = `${contentSize}px`;}}}
}AdaptiveStyles();window.addEventListener('resize', function() {engine.resize();AdaptiveStyles();
});

        在该段代码中使用了模板字符串,关于模板字符串的使用方法,请参看以下链接:

模板字符串VS普通字符串:核心区别与使用场景

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

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

相关文章

FPGA与ASIC:深度解析与职业选择

IC&#xff08;集成电路&#xff09;行业涵盖广泛&#xff0c;涉及数字、模拟等不同研究方向&#xff0c;以及设计、制造、封测等不同产业环节。其中&#xff0c;FPGA&#xff08;现场可编程门阵列&#xff09;和ASIC&#xff08;专用集成电路&#xff09;是两种重要的芯片类型…

【Linux】Linux入门(三)权限

目录 前提权限概念whoami指令 Linux权限管理文件访问者的分类&#xff08;人&#xff09;file指令权限信息权限的表示方法 chmod指令 更改权限chown指令 修改文件&#xff0c;文件夹所属用户和用户组 权限掩码umask&#xff08;权限掩码&#xff09; 粘滞位 前提 请先看下面这…

蓝桥与力扣刷题(73 矩阵置零)

题目&#xff1a;给定一个 m x n 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,1,1],[1,0,1],[1,1,1]] 输出&#xff1a;[[1,0,1],[0,0,0],[1,0,1]]示例 2&…

Node.js接收文件分片数据并进行合并处理

前言&#xff1a;上一篇文章讲了如何进行文件的分片&#xff1a;Vue3使用多线程处理文件分片任务&#xff0c;那么本篇文章主要看一下后端怎么接收前端上传来的分片并进行合并处理。 目录&#xff1a; 一、文件结构二、主要依赖1. express2. multer3. fs (文件系统模块)4. pat…

大数据,Hadoop,HDFS的简单介绍

大数据 海量数据&#xff0c;具有高增长率、数据类型多样化、一定时间内无法使用常规软件工具进行捕捉、管理和处理的数据集 合 大数据的特征: 4V Volume : 巨大的数据量 Variety : 数据类型多样化 结构化的数据 : 即具有固定格式和有限长度的数据 半结构化的数据 : 是…

深度强化学习:PPO

深度强化学习算法&#xff1a;PPO 1. Importance Sampling 先说一下什么是采样&#xff1a;对于一个随机变量&#xff0c;我们通常用概率密度函数来描述该变量的概率分布特性。具体来说&#xff0c;给定随机变量的一个取值&#xff0c;可以根据概率密度函数来计算该值对应的概…

Flink底层架构与运行流程

这张图展示了Flink程序的架构和运行流程。 主要组件及功能&#xff1a; Flink Program&#xff08;Flink程序&#xff09;&#xff1a; 包含Program code&#xff08;程序代码&#xff09;&#xff0c;这是用户编写的业务逻辑代码。经过Optimizer / Graph Builder&#xff08…

嵌入式知识点总结 C/C++ 专题提升(一)-关键字

针对于嵌入式软件杂乱的知识点总结起来&#xff0c;提供给读者学习复习对下述内容的强化。 目录 1.C语言宏中"#“和"##"的用法 1.1.(#)字符串化操作符 1.2.(##)符号连接操作符 2.关键字volatile有什么含意?并举出三个不同的例子? 2.1.并行设备的硬件寄存…

mysql精简单机版,免登录,可复制,不启动服务与本机mysql无冲突

突然有了个需要在本地使用的mysql需求&#xff0c;要求不用安装,随拷随用,不影响其他mysql服务,占用空间小.基于这种需求做了个精简版的mysql 首先下载mysql的zip安装包 > windows 64位 > https://repo.huaweicloud.com/mysql/Downloads/MySQL-5.7/mysql-5.7.36-winx64…

俄语画外音的特点

随着全球媒体消费的增加&#xff0c;语音服务呈指数级增长。作为视听翻译和本地化的一个关键方面&#xff0c;画外音在确保来自不同语言和文化背景的观众能够以一种真实和可访问的方式参与内容方面发挥着重要作用。说到俄语&#xff0c;画外音有其独特的特点、挑战和复杂性&…

【vitePress】基于github快速添加评论功能(giscus)

一.添加评论插件 使用giscus来做vitepress 的评论模块&#xff0c;使用也非常的简单&#xff0c;具体可以参考&#xff1a;giscus 文档&#xff0c;首先安装giscus npm i giscus/vue 二.giscus操作 打开giscus 文档&#xff0c;如下图所示&#xff0c;填入你的 github 用户…

python麻辣香锅菜品推荐

1.推荐算法概述 推荐算法出现得很早,最早的推荐系统是卡耐基梅隆大学推出的Web Watcher浏览器导航系统&#xff0c;可以根据当的搜索目标和用户信息,突出显示对用户有用的超链接。斯坦福大学则推出了个性化推荐系统LIRA.AT&T实验室于1997年提出基于协作过滤的个性化推荐系统…

Android系统开发(六):从Linux到Android:模块化开发,GKI内核的硬核科普

引言&#xff1a; 今天我们聊聊Android生态中最“硬核”的话题&#xff1a;通用内核镜像&#xff08;GKI&#xff09;与内核模块接口&#xff08;KMI&#xff09;。这是内核碎片化终结者的秘密武器&#xff0c;解决了内核和供应商模块之间无尽的兼容性问题。为什么重要&#x…

UE 像素流Pixel Streaming笔记

参考 UE 像素流Pixel Streaming基本介绍和使用方法 UE4-PixelStreaming&#xff08;虚幻引擎4-像素流&#xff09;笔记 UE 像素流常用回调 UE 像素流通信 这链接能学到不少像素流的东西 使用 1.像素流连接成功&#xff08;On New Connection&#xff09; 必须使用GetPixe…

Java 资源管理教程:掌握 close 方法、Cleaner 类与 Runtime.addShutdownHook

在 Java 编程中&#xff0c;高效地管理资源是至关重要的&#xff0c;特别是当你处理文件、数据库连接、网络连接等有限资源时。为了确保这些资源得到正确释放&#xff0c;Java 提供了多种机制。本教程将深入探讨 close 方法、Cleaner类以及 Runtime.addShutdownHook 方法&#…

ASP.NET Blazor部署方式有哪些?

今天我们来说说Blazor的三种部署方式&#xff0c;如果大家还不了解Blazor&#xff0c;那么我先简单介绍下Blazor Blazor 是一种 .NET 前端 Web 框架&#xff0c;在单个编程模型中同时支持服务器端呈现和客户端交互性&#xff1a; ● 使用 C# 创建丰富的交互式 UI。 ● 共享使用…

微信小程序使用上拉加载onReachBottom。页面拖不动。一直无法触发上拉的事件。

1&#xff0c;可能是原因是你使用了scroll-view的标签&#xff0c;用onReachBottom触发加载事件。这两个是有冲突的。没办法一起使用。如果页面的样式是滚动的是无法去触发页面的onReachBottom的函数的。因此&#xff0c;你使用overflow:auto.来使用页面的某些元素滚动&#xf…

学习ASP.NET Core的身份认证(基于JwtBearer的身份认证9)

测试数据库中只有之前记录温湿度及烟雾值的表中数据较多&#xff0c;在该数据库中增加AppUser表&#xff0c;用于登录用户身份查询&#xff0c;数据库表如下所示&#xff1a;   项目中安装SqlSugarCore包&#xff0c;然后修改控制器类的登录函数及分页查询数据函数&#xff…

【人工智能】:搭建本地AI服务——Ollama、LobeChat和Go语言的全方位实践指南

前言 随着自然语言处理&#xff08;NLP&#xff09;技术的快速发展&#xff0c;越来越多的企业和个人开发者寻求在本地环境中运行大型语言模型&#xff08;LLM&#xff09;&#xff0c;以确保数据隐私和提高响应速度。Ollama 作为一个强大的本地运行框架&#xff0c;支持多种先…

Flutter:carousel_slider 横向轮播图、垂直轮播公告栏实现

安装依赖 carousel_slider: ^5.0.01、垂直滚动公告栏 import package:carousel_slider/carousel_options.dart;// 垂直滚动公告栏Widget _buildNotice() {return <Widget>[<Widget>[TDImage(assetUrl: "assets/img/home11.png",width: 60.w,height: 60.w…