实际应用案例
本节介绍 tui-entine 在实际项目中的应用案例,展示其在不同场景下的使用方式。
t-color 组件
t-color 是一个颜色选择器组件,使用 tui-entine 实现了以下功能:
核心功能
- 颜色选择区域:使用 Canvas 绘制颜色选择面板,支持 HSL 颜色模型
- 透明度滑条:可调节颜色透明度的滑动条
- 拖拽手柄:用于在颜色面板上选择颜色
- 颜色块预览:实时显示当前选中的颜色
- 文本区域:显示颜色值(HEX、RGB、HSL 等格式)
技术实现
ts
// 颜色选择区域绘制
function drawColorPanel(engine: ITuiEngine, hue: number) {
const panel = engine.createView();
panel.style.width = 200;
panel.style.height = 200;
panel.style.backgroundColor = `hsl(${hue}, 100%, 50%)`;
// 绘制黑白渐变遮罩
const overlay = engine.createView();
overlay.style.width = 200;
overlay.style.height = 200;
overlay.style.backgroundImage =
"linear-gradient(to right, white, transparent), linear-gradient(to top, black, transparent)";
panel.appendChild(overlay);
return panel;
}
// 拖拽手柄
function createColorHandle(engine: ITuiEngine) {
const handle = engine.createView();
handle.style.width = 20;
handle.style.height = 20;
handle.style.borderWidth = 2;
handle.style.borderColor = "#ffffff";
handle.style.borderRadius = 10;
handle.style.position = "absolute";
// 添加拖拽事件
let isDragging = false;
handle.addEventListener("touchstart", () => (isDragging = true));
handle.addEventListener("touchmove", (event) => {
if (isDragging) {
// 更新手柄位置
handle.style.left = event.clientX - 10;
handle.style.top = event.clientY - 10;
engine.updateElement(handle, true);
// 计算新的颜色值
updateColorFromPosition(event.clientX, event.clientY);
}
});
handle.addEventListener("touchend", () => (isDragging = false));
return handle;
}性能优化
- 局部更新:只更新颜色选择手柄和颜色预览,不重绘整个面板
- 事件节流:对
touchmove事件进行节流,减少计算次数 - 缓存:缓存颜色面板的静态部分,只更新动态元素
t-joystick 组件
t-joystick 是一个虚拟摇杆组件,使用 tui-entine 实现了以下功能:
核心功能
- 摇杆底盘:绘制圆形摇杆底座
- 摇杆控制:可拖动的摇杆控制杆
- 箭头图片:指示摇杆方向
- 指南针图片:显示当前方向
- 小球图片:作为摇杆的控制点
技术实现
ts
// 摇杆底盘
function createJoystickBase(engine: ITuiEngine) {
const base = engine.createView();
base.style.width = 120;
base.style.height = 120;
base.style.backgroundColor = "rgba(0, 0, 0, 0.3)";
base.style.borderRadius = 60;
base.style.justifyContent = "center";
base.style.alignItems = "center";
return base;
}
// 摇杆控制杆
function createJoystickStick(engine: ITuiEngine) {
const stick = engine.createView();
stick.style.width = 60;
stick.style.height = 60;
stick.style.backgroundColor = "rgba(255, 255, 255, 0.8)";
stick.style.borderRadius = 30;
// 添加拖拽事件
let isDragging = false;
let startX = 0;
let startY = 0;
stick.addEventListener("touchstart", (event) => {
isDragging = true;
startX = event.clientX;
startY = event.clientY;
});
stick.addEventListener("touchmove", (event) => {
if (isDragging) {
const deltaX = event.clientX - startX;
const deltaY = event.clientY - startY;
// 限制在圆形范围内
const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
const maxDistance = 30; // 摇杆半径
if (distance > maxDistance) {
const angle = Math.atan2(deltaY, deltaX);
stick.style.transform = {
translateX: Math.cos(angle) * maxDistance,
translateY: Math.sin(angle) * maxDistance,
};
} else {
stick.style.transform = {
translateX: deltaX,
translateY: deltaY,
};
}
engine.updateElement(stick, true);
// 计算方向和强度
updateJoystickDirection(deltaX, deltaY);
}
});
stick.addEventListener("touchend", () => {
isDragging = false;
// 重置位置
stick.style.transform = {
translateX: 0,
translateY: 0,
};
engine.updateElement(stick, true);
});
return stick;
}性能优化
- 局部更新:只更新摇杆位置,不重绘整个组件
- 事件处理:使用触摸事件而非鼠标事件,提高响应速度
- 数学优化:使用三角函数计算摇杆位置,减少计算量
t-slider-menu 组件
t-slider-menu 是一个侧滑菜单组件,使用 tui-entine 实现了以下功能:
核心功能
- 自定义左侧菜单:可滑动的左侧菜单
- 自定义右侧内容区:主内容区域
- 滚动裁剪:按当前滚动位置裁剪可见项
- 惯性滚动:支持手势惯性滚动
- 边界回弹:到达边界时的回弹效果
技术实现
ts
// 菜单容器
function createMenuContainer(engine: ITuiEngine) {
const container = engine.createView();
container.style.width = 250;
container.style.height = engine.height;
container.style.backgroundColor = "#ffffff";
container.style.position = "absolute";
container.style.left = -250; // 默认隐藏
// 菜单项
const menuItems = [];
for (let i = 0; i < 20; i++) {
const item = engine.createView();
item.style.width = "100%";
item.style.height = 50;
item.style.paddingLeft = 20;
item.style.justifyContent = "center";
item.style.alignItems = "flex-start";
item.style.borderBottomWidth = 1;
item.style.borderBottomColor = "#f0f0f0";
const text = engine.createText();
text.value = `菜单项 ${i + 1}`;
text.style.fontSize = 16;
text.style.color = "#333333";
item.appendChild(text);
menuItems.push(item);
}
container.appendChild(...menuItems);
return container;
}
// 滑动处理
function handleMenuSwipe(engine: ITuiEngine, menu: any) {
let startX = 0;
let currentX = -250;
let isDragging = false;
menu.addEventListener("touchstart", (event: any) => {
isDragging = true;
startX = event.clientX;
});
menu.addEventListener("touchmove", (event: any) => {
if (isDragging) {
const deltaX = event.clientX - startX;
currentX = Math.max(-250, Math.min(0, currentX + deltaX));
menu.style.left = currentX;
engine.updateElement(menu, true);
startX = event.clientX;
}
});
menu.addEventListener("touchend", () => {
isDragging = false;
// 自动回弹
if (currentX > -125) {
// 打开菜单
animateTo(menu, 0);
} else {
// 关闭菜单
animateTo(menu, -250);
}
});
}
// 动画函数
function animateTo(element: any, targetValue: number) {
let currentValue = element.style.left;
const duration = 300;
const startTime = Date.now();
function animate() {
const elapsed = Date.now() - startTime;
const progress = Math.min(elapsed / duration, 1);
// 缓动函数
const easeProgress = 1 - Math.pow(1 - progress, 3);
element.style.left =
currentValue + (targetValue - currentValue) * easeProgress;
if (progress < 1) {
requestAnimationFrame(animate);
}
}
animate();
}性能优化
- 滚动裁剪:只绘制可见区域的菜单项,减少绘制量
- 惯性滚动:使用物理模型模拟惯性,提高用户体验
- 批量更新:使用
requestAnimationFrame批量更新,减少重绘次数
其他应用案例
1. 自定义仪表盘
功能:
- 圆形仪表盘绘制
- 指针动画效果
- 实时数据更新
技术点:
- Canvas 路径绘制
- 三角函数计算
- 动画缓动效果
2. 绘图板
功能:
- 自由绘制
- 颜色选择
- 笔触大小调整
技术点:
- 触摸事件跟踪
- 路径绘制
- 局部更新优化
3. 粒子效果
功能:
- 粒子系统
- 物理碰撞
- 动画效果
技术点:
- 批量绘制
- 物理引擎
- 性能优化
总结
tui-entine 在以下场景中表现优异:
- 高频重绘场景:如颜色选择器、仪表盘等
- 复杂交互场景:如摇杆、绘图板等
- 自定义渲染场景:如侧滑菜单、粒子效果等
- 性能敏感场景:需要精确控制渲染范围的场景
通过合理使用 tui-entine 的 API,可以创建出性能优异、交互流畅的复杂组件,为用户提供更好的体验。
提示:
- 对于简单的静态布局,直接使用原生组件可能更合适
- 对于需要精细控制渲染的场景,
tui-entine是理想选择 - 合理使用局部更新和缓存,可以显著提高性能
- 结合
t-canvas-engine使用,可以更方便地管理 Canvas 生命周期