You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

280 lines
9.7 KiB
JavaScript

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import { scene, axis, meshList, pointsList, axis2D, scene2D } from './index.js';
import { createAxisInfo } from './axisInfo/constant.js';
const lut = new THREE.Lut();
lut.addColorMap('axis', [[0.0, 0x00ee00], [0.25, 0xeeee00], [0.75, 0xee0000], [1.0, 0x4e0211]],);
lut.setColorMap('axis',1024)
let pointColors = [
{
material: new THREE.PointsMaterial({ color: 0xD94E5D, size: 2, sizeAttenuation: false }),
colors: 0xD94E5D,
num: 15,
},
{
material: new THREE.PointsMaterial({ color: 0xE28B4A, size: 2, sizeAttenuation: false }),
colors: 0xE28B4A,
num: 14,
},
{
material: new THREE.PointsMaterial({ color: 0xEAC736, size: 2, sizeAttenuation: false }),
colors: 0xEAC736,
num: 10,
},
{
material: new THREE.PointsMaterial({ color: 0x9DB578, size: 2, sizeAttenuation: false }),
colors: 0x9DB578,
num: 7,
},
{
material: new THREE.PointsMaterial({ color: 0x50A3BA, size: 2, sizeAttenuation: false }),
colors: 0x50A3BA,
num: 5,
},
];
const initPoints = new THREE.Points(
new THREE.BufferGeometry().setAttribute('position', new THREE.Float32BufferAttribute([0.5, 0, 0], 3)),
new THREE.PointsMaterial({ color: 0x0082df, size: 2, sizeAttenuation: false })
);
//柱子材质数据
let meterials = [
{
material: new THREE.MeshBasicMaterial({
color: '#4e0211',
}),
max: 0.75
},
{
material: new THREE.MeshBasicMaterial({
color: '#ee0000',
}),
max: 0.5
},
{
material: new THREE.MeshBasicMaterial({
color: '#eeee00',
}),
max: 0.25
},
{
material: new THREE.MeshBasicMaterial({
color: '#00ee00',
}),
max: 0,
},
];
const initGeometry = new THREE.BoxGeometry(0.6, 1, 2.5);
//绘制图表柱子
const drawChartsContent = (px, pz, py = 50, max, pxNum) => {
let y = py < 0 ? -py : py;
const material = new THREE.MeshBasicMaterial({color:lut.getColor(Number(y)/max)});//
//const material = meterials.find(item => (y / max) >= item.max).material;
//柱子宽高长
const geometry = initGeometry.clone();
geometry.scale(1, y, 1);
geometry.translate(49.4 - pxNum, Math.fround(py / 2), 360 - pz);
return { geometry, material }
}
//正弦曲线绘制
const drawSinLine = (obj) => {
let { line, color } = obj, list = [];
line.forEach(item => {
list.push(new THREE.Vector3(...item));
})
let geometry = new THREE.BufferGeometry(); //声明一个几何体对象Geometry
// 三维样条曲线 Catmull-Rom算法
let curve = new THREE.CatmullRomCurve3(list);
//getPoints是基类Curve的方法返回一个vector3对象作为元素组成的数组
let points = curve.getPoints(200); //分段数100返回101个顶点
// setFromPoints方法从points中提取数据改变几何体的顶点属性vertices
geometry.setFromPoints(points);
//材质对象
let material = new THREE.LineBasicMaterial({
color,
linewidth: 1,
});
//线条模型对象
let modelLine = new THREE.Line(geometry, material);
return modelLine
//scene.add(line); //线条对象添加到场景中
}
//绘制网格线条
const drawLine = (obj) => {
let { line, color, position, margin, num } = obj
let geometry = new THREE.BufferGeometry(); //创建一个Buffer类型几何体对象
//3个为一组表示一个顶点的xyz坐标
geometry.setAttribute('position', new THREE.Float32BufferAttribute(line, 3))
// 线条渲染模式
let material = new THREE.LineBasicMaterial({
color, //线条颜色
});//材质对象
let LineList = [];
let modelLine = new THREE.Line(geometry, material);//线条模型对象
LineList.push(modelLine)
for (let i = 1; i < num; i++) {
let lineChildren = modelLine.clone()['translate' + position](i * margin)
LineList.push(lineChildren);
}
return LineList
}
// 添加文字geometry
const add3DText = (text, callback) => {
let { content, url, size, set, rotation, xyz } = text;
let loader = new THREE.FontLoader();
//加载相应的字体下面字体名和样式组成gentilis_bold.typeface.json 完整文件名
let fontJsonUrl = url ? url : 'common/fonts/Century Gothic_Regular.json'; //你的字体json路径文件名规格随意
loader.load(fontJsonUrl, function (font) {
const color = 0xffffff;
const matLite = new THREE.MeshBasicMaterial({
color: color, // 字体大小
});
const geometry = new THREE.TextGeometry(content, {
font: font,
size: size ? size : 5,
height: 1,
});
geometry.translate(...xyz);
if (rotation) {
for (let i of rotation) {
geometry['rotate' + i[0]](Math.PI / i[1])
}
}
let mesh = new THREE.Mesh(geometry, matLite);
// mesh.scale.set(2, 2, 2)
if (set) {
mesh.scale.set(...set);
}
mesh.castShadow = true;
mesh.receiveShadow = true;
mesh.name = 'text';
callback(mesh)
});
}
// 添加精灵图文字
const draw2DText = (obj) => {
let scale = 1;//window.devicePixelRatio;
let { content, w, h, color, font, xyz, size, cw, ch, rotate } = obj;
cw = cw ? cw : 6;
ch = ch ? ch : 8;
let canvas = document.createElement('canvas')
canvas.style.width = w * scale;
canvas.style.height = h * scale;
if (rotate) {
canvas.width = w * cw * scale * 3;
canvas.height = h * ch * scale * 2;
} else {
canvas.width = w * cw * scale * 2;
canvas.height = h * ch * scale * 3;
}
let ctx = canvas.getContext('2d');
ctx.fillStyle = color;
ctx.strokeStyle = color;
ctx.font = font;
ctx.direction = "ltr"; // 文本方向从左向右
ctx.textAlign = "left"; // 左对齐
ctx.textBaseline = 'middle'//基线对齐选项,决定文字垂直方向的对齐方式
if (rotate) {
ctx.translate(canvas.width / 2, canvas.height);
ctx.rotate(-Math.PI / 2);
ctx.fillText(content, h, 0);
//ctx.strokeText(content, h, 0);
} else {
for (let i = 0; i < 1; i++) {
ctx.fillText(content[i], 0, canvas.height / 2);
ctx.strokeText(content[i], 0, canvas.height / 2);
}
}
let texture = new THREE.CanvasTexture(canvas)
// texture.needsUpdate = true//如果编码类型在纹理已被一个材质使用之后发生了改变, 你需要来设置Material.needsUpdate为true来使得材质重新编译
let geometry = new THREE.BufferGeometry(); //创建一个Buffer类型几何体对象
//3个为一组表示一个顶点的xyz坐标
geometry.setAttribute('position', new THREE.Float32BufferAttribute(xyz, 3));
const material = new THREE.PointsMaterial({
map: texture,
transparent: true,//材质透明
size: size ? size : 16.0, //点对象像素尺寸
});
const pointsText = new THREE.Points(geometry, material);
pointsText.name = 'pointsText';
return pointsText;
}
const drawAxis = (size, minNum, is2DInit) => {
scene.remove(...scene.children.filter(item => item.name === 'axisNumberText'))
if (axis.children.length) {
axis.remove(...axis.children)
}
let axisText = new THREE.Group();
axisText.name = 'axisNumberText';
scene.add(axisText)
const data = createAxisInfo(size, minNum);
axis.scale.set(...data[size]['set'])
meshList.scale.set(...data[size]['set'])
pointsList.scale.set(...data[size]['set'])
data[size]['prps'].forEach(async item => {
switch (item.type) {
case 'plan':
axis.add(drawPlan(item));
break;
case 'line':
axis.add(...drawLine(item));
break;
case 'curveLine':
axis.add(drawSinLine(item));
break;
case 'text':
axisText.add(draw2DText(item));
}
});
if (is2DInit) {
return;
}
drawAxis2D(size, minNum);
}
const drawAxis2D = (size, minNum) => {
if (axis2D.children.length) {
axis2D.remove(...axis2D.children)
}
let axisList = scene2D?.children.filter(item => item.name === 'axisNumberText');
axisList && scene2D.remove(...axisList)
let axisText = new THREE.Group();
const data = createAxisInfo(size, minNum);
axisText.name = 'axisNumberText';
scene2D.add(axisText)
axis2D.scale.set(...data[size]['set'])
let list = scene2D.getObjectByName('chartsPoint')
if (list) {
list.scale.set(...data[size]['set'])
}
data[size]['prpd'].forEach(async item => {
switch (item.type) {
case 'line':
axis2D.add(...drawLine(item));
break;
case 'curveLine':
axis2D.add(drawSinLine(item));
break;
case 'text':
axisText.add(draw2DText(item));
}
});
}
//绘制平面
const drawPlan = (obj) => {
const { size, color } = obj;
let geometry = new THREE.PlaneGeometry(size, 360); //创建一个Buffer类型几何体对象
geometry.rotateX(Math.PI / 2).translate(size/2, 0, 180);
// 三角面(网格)渲染模式
let material = new THREE.MeshBasicMaterial({
color, //三角面颜色
transparent: true,//透明
opacity: 0.2,
side: THREE.DoubleSide, //两面可见
}); //材质对象
let mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh
mesh.name = 'plan';
//scene.add(mesh);
return mesh
}
export { drawChartsContent, drawSinLine, drawLine, add3DText, draw2DText, drawAxis, drawAxis2D, initPoints, pointColors, drawPlan }