|
|
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 = '#000';
|
|
|
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 { line, color } = obj;
|
|
|
let geometry = new THREE.PlaneGeometry(50, 360); //创建一个Buffer类型几何体对象
|
|
|
geometry.rotateX(Math.PI / 2).translate(25, 0, 180);
|
|
|
//3个为一组,表示一个顶点的xyz坐标
|
|
|
//geometry.setAttribute('position', new THREE.Float32BufferAttribute(line, 3))
|
|
|
// 三角面(网格)渲染模式
|
|
|
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 } |