如何在QML中绘制带阴影框的Path曲线并实现鼠标选中?
实现自定义线条绘制与鼠标选中功能
一、绘制目标线条
以Three.js为例,实现示例图中的线条效果:
定义线条顶点数据
根据需求设置线条的起点、终点(可根据示例图调整顶点坐标):// 创建顶点数组 const points = [ new THREE.Vector3(-2, 0, 0), new THREE.Vector3(2, 0, 0) ]; // 生成几何体 const lineGeometry = new THREE.BufferGeometry().setFromPoints(points);配置线条材质
匹配示例图的视觉样式,设置颜色、线宽等属性:const lineMaterial = new THREE.LineBasicMaterial({ color: 0x0000ff, linewidth: 2 // 注:部分渲染器对linewidth支持有限,需宽线条可改用Line2扩展 });创建线条并加入场景
const line = new THREE.Line(lineGeometry, lineMaterial); // 给线条加唯一标识,方便后续选中判断 line.userData.id = 'target-line'; scene.add(line);
二、通过TapHandler实现鼠标选中功能
结合射线检测与TapHandler完成线条选中逻辑:
初始化工具对象
const tapHandler = new THREE.TapHandler(renderer.domElement); const raycaster = new THREE.Raycaster(); const mouse = new THREE.Vector2();绑定点击事件处理选中逻辑
tapHandler.addEventListener('tap', (event) => { // 转换鼠标坐标为Three.js标准坐标 mouse.x = (event.clientX / window.innerWidth) * 2 - 1; mouse.y = -(event.clientY / window.innerHeight) * 2 + 1; // 更新射线检测范围 raycaster.setFromCamera(mouse, camera); // 只检测场景中的线条对象 const lineObjects = scene.children.filter(child => child.type === 'Line'); const intersects = raycaster.intersectObjects(lineObjects); if (intersects.length > 0) { const selectedLine = intersects[0].object; // 标记选中状态,比如切换颜色 selectedLine.material.color.set(0xff0000); console.log('选中线条:', selectedLine.userData.id); } });可选:添加取消选中逻辑
点击空白区域时重置所有线条状态:tapHandler.addEventListener('tap', (event) => { // 坐标转换与射线检测... const intersects = raycaster.intersectObjects(lineObjects); if (intersects.length > 0) { // 先重置所有线条颜色 lineObjects.forEach(line => line.material.color.set(0x0000ff)); // 标记当前选中线条 intersects[0].object.material.color.set(0xff0000); } else { // 点击空白,重置所有线条状态 lineObjects.forEach(line => line.material.color.set(0x0000ff)); } });
补充说明
- 若示例图是带箭头的连接线,可在线条末端添加箭头几何体,结合
Line与Mesh实现 - 若需要更稳定的宽线条效果,可引入Three.js的
Line2扩展组件 - 确保相机、渲染器的基础配置正确,否则射线检测无法正常工作
内容的提问来源于stack exchange,提问作者Mohsen Kondori
相关产品推荐
相关产品推荐

