当前位置: 首页 > article >正文

【Godot4.3】自定义圆角容器

概述

Godot控件想要完全实现现代UI风格,需要进行大量的自定义组件设计。本篇就依托于笔者自己对现代UI设计中的圆角面板元素模仿来制作圆角容器组件。

圆角容器

圆角元素在现代的扁平UI设计中非常常见,在Godot中可以通过改进PanelContainer来或者自定义容器来实现圆角面板效果。

  • 我初期想基于PanelContainer写一个容器类,但是发现比较绕
  • 于是还是直接基于Container类型写了一个自定义容器类
  • 初期我偏向于直接用绘图函数绘制StyleBox
  • 但是当遇到渐变和图片时,绘制StyleBox的方式将无法获得圆角
  • 所以最后不得不采用绘图函数draw_colored_polygon,并且自己计算圆角矩形顶点集合以及计算每个点的UV坐标,从而实现一种类似矢量遮罩的效果。

最终实现效果

基础效果

RadiusPanelContainer

容器的自定义参数如下:

基本参数

实现如下功能:

  • 快速获得带圆角的纯色、图片背景(包括渐变等)的容器
  • 可以设定统一的描边颜色、宽度,以及圆角大小
  • 可以设定子元素的内边距
  • 可以设定容器的不透明度

注意: 需要搭配常见容器使用,第一个子元素也是唯一被正确显示的第一级子元素,需要是一个容器类型。


第一级第一个子元素需要为容器类型

完整代码

# ==========================================================
# RadiusPanelContainer
# 类型:自定义容器
# 概述:现代化UI系列,实现基础的圆角面板元素
# 巽星石
# 创建时间20251313:45:32
# 最后修改时间:20251317:54:39
# ==========================================================
@tool
class_name  RadiusPanelContainer extends Container# =============================== 参数 ===============================@export var padding:=10: ## 内边距set(val):padding = valqueue_redraw()@export_range(0.0,1.0,0.1) var opacity=1.0: ## 透明度set(val):opacity = valif val:self_modulate = Color(1.0,1.0,1.0,val)queue_redraw()@export_group("background")
@export var bg_color:=Color.WHITE: ## 背景颜色set(val):bg_color = valqueue_redraw()@export var bg_texture:Texture2D: ## 背景图片set(val):bg_texture = valqueue_redraw()@export_group("border")
@export var border_color:=Color.WHITE: ## 边框颜色set(val):border_color = valqueue_redraw()@export var border_radius:=5: ## 圆角半径set(val):border_radius = valqueue_redraw()@export var border_width:=0:## 边线宽度set(val):border_width = valqueue_redraw()# =============================== 虚函数 ===============================
func _init() -> void:clip_contents = truefunc _draw() -> void:var rect = get_rect() * get_transform()var pots = round_rect(rect,border_radius,border_width/2.0)# 绘制背景if bg_texture:var uvs:PackedVector2Arrayfor pot in pots: # 计算UV坐标uvs.append(pot/rect.size)# 绘制圆角矩形draw_colored_polygon(pots,bg_color,uvs,bg_texture)else:draw_polygon(pots,[bg_color])# 绘制边线draw_polyline(pots,border_color,border_width)# 重排子元素queue_sort()func _notification(what: int) -> void:var rect = get_rect() * get_transform()rect.position += Vector2.ONE * paddingrect.size -= Vector2.ONE * padding * 2match what:NOTIFICATION_SORT_CHILDREN:if get_child_count()>0:fit_child_in_rect(get_children()[0],rect)# =============================== 自定义函数 ===============================
# 求圆弧点集
func arc(c:Vector2,r:float,start_angle:float,end_angle:float,steps:=10) -> PackedVector2Array:var arr:PackedVector2Arrayvar v1 = Vector2.RIGHT * rvar ang = deg_to_rad(end_angle - start_angle)/float(steps)for i in range(steps+1):arr.append(v1.rotated(ang * float(i) + deg_to_rad(start_angle)) + c)return arr# 获取圆角矩形
func round_rect(rect:Rect2,r:float,offset:float) -> PackedVector2Array:var arr:PackedVector2Arrayvar pots:PackedVector2Array = get_rect2_points(rect) # 矩形顶点var vec = Vector2.ONE * (r + offset)  # 圆角偏移向量arr.append_array(arc(pots[0] + vec,r,180,270))arr.append_array(arc(pots[1] + Transform2D.FLIP_X * vec,r,270,360))arr.append_array(arc(pots[2] + vec * -1,r,0,90))arr.append_array(arc(pots[3] + Transform2D.FLIP_Y * vec,r,90,180))arr.append(pots[0] + vec - Vector2(r,0))return arr# 获取Rect对应的点集合
func get_rect2_points(rect:Rect2) -> PackedVector2Array:var arr:PackedVector2Arrayvar pos = rect.positionvar end = rect.endvar w = rect.size.xarr.append(pos)arr.append(pos + Vector2.RIGHT * w)arr.append(end)arr.append(end - Vector2.RIGHT * w)return arr

提示

  • 这只是个基础版本,后续改进,敬请期待

相关文章:

【Godot4.3】自定义圆角容器

概述 Godot控件想要完全实现现代UI风格,需要进行大量的自定义组件设计。本篇就依托于笔者自己对现代UI设计中的圆角面板元素模仿来制作圆角容器组件。 圆角容器 圆角元素在现代的扁平UI设计中非常常见,在Godot中可以通过改进PanelContainer来或者自定…...

Flutter系列教程之(5)——常用控件Widget的使用示例

目录 1.页面跳转 2.某个控件设置点击事件 3.AlertDialog对话框的使用 4.文本输入框 5.按钮 圆角扁平按钮: 圆角悬浮按钮: 6.补充 圆点 7.布局使用 Row控件左右对齐 调整边距 1.页面跳转 首先,先介绍一下页面跳转功能吧 Flutter使用 Navigator 进行页面…...

DeepSeek开源周,第三弹再次来袭,DeepGEMM

在大型模型推理中,矩阵乘法(GEMM)是计算的核心瓶颈。DeepGEMM 应运而生——一款专为 FP8精度矩阵乘法 设计的轻量级CUDA库,由深度求索(DeepSeek)团队开源。它凭借极简代码(核心仅300行&#xff…...

stm32四种方式精密控制步进电机

在搭建完clion的开发环境后,我决定重写之前的项目并优化完善,争取做出完全可落地的东西,也结合要写的论文内容一同学习下去。 因此,首当其冲的就是回到步进电机控制领域,把之前使用中断溢出进行步进电机控制的方案进行…...

C++11 智能指针:unique_ptr、shared_ptr和weak_ptr 功能特性 模拟实现

文章目录 unique_ptr功能和特性使用场景make_unique模拟实现 shared_ptr功能和特性使用场景make_shared模拟实现 weak_ptr C 中智能指针都是 RAII(Resource Acquisition Is Initialization)机制的典型应用,在构造时获取资源,在析构…...

Spring Boot启动过程?

目录 1. 启动入口 2. SpringApplication 初始化 3. 准备环境 4. 创建应用上下文(ApplicationContext) 5. 准备应用上下文 6. 刷新应用上下文 7. 启动 Web 服务器(若为 Web 应用) 8. 发布 ApplicationStartedEvent 事件 9. 执行 Runner 10. 发布 ApplicationReady…...

2025年软考报名费用是多少?全国费用汇总!

软考报名时间终于确定了!想要参加2025年软考的同学们注意啦!特别是那些一年只有一次考试机会的科目,千万不要错过哦!这里为大家整理了各地的报名时间、科目、费用等信息,快来看看吧! 一、2025年软考时间安…...

算法-二叉树篇06-二叉树的最大深度

二叉树的最大深度 力扣题目链接 题目描述 给定一个二叉树 root ,返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 解题思路 一样可以使用递归的思想,代码也十分简洁,计算出两个子树的深度取最大加…...

git merge -s ours ...的使用方法

当我们在自己的feature branch上开发时,并且已经commit,push了好几次 同时develop分支也commit , push了好几次, 如下图所示 这个时候就不能直接将feature branch上的改动 pull request到develop上面,因为develop基线已经不一样了…...

面试之《react hooks在源码中是怎么实现的?》

要深入理解 React Hooks 在源码中的实现,可以从以下几个关键方面来剖析: 核心数据结构 在 React 内部,使用链表来管理每个函数组件的 Hooks。每个 Hook 对应一个节点,这些节点通过 next 指针相连。以下是简化后的 Hook 节点结构…...

数字可调控开关电源设计(论文+源码)

1 设计要求 在本次数字可调控开关电源设计过程中,对关键参数设定如下: (1)输入电压:DC24-26V,输出电压:12-24(可调); (2)输出电压误差&#xf…...

【DeepSeek】【GPT-Academic】:DeepSeek集成到GPT-Academic(官方+第三方)

目录 1 官方deepseek 1.1 拉取学术GPT项目 1.2 安装依赖 1.3 修改配置文件中的DEEPSEEK_API_KEY 2 第三方API 2.1 修改DEEPSEEK_API_KEY 2.2 修改CUSTOM_API_KEY_PATTERM 2.3 地址重定向 2.4 修改模型参数 2.5 成功调用 2.6 尝试添加一个deepseek-r1参数 3 使用千帆…...

DeepSeek R1 + 飞书机器人实现AI智能助手

效果 TFChat项目地址 https://github.com/fish2018/TFChat 腾讯大模型知识引擎用的是DeepSeek R1,项目为sanic和redis实现,利用httpx异步处理流式响应,同时使用buffer来避免频繁调用飞书接口更新卡片的网络耗时。为了进一步减少网络IO消耗&…...

Android移动应用开发实践-1-下载安装和简单使用Android Studio 3.5.2版本(频频出错)

一、下载安装 1.Android Studio3.5.2下载地址:Android Studio3.5.2下载地址 其他版本下载地址:其他版本下载地址 2.安装教程(可以多找几个看看) 安装 | 手把手教你Android studio 3.5.2安装(安装教程)_a…...

Rk3568驱动开发_驱动编写和挂载_2

1.字符驱动介绍: 字符驱动:按照字节流镜像读写操作的设备,读写数据分先后顺序,例如:点灯、按键、IIC、SPI、等等都是字符设备,这些设备的驱动叫字符驱动设备 Linux应用层如何调用驱动: 字符设…...

验证码识别:使用OCR技术识别图形验证码详解

文章目录 一、基本原理二、所需工具2.1 Python环境2.2 图像处理库2.3 OCR引擎2.4 Python接口 三、实现步骤3.1 获取验证码图像3.2 图像预处理3.3 使用OCR进行字符识别3.4 基本 OCR 识别样例 四、提高识别准确率的方法4.1 字符分割4.2 使用深度学习模型4.3 数据增强4.4 集成多个…...

剑指 Offer II 033. 变位词组

comments: true edit_url: https://github.com/doocs/leetcode/edit/main/lcof2/%E5%89%91%E6%8C%87%20Offer%20II%20033.%20%E5%8F%98%E4%BD%8D%E8%AF%8D%E7%BB%84/README.md 剑指 Offer II 033. 变位词组 题目描述 给定一个字符串数组 strs ,将 变位词 组合在一起…...

【苍穹外卖】问题笔记

【DAY1 】 1.VCS找不到 好吧,发现没安git 接着发现安全模式有问题,点开代码信任此项目 2.导入初始文件,全员爆红 好像没maven,配一个 并在设置里设置好maven 3.启用注解,见新手苍穹 pom.xml改lombok版本为1.1…...

微信小程序 - 自定义实现分页功能

概述 在微信小程序项目中,没有现成的分页器组件,所以需要自定义实现分页功能 自定义实现分页功能 1、index.json {"usingComponents": {"van-button": "vant/weapp/button/index"} }这里使用 Vant Weapp 中的 van-butt…...

1.1部署es:9200

安装es:root用户: 1.布署java环境 - 所有节点 wget https://d6.injdk.cn/oraclejdk/8/jdk-8u341-linux-x64.rpm yum localinstall jdk-8u341-linux-x64.rpm -y java -version 2.下载安装elasticsearch - 所有节点 wget ftp://10.3.148.254/Note/Elk/…...

《模拟器过检测教程:Nox、雷电、Mumu、逍遥模拟器 Magisk、LSposed 框架安装与隐藏应用配置》

一、夜神模拟器 (Nox) 过检测 使用版本:7.0.6.2(20250209) 1. 准备工作 将需要用到的应用放入文件夹: C:\Users\Administrator.DESKTOP-I5V50SS\Nox_share\Download 2. 安装面具鸭(Magisk) 在模拟器下…...

人工智能、机器学习、深度学习和大语言模型之间的关系

人工智能(AI)、机器学习(ML)、深度学习(DL)和大语言模型(LLM)之间是逐层包含且技术递进的关系,具体如下: 1. 层级关系 人工智能(AI)…...

上传securecmd失败

上传securecmd失败 问题描述:KES V8R6部署工具中,节点管理里新建节点下一步提示上传securecmd失败,如下: 解决办法: [rootlocalhost ~]# yum install -y unzip 上传的过程中会解压,如果未安装unzip依赖包…...

C++:dfs,bfs各两则

1.木棒 167. 木棒 - AcWing题库 乔治拿来一组等长的木棒,将它们随机地砍断,使得每一节木棍的长度都不超过 5050 个长度单位。 然后他又想把这些木棍恢复到为裁截前的状态,但忘记了初始时有多少木棒以及木棒的初始长度。 请你设计一个程序…...

Python在实际工作中的运用-通用格式CSV文件自动转换XLSX

继续上篇《Python在实际工作中的运用-CSV无损转XLSX的几个方法》我们虽然对特定格式的CSV实现了快速转换XLSX的目标,但是在运行Py脚本前,还是需要编辑表格创建脚本和数据插入脚本,自动化程度很低,实用性不强,为减少人工提高效率,实现输入CSV文件路径即可自动适配完成转换…...

P9420 [蓝桥杯 2023 国 B] 子 2023

P9420 [蓝桥杯 2023 国 B] 子 2023 题目 分析代码 题目 分析 刚拿到这道题,我大脑简单算了一下,这个值太大了,直观感觉就很难!! 但是,你仔仔细细的一看,先从最简单的第一步入手,再…...

2025-02-26 学习记录--C/C++-C语言 判断字符串S2是否在字符串S1中

合抱之木&#xff0c;生于毫末&#xff1b;九层之台&#xff0c;起于累土&#xff1b;千里之行&#xff0c;始于足下。&#x1f4aa;&#x1f3fb; C语言 判断字符串S2是否在字符串S1中 #include <stdio.h> // 引入标准输入输出库&#xff0c;用于使用 printf 等函数 #…...

004 Kafka异常处理

6.异常处理 文章目录 6.异常处理1.异常分类与处理原则2.生产者异常处理1. 同步发送捕获异常2. 异步发送回调处理 3.消费者异常处理1.全局异常处理器2.方法级处理3.重试yml配置 4.死信队列&#xff08;DLQ&#xff09;配置1. 启用死信队列2. 手动发送到DLQ 5.事务场景异常处理1.…...

创建第一个 Maven 项目(二)

六、添加依赖 在 Maven 项目开发过程中&#xff0c;添加依赖是一项常见且关键的操作。通过添加依赖&#xff0c;我们可以引入项目所需的各种库和框架&#xff0c;极大地扩展项目的功能。接下来&#xff0c;我们将以 JUnit 依赖为例&#xff0c;详细介绍如何在 Maven 项目中添加…...

游戏引擎学习第124天

仓库:https://gitee.com/mrxiao_com/2d_game_3 回顾/复习 今天是继续完善和调试多线程的任务队列。之前的几天&#xff0c;我们已经介绍了多线程的一些基础知识&#xff0c;包括如何创建工作队列以及如何在线程中处理任务。今天&#xff0c;重点是解决那些我们之前没有注意到…...