TrailMesh.js
3.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import * as echarts from 'echarts/lib/echarts';
import graphicGL from '../../util/graphicGL';
import TrailGeometry from './TrailGeometry';
import { getItemVisualColor, getItemVisualOpacity } from '../../util/visual';
import trailGLSL from './shader/trail.glsl.js';
graphicGL.Shader.import(trailGLSL);
export default graphicGL.Mesh.extend(function () {
var material = new graphicGL.Material({
shader: new graphicGL.Shader({
vertex: graphicGL.Shader.source('ecgl.trail.vertex'),
fragment: graphicGL.Shader.source('ecgl.trail.fragment')
}),
transparent: true,
depthMask: false
});
// texture saving the keypoints.
var pointsTexture = new graphicGL.Texture2D({
type: graphicGL.Texture.FLOAT,
minFilter: graphicGL.Texture.NEAREST,
magFilter: graphicGL.Texture.NEAREST,
width: 1024
});
return {
geometry: new TrailGeometry({
dynamic: true
}),
material: material,
culling: false,
$ignorePicking: true,
_pointsTexture: pointsTexture
};
}, {
setData: function (data, api) {
var seriesModel = data.hostModel;
var geometry = this.geometry;
var effectModel = seriesModel.getModel('effect');
var size = effectModel.get('trailWidth') * api.getDevicePixelRatio();
var trailLength = effectModel.get('trailLength');
geometry.trailLength = trailLength;
this.material.set('trailLength', trailLength);
geometry.reset();
var vertexCount = 0;
var triangleCount = 0;
data.each(function (idx) {
var pts = data.getItemLayout(idx);
vertexCount += geometry.getCurveVertexCount(pts[0], pts[1], pts[2], pts[3]);
triangleCount += geometry.getCurveTriangleCount(pts[0], pts[1], pts[2], pts[3]);
});
geometry.setVertexCount(vertexCount);
geometry.setTriangleCount(triangleCount);
var colorArr = [];
var textureWidth = this._pointsTexture.width;
var textureHeight = Math.ceil(data.count() / (textureWidth / 4));
var pointsTexture = this._pointsTexture;
pointsTexture.height = textureHeight;
if (!(pointsTexture.pixels && pointsTexture.pixels.length === textureWidth * textureHeight * 4)) {
pointsTexture.pixels = new Float32Array(textureWidth * textureHeight * 4);
}
var pixels = pointsTexture.pixels;
var effectColor = effectModel.get('trailColor');
var effectOpacity = effectModel.get('trailOpacity');
var hasEffectColor = effectColor != null;
var hasEffectOpacity = effectOpacity != null;
data.each(function (idx) {
var pts = data.getItemLayout(idx);
var opacity = hasEffectOpacity ? effectOpacity : getItemVisualOpacity(data, idx);
var color = getItemVisualColor(data, idx);
if (opacity == null) {
opacity = 1;
}
colorArr = graphicGL.parseColor(hasEffectColor ? effectColor : color, colorArr);
colorArr[3] *= opacity;
var u = idx * 4 % textureWidth / (textureWidth - 1);
var v = Math.floor(idx * 4 / textureWidth) / (textureHeight - 1) || 0;
for (var k = 0; k < 4; k++) {
pixels[(idx * 4 + k) * 4] = pts[k][0];
pixels[(idx * 4 + k) * 4 + 1] = pts[k][1];
pixels[(idx * 4 + k) * 4 + 2] = pts[k][2];
}
geometry.addCurveTrail(
pts[0], pts[1], pts[2], pts[3], [u, v], size, colorArr
);
});
this.material.set('pointsTexture', pointsTexture);
pointsTexture.dirty();
geometry.dirty();
},
setScale: function (scale) {
this.geometry.scale = scale;
},
setAnimationPercent: function (percent) {
this.material.set('percent', percent);
}
});