fl-web-component 1.3.14 → 1.3.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- @charset "UTF-8";#fl-model[data-v-0390b048]{width:100%;height:100%;cursor:pointer}[data-v-0390b048] .tips-label{width:60px;color:#000;font:12px Helvetica;margin-top:-3em;padding:5px;text-align:center;vertical-align:middle;background-color:khaki}[data-v-0390b048] .measure-label{max-width:100px;margin-top:-1em;border:10px;border-radius:5px;padding:3px 10px;cursor:pointer;color:#009bea;background-color:#f4f4f4;box-shadow:0 1px 3px 1px rgba(0,0,0,.25)}[data-v-0390b048] .circle-tag{width:10px;height:10px;margin-top:5px;border-radius:50%;background-color:#ff5000}[data-v-0390b048] .measure-label-font{word-break:break-all}[data-v-0390b048] .mark-label-img{padding-top:5px;width:20px;height:20px}.lil-gui{background:hsla(0,0%,100%,.95)!important;border:1px solid #e0e0e0!important;border-radius:8px!important;box-shadow:0 4px 12px rgba(0,0,0,.15)!important;backdrop-filter:blur(10px)!important;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif!important}.lil-gui .title{background:linear-gradient(135deg,#f8f9fa,#e9ecef)!important;color:#495057!important;border-bottom:1px solid #dee2e6!important;font-weight:600!important;padding:0 12px!important;border-radius:8px 8px 0 0!important}.lil-gui .controller{border-bottom:1px solid #f1f3f4!important;background:transparent!important}.lil-gui .controller:last-child{border-bottom:none!important}.lil-gui .controller .name{color:#495057!important;font-weight:500!important;font-size:12px!important}.lil-gui .controller .widget{background:#f8f9fa!important;border:1px solid #ced4da!important;border-radius:4px!important;color:#495057!important}.lil-gui .controller .widget:focus,.lil-gui .controller .widget:hover{border-color:#80bdff!important;box-shadow:0 0 0 2px rgba(0,123,255,.25)!important}.lil-gui .controller .widget:focus{outline:none!important}.lil-gui .controller input[type=range]{background:#e9ecef!important;height:4px!important;-webkit-appearance:none!important;-moz-appearance:none!important;appearance:none!important;border-radius:2px!important}.lil-gui .controller.number .fill{border-right:solid #008de9}.lil-gui .controller input[type=range]::-webkit-slider-thumb{background:#007bff!important;border:2px solid #fff!important;box-shadow:0 2px 4px rgba(0,0,0,.2)!important;width:16px!important;height:16px!important;border-radius:50%!important;-webkit-appearance:none!important;appearance:none!important;cursor:pointer!important}.lil-gui .controller input[type=range]::-moz-range-thumb{background:#007bff!important;border:2px solid #fff!important;box-shadow:0 2px 4px rgba(0,0,0,.2)!important;width:16px!important;height:16px!important;border-radius:50%!important;cursor:pointer!important}.lil-gui .controller .option{background:#fff!important;color:#495057!important;border-bottom:1px solid #f1f3f4!important}.lil-gui .controller .option:hover{background:#f8f9fa!important}.lil-gui .controller .option:last-child{border-bottom:none!important}.lil-gui input:active{background:#e6eff4}.lil-gui .controller button{background:linear-gradient(135deg,#007bff,#0056b3)!important;color:#fff!important;border:none!important;border-radius:4px!important;font-weight:500!important;transition:all .2s ease!important}.lil-gui .controller button:hover{background:linear-gradient(135deg,#0056b3,#004085)!important;transform:translateY(-1px)!important;box-shadow:0 4px 8px rgba(0,123,255,.3)!important}.lil-gui .controller .color{border:2px solid #fff!important;border-radius:4px!important;box-shadow:0 2px 4px rgba(0,0,0,.1)!important}.lil-gui .controller.number .slider,.lil-gui .controller.number .slider:hover{background-color:#e6eff4}.lil-gui input,.lil-gui input:hover,.lil-gui input[type=number]:focus,.lil-gui input[type=text]:focus{background:#e6eff4}.lil-gui .controller>.name{min-width:25px}.lil-gui .controller.number input{color:#2e3136}.lil-gui .controller.number .slider:active{background-color:#e6eff4}.lil-gui .folder>.title{background:linear-gradient(135deg,#f1f3f4,#e9ecef)!important;color:#495057!important;border-bottom:1px solid #dee2e6!important}.lil-gui .folder>.title:before{color:#6c757d!important}.lil-gui .folder.closed>.children{display:none!important}#konva-container[data-v-1b43deb6]{z-index:3;width:100%;height:100%;cursor:pointer;overflow:hidden}span[data-v-f547d5c6]{font-weight:bolder}.text[data-v-f547d5c6]{margin-top:20px}.line[data-v-f547d5c6]{border-bottom:1px solid #dcdfe6;margin:20px 0}.center[data-v-f547d5c6]{display:flex;flex-direction:column;align-items:center}.center .cen span[data-v-f547d5c6],.center .top span[data-v-f547d5c6]{color:"#53a8ff";display:inline-block;width:30px;height:30px;text-align:center;line-height:30px;border:1px solid;padding:5px;margin-bottom:10px;background-color:#e9f3ff}.center .cen span[data-v-f547d5c6]{margin:10px}.button[data-v-f547d5c6]{display:flex;justify-content:end;margin-top:20px}@font-face{font-family:iconfont;src:url(//at.alicdn.com/t/font_3226805_qqvo3ag3r8.woff2?t=1646635700216) format("woff2"),url(//at.alicdn.com/t/font_3226805_qqvo3ag3r8.woff?t=1646635700216) format("woff"),url(//at.alicdn.com/t/font_3226805_qqvo3ag3r8.ttf?t=1646635700216) format("truetype")}.iconfont[data-v-f547d5c6]{font-family:iconfont!important;font-size:50px;font-style:normal;color:"#53a8ff";-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.icon-shubiao[data-v-f547d5c6]:before{content:""}#svg-tigger[data-v-0ec35ee4]{cursor:pointer;height:100%;width:100%}
1
+ @charset "UTF-8";#fl-model[data-v-c496e868]{width:100%;height:100%;cursor:pointer}[data-v-c496e868] .tips-label{width:60px;color:#000;font:12px Helvetica;margin-top:-3em;padding:5px;text-align:center;vertical-align:middle;background-color:khaki}[data-v-c496e868] .measure-label{max-width:100px;margin-top:-1em;border:10px;border-radius:5px;padding:3px 10px;cursor:pointer;color:#009bea;background-color:#f4f4f4;box-shadow:0 1px 3px 1px rgba(0,0,0,.25)}[data-v-c496e868] .circle-tag{width:10px;height:10px;margin-top:5px;border-radius:50%;background-color:#ff5000}[data-v-c496e868] .measure-label-font{word-break:break-all}[data-v-c496e868] .mark-label-img{padding-top:5px;width:20px;height:20px}.lil-gui{background:hsla(0,0%,100%,.95)!important;border:1px solid #e0e0e0!important;border-radius:8px!important;box-shadow:0 4px 12px rgba(0,0,0,.15)!important;backdrop-filter:blur(10px)!important;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif!important}.lil-gui .title{background:linear-gradient(135deg,#f8f9fa,#e9ecef)!important;color:#495057!important;border-bottom:1px solid #dee2e6!important;font-weight:600!important;padding:0 12px!important;border-radius:8px 8px 0 0!important}.lil-gui .controller{border-bottom:1px solid #f1f3f4!important;background:transparent!important}.lil-gui .controller:last-child{border-bottom:none!important}.lil-gui .controller .name{color:#495057!important;font-weight:500!important;font-size:12px!important}.lil-gui .controller .widget{background:#f8f9fa!important;border:1px solid #ced4da!important;border-radius:4px!important;color:#495057!important}.lil-gui .controller .widget:focus,.lil-gui .controller .widget:hover{border-color:#80bdff!important;box-shadow:0 0 0 2px rgba(0,123,255,.25)!important}.lil-gui .controller .widget:focus{outline:none!important}.lil-gui .controller input[type=range]{background:#e9ecef!important;height:4px!important;-webkit-appearance:none!important;-moz-appearance:none!important;appearance:none!important;border-radius:2px!important}.lil-gui .controller.number .fill{border-right:solid #008de9}.lil-gui .controller input[type=range]::-webkit-slider-thumb{background:#007bff!important;border:2px solid #fff!important;box-shadow:0 2px 4px rgba(0,0,0,.2)!important;width:16px!important;height:16px!important;border-radius:50%!important;-webkit-appearance:none!important;appearance:none!important;cursor:pointer!important}.lil-gui .controller input[type=range]::-moz-range-thumb{background:#007bff!important;border:2px solid #fff!important;box-shadow:0 2px 4px rgba(0,0,0,.2)!important;width:16px!important;height:16px!important;border-radius:50%!important;cursor:pointer!important}.lil-gui .controller .option{background:#fff!important;color:#495057!important;border-bottom:1px solid #f1f3f4!important}.lil-gui .controller .option:hover{background:#f8f9fa!important}.lil-gui .controller .option:last-child{border-bottom:none!important}.lil-gui input:active{background:#e6eff4}.lil-gui .controller button{background:linear-gradient(135deg,#007bff,#0056b3)!important;color:#fff!important;border:none!important;border-radius:4px!important;font-weight:500!important;transition:all .2s ease!important}.lil-gui .controller button:hover{background:linear-gradient(135deg,#0056b3,#004085)!important;transform:translateY(-1px)!important;box-shadow:0 4px 8px rgba(0,123,255,.3)!important}.lil-gui .controller .color{border:2px solid #fff!important;border-radius:4px!important;box-shadow:0 2px 4px rgba(0,0,0,.1)!important}.lil-gui .controller.number .slider,.lil-gui .controller.number .slider:hover{background-color:#e6eff4}.lil-gui input,.lil-gui input:hover,.lil-gui input[type=number]:focus,.lil-gui input[type=text]:focus{background:#e6eff4}.lil-gui .controller>.name{min-width:25px}.lil-gui .controller.number input{color:#2e3136}.lil-gui .controller.number .slider:active{background-color:#e6eff4}.lil-gui .folder>.title{background:linear-gradient(135deg,#f1f3f4,#e9ecef)!important;color:#495057!important;border-bottom:1px solid #dee2e6!important}.lil-gui .folder>.title:before{color:#6c757d!important}.lil-gui .folder.closed>.children{display:none!important}#konva-container[data-v-1b43deb6]{z-index:3;width:100%;height:100%;cursor:pointer;overflow:hidden}span[data-v-f547d5c6]{font-weight:bolder}.text[data-v-f547d5c6]{margin-top:20px}.line[data-v-f547d5c6]{border-bottom:1px solid #dcdfe6;margin:20px 0}.center[data-v-f547d5c6]{display:flex;flex-direction:column;align-items:center}.center .cen span[data-v-f547d5c6],.center .top span[data-v-f547d5c6]{color:"#53a8ff";display:inline-block;width:30px;height:30px;text-align:center;line-height:30px;border:1px solid;padding:5px;margin-bottom:10px;background-color:#e9f3ff}.center .cen span[data-v-f547d5c6]{margin:10px}.button[data-v-f547d5c6]{display:flex;justify-content:end;margin-top:20px}@font-face{font-family:iconfont;src:url(//at.alicdn.com/t/font_3226805_qqvo3ag3r8.woff2?t=1646635700216) format("woff2"),url(//at.alicdn.com/t/font_3226805_qqvo3ag3r8.woff?t=1646635700216) format("woff"),url(//at.alicdn.com/t/font_3226805_qqvo3ag3r8.ttf?t=1646635700216) format("truetype")}.iconfont[data-v-f547d5c6]{font-family:iconfont!important;font-size:50px;font-style:normal;color:"#53a8ff";-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.icon-shubiao[data-v-f547d5c6]:before{content:""}#svg-tigger[data-v-0ec35ee4]{cursor:pointer;height:100%;width:100%}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fl-web-component",
3
- "version": "1.3.14",
3
+ "version": "1.3.16",
4
4
  "scripts": {
5
5
  "tip1": "仅调试本组件不涉及业务组件,请执行dev",
6
6
  "dev": "vue-cli-service serve",
@@ -220,7 +220,7 @@
220
220
  color: '' 初始化模型的颜色 在业务方 有这个需求
221
221
  meshNameConfig: {}
222
222
  */
223
- drawModel(data, color = '', meshNameConfig = {}) {
223
+ drawModel(data, color = '', meshNameConfig = {}, options = {}) {
224
224
  if (Object.keys(data).length === 0) {
225
225
  return;
226
226
  }
@@ -282,6 +282,9 @@
282
282
  this.$emit('modelLoaded');
283
283
  // cameraControls.saveState();
284
284
  }
285
+
286
+ // 动态设置视角滚轮的距离
287
+ this.setCameraConfig();
285
288
  },
286
289
  // 获取mesh的中心点
287
290
  getMeshCenterAndVolume(mesh) {
@@ -1563,6 +1566,19 @@
1563
1566
  left && (cameraControls.mouseButtons.left = ACTION_ENUM[left]);
1564
1567
  right && (cameraControls.mouseButtons.right = ACTION_ENUM[right]);
1565
1568
  },
1569
+ // 动态设置视角滚轮的距离
1570
+ setCameraConfig() {
1571
+ let box3 = new this.THREE.Box3().setFromObject(scene);
1572
+ let size = new this.THREE.Vector3();
1573
+ box3.getSize(size);
1574
+ const maxBorder = Math.max(size.x, size.y, size.z);
1575
+
1576
+ cameraControls.camera.far = maxBorder * 50; // 设置相机的远裁剪面
1577
+
1578
+ cameraControls.minDistance = maxBorder * 0.05; // 动态设置视角滚轮的距离
1579
+
1580
+ camera.updateProjectionMatrix();
1581
+ },
1566
1582
  },
1567
1583
  };
1568
1584
  </script>
@@ -69,7 +69,8 @@ function parseData(input) {
69
69
  italic: material?.italic,
70
70
  linepacing: 1, // 默认值
71
71
  linewidth: material?.linewidth !== undefined ? material?.linewidth : 1, // 默认值
72
- visible: material?.visible === false ? false : true
72
+ visible: material?.visible === false ? false : true,
73
+ transparent: material?.transp,
73
74
  };
74
75
 
75
76
  const identity = new THREE.Matrix4().identity();
@@ -161,7 +162,8 @@ function parseNode(node) {
161
162
  }
162
163
  });
163
164
  if (isRoot) {
164
- const processed = processInstance(instance, instance._batchId, instanceMap);
165
+ // 根节点父ID应为空字符串
166
+ const processed = processInstance(instance, '', instanceMap);
165
167
  rootInstances.push(processed);
166
168
  }
167
169
  });
@@ -65,14 +65,16 @@ function handleInstancedMeshModel(
65
65
  let targetGroup, instancedMeshIndex, drawObjectName;
66
66
  const drawObjInstance = drawObjMapInstance[instances[i].drawObject];
67
67
  if (drawObjInstance.MapMesh?.length > 0) {
68
+ // 确保始终使用当前实例的 drawObject 设置分组名
69
+ drawObjectName = instances[i].drawObject;
68
70
  drawObjInstance.MapInstance.forEach((instance, index) => {
69
71
  if (instance.instanceId == instances[i].instanceId) {
70
72
  instancedMeshIndex = index;
71
- drawObjectName = instances[i].drawObject;
72
73
  }
73
74
  });
75
+ // 在 modelGroup 中查找,避免因尚未加入 scene 而重复创建
74
76
  if (drawObjectName) {
75
- targetGroup = scene.getObjectByName(drawObjectName);
77
+ targetGroup = modelGroup.getObjectByName(drawObjectName);
76
78
  }
77
79
  if (!targetGroup) {
78
80
  const drawObj = drawObjMapInstance[instances[i].drawObject];
@@ -104,46 +106,48 @@ function handleInstancedMeshModel(
104
106
  model.userData[key] = meshNameConfig[key];
105
107
  meshName += ':' + meshNameConfig[key];
106
108
  }
109
+ // 一次性为该 drawObject 的所有实例设置矩阵与颜色
107
110
  drawObj.MapInstance.forEach((item, index) => {
108
- if (item.instanceId == instances[i].instanceId) {
109
- model.userData.instanceIndex = index;
110
- model.userData.instanceId = instances[i].instanceId;
111
- model.userData.primId = mesh.prmid;
112
- model.name =
113
- meshName !== '' ? instances[i].instanceId + meshName : instances[i].instanceId;
114
- const matrixVal = item.matrix?.val;
115
- if (matrixVal) {
116
- const m4 = new THREE.Matrix4();
117
- const meshMatrix = new THREE.Matrix4();
118
- const geomMatrix = new THREE.Matrix4();
119
- // m4.setPosition(new THREE.Vector3(9999999, 9999999, 9999999)); // TODO 临时隐藏方案
120
- meshMatrix.elements = item.matrix.val;
121
- geomMatrix.elements = mesh.matrix.val;
122
-
123
- // 处理文本居中对齐
124
- const { points, alignType } = mesh;
125
- if (isTextType(mesh.type)) {
126
- const positionMatrix = new THREE.Matrix4();
127
-
128
- const alignMatrix = createAlignedText(alignType, model.geometry);
129
-
130
- positionMatrix.identity().makeTranslation(points[0], points[1], points[2]);
131
- geomMatrix.multiply(alignMatrix).multiply(positionMatrix);
132
- }
133
- m4.multiplyMatrices(meshMatrix, geomMatrix);
134
-
135
- model.setMatrixAt(index, m4);
136
- const copyMatrix = new THREE.Matrix4().copy(m4);
137
- model.userData.copyMatrix = copyMatrix;
111
+ model.userData.instanceIndex = index;
112
+ model.userData.instanceId = item.instanceId;
113
+ model.userData.primId = mesh.prmid;
114
+ model.name = meshName !== '' ? item.instanceId + meshName : item.instanceId;
115
+
116
+ const matrixVal = item.matrix?.val;
117
+ if (matrixVal) {
118
+ const m4 = new THREE.Matrix4();
119
+ const meshMatrix = new THREE.Matrix4();
120
+ const geomMatrix = new THREE.Matrix4();
121
+ // m4.setPosition(new THREE.Vector3(9999999, 9999999, 9999999)); // TODO 临时隐藏方案
122
+ meshMatrix.elements = item.matrix.val;
123
+ geomMatrix.elements = mesh.matrix.val;
124
+
125
+ // 处理文本居中对齐
126
+ const { points, alignType } = mesh;
127
+ if (isTextType(mesh.type)) {
128
+ const positionMatrix = new THREE.Matrix4();
129
+
130
+ const alignMatrix = createAlignedText(alignType, model.geometry);
131
+
132
+ positionMatrix.identity().makeTranslation(points[0], points[1], points[2]);
133
+ geomMatrix.multiply(alignMatrix).multiply(positionMatrix);
138
134
  }
139
- // 需要先设置全部实例颜色,否则后续设置颜色无效
140
- const { color } = mesh.prop;
141
- const meshColor = customColor
142
- ? new THREE.Color(customColor)
143
- : new THREE.Color(`rgb(${color[0]}, ${color[1]}, ${color[2]})`);
144
- model.setColorAt(index, meshColor);
135
+ m4.multiplyMatrices(meshMatrix, geomMatrix);
136
+
137
+ model.setMatrixAt(index, m4);
138
+ const copyMatrix = new THREE.Matrix4().copy(m4);
139
+ model.userData.copyMatrix = copyMatrix;
145
140
  }
141
+ // 需要先设置全部实例颜色,否则后续设置颜色无效
142
+ const { color } = mesh.prop;
143
+ const meshColor = customColor
144
+ ? new THREE.Color(customColor)
145
+ : new THREE.Color(`rgb(${color[0]}, ${color[1]}, ${color[2]})`);
146
+ model.setColorAt(index, meshColor);
146
147
  });
148
+ // 标记实例属性更新
149
+ if (model.instanceMatrix) model.instanceMatrix.needsUpdate = true;
150
+ if (model.instanceColor) model.instanceColor.needsUpdate = true;
147
151
  // model.instanceColor.needsUpdate = true;
148
152
  group.add(model);
149
153
  });
@@ -343,7 +347,7 @@ function draw3Dmodel(geom, instanceName, instanceCount, nColor, nOpacity) {
343
347
  const normal = new Float32Array(normals);
344
348
  geometry.setAttribute('normal', new THREE.BufferAttribute(normal, 3));
345
349
  }
346
- const { color } = prop;
350
+ const { color, transparent } = prop;
347
351
  let material, mesh, colors, opacity;
348
352
  if (Array.isArray(color) && color.length) {
349
353
  colors = color;
@@ -356,6 +360,11 @@ function draw3Dmodel(geom, instanceName, instanceCount, nColor, nOpacity) {
356
360
  opacity = 1;
357
361
  }
358
362
 
363
+ // 处理transparent透明度
364
+ if (transparent) {
365
+ opacity = 1 - transparent;
366
+ }
367
+
359
368
  // 使用自定义材质或创建标准材质(默认参数配置)
360
369
  let materialOptions = {
361
370
  userData: {
@@ -392,34 +401,34 @@ function draw3Dmodel(geom, instanceName, instanceCount, nColor, nOpacity) {
392
401
  geometry.setAttribute('opacity', new THREE.InstancedBufferAttribute(opacities, 1));
393
402
 
394
403
  // 自定义着色器逻辑
395
- // if (!customMaterial) {
396
- // material.onBeforeCompile = shader => {
397
- // // 添加顶点着色器输入
398
- // shader.vertexShader = `
399
- // in float opacity; // 实例透明度属性
400
- // out float vAlpha;
401
- // ${shader.vertexShader}
402
- // `.replace(
403
- // '#include <begin_vertex>',
404
- // `
405
- // #include <begin_vertex>
406
- // vAlpha = opacity; // 传递透明度到片段着色器
407
- // `
408
- // );
409
-
410
- // // 修改片段着色器
411
- // shader.fragmentShader = `
412
- // in float vAlpha;
413
- // ${shader.fragmentShader}
414
- // `.replace(
415
- // '#include <alphatest_fragment>',
416
- // `
417
- // #include <alphatest_fragment>
418
- // diffuseColor.a *= vAlpha; // 应用实例透明度
419
- // `
420
- // );
421
- // };
422
- // }
404
+ if (!customMaterial) {
405
+ material.onBeforeCompile = shader => {
406
+ // 添加顶点着色器输入
407
+ shader.vertexShader = `
408
+ in float opacity; // 实例透明度属性
409
+ out float vAlpha;
410
+ ${shader.vertexShader}
411
+ `.replace(
412
+ '#include <begin_vertex>',
413
+ `
414
+ #include <begin_vertex>
415
+ vAlpha = opacity; // 传递透明度到片段着色器
416
+ `
417
+ );
418
+
419
+ // 修改片段着色器
420
+ shader.fragmentShader = `
421
+ in float vAlpha;
422
+ ${shader.fragmentShader}
423
+ `.replace(
424
+ '#include <alphatest_fragment>',
425
+ `
426
+ #include <alphatest_fragment>
427
+ diffuseColor.a *= vAlpha; // 应用实例透明度
428
+ `
429
+ );
430
+ };
431
+ }
423
432
  mesh = new THREE.InstancedMesh(geometry, material, instanceCount);
424
433
 
425
434
  const { visible } = prop;