c2
Version:
d3 component canvas
282 lines (252 loc) • 9.08 kB
JavaScript
function reset (context) {
context.clearColor(0,0,0,1.0);
context.clearDepth(1.0);
context.clear(context.COLOR_BUFFER_BIT | context.DEPTH_BUFFER_BIT);
}
var pMatrixUniform;
const canvas = document.querySelector('canvas'),
context = d3.select(canvas)
.style('width',(window.innerWidth-100)+'px')
.style('height',(window.innerHeight-100)+'px')
.attr('width',window.innerWidth-100)
.attr('height',window.innerHeight-100)
.select(c2.ContextWebGL)
.on('tick',function () {
gl.uniformMatrix4fv(pMatrixUniform,false,pMatrix);
reset(this.context)
}),
//this is the part that needs to be organized better
gl = context.node().context,
vertex_shader = gl.createShader(gl.VERTEX_SHADER),
fragment_shader = gl.createShader(gl.FRAGMENT_SHADER),
program = gl.createProgram();
//mvMatrix = mat4.create(),
//gl.viewport(0,0,window.innerWidth,window.innerHeight);
var pMatrix = mat4.perspective(mat4.create(),45,window.innerWidth/window.innerHeight,0.1,10);
mat4.translate(pMatrix,pMatrix,[0,0,-10])
mat4.rotate(pMatrix,pMatrix,0.9,[1,0,0])
//mat4.rotate(pMatrix,pMatrix,Math.PI*2.1+.25,[1,0,0])
//console.error(pMatrix);
var mvMatrix = mat4.scale(mat4.create(),mat4.create(),[1,1,0.01]);
//mat4.rotate(mvMatrix,mvMatrix,-1,[1,1,1]);
!function init () {
var model = new Float32Array([
// Front face
-1.0, -1.0, 1.0,
1.0, -1.0, 1.0,
1.0, 1.0, 1.0,
-1.0, 1.0, 1.0,
// Back face
-1.0, -1.0, -1.0,
-1.0, 1.0, -1.0,
1.0, 1.0, -1.0,
1.0, -1.0, -1.0,
// Top face
-1.0, 1.0, -1.0,
-1.0, 1.0, 1.0,
1.0, 1.0, 1.0,
1.0, 1.0, -1.0,
// Bottom face
-1.0, -1.0, -1.0,
1.0, -1.0, -1.0,
1.0, -1.0, 1.0,
-1.0, -1.0, 1.0,
// Right face
1.0, -1.0, -1.0,
1.0, 1.0, -1.0,
1.0, 1.0, 1.0,
1.0, -1.0, 1.0,
// Left face
-1.0, -1.0, -1.0,
-1.0, -1.0, 1.0,
-1.0, 1.0, 1.0,
-1.0, 1.0, -1.0
]),
colors = new Float32Array([
1.0, 1.0, 1.0, 1.0, // Front face: white
1.0, 0.0, 0.0, 1.0, // Back face: red
0.0, 1.0, 0.0, 1.0, // Top face: green
0.0, 0.0, 1.0, 1.0, // Bottom face: blue
1.0, 1.0, 0.0, 1.0, // Right face: yellow
1.0, 0.0, 1.0, 1.0 // Left face: purple
]),
indices = new Uint16Array( [
0, 1, 2, 0, 2, 3, // front
4, 5, 6, 4, 6, 7, // back
8, 9, 10, 8, 10, 11, // top
12, 13, 14, 12, 14, 15, // bottom
16, 17, 18, 16, 18, 19, // right
20, 21, 22, 20, 22, 23 // left
]),
itemSize = 3,
numItems = model.length / itemSize,
mvMatrixUniform,
Triangle,
selection,
xScale,yScale,
vbuffer = gl.createBuffer(),
cbuffer = gl.createBuffer(),
ibuffer = gl.createBuffer();
gl.shaderSource(vertex_shader,`
attribute vec3 aVertexPosition;
//attribute float aValue;
//uniform float value;
//uniform float x;
uniform mat4 uPMatrix;
//uniform mat4 uMVMatrix;
varying float t;
void main () {
gl_Position = uPMatrix*vec4(aVertexPosition,1.0);
t = aVertexPosition.y*aVertexPosition.z;
}
`);
gl.shaderSource(fragment_shader,`
#ifdef GL_ES
precision highp float;
#endif
varying float t;
void main () {
gl_FragColor = vec4(0,0,1.0-t,0.3);
}
`);
gl.compileShader(vertex_shader);
gl.compileShader(fragment_shader);
gl.attachShader(program,vertex_shader);
gl.attachShader(program,fragment_shader);
gl.linkProgram(program);
if (!gl.getProgramParameter(program,gl.LINK_STATUS)) {
throw "shader program error"
}
//gl.bindBuffer(gl.ARRAY_BUFFER,cbuffer);
//gl.bufferData(gl.ARRAY_BUFFER,colors,gl.STATIC_DRAW);
gl.bindBuffer(gl.ARRAY_BUFFER,vbuffer);
gl.bufferData(gl.ARRAY_BUFFER,model,gl.STATIC_DRAW);
gl.useProgram(program);
pMatrixUniform = gl.getUniformLocation(program,'uPMatrix'),
//mvMatrixUniform = gl.getUniformLocation(program,'uMVMatrix');
valueUniform = gl.getUniformLocation(program,'value'),
xUniform = gl.getUniformLocation(program,'x');
gl.uniformMatrix4fv(pMatrixUniform,false,pMatrix);
//program.uColor = gl.getUniformLocation(program,'uColor');
//gl.uniform4fv(program.uColor,[0,0.0,1.0,1.0]);
gl.uniform1f(valueUniform,0);
gl.uniform1f(xUniform,0);
program.aVertexPosition = gl.getAttribLocation(program,'aVertexPosition');
//program.aXPosition = gl.getAttribLocation(program,'aXPosition');
//program.aValue = gl.getAttribLocation(program,'aValue');
gl.enableVertexAttribArray(program.aVertexPosition);
gl.vertexAttribPointer(program.aVertexPosition,3,gl.FLOAT,false,0,0);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,ibuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,indices,gl.STATIC_DRAW);
gl.enable(gl.BLEND);
gl.enable(gl.DEPTH_TEST);
gl.viewport(0,0,window.innerWidth-100,window.innerHeight-100)
//gl.depthFunc(gl.LEQUAL);
gl.blendFunc(gl.SRC_ALPHA,gl.ONE_MINUS_SRC_ALPHA);
var data = [];
for (var i=0,ln=1000;i<ln;i++) {
data.push({
id : i,
name : `cat${i}`,
value : Math.random()*30
});
}
xScale = d3.scaleLinear().domain([0,data.length]).range([-data.length/1.1,-data.length/5]);
yScale = d3.scaleLinear().domain([0,d3.max(data,(d)=>d.value)]).range([0,1]);
class BarShader extends c2.Element {
constructor () {
super();
this.indices = gl.createBuffer();
//this.vbuffer = gl.createBuffer();
}
render (context,d,i) {
var children = this.children,
child,
indices = this.indices,
children_length = children.length;
if (!indices || indices.length !== children_length * 36) {
indices = new Uint16Array(children_length*36);
var j,jln;
//duplicate indices
for (var i=0,ln=indices.length;i<ln;) {
for (j=0,jln=model.length;j<jln;j++) {
indices[i++] = model[j];
}
}
} else {
indices = this.indices;
}
for (var i=0,ln=children_length;i<ln;i++) {
child = children[i];
}
context.bindBuffer(gl.ARRAY_BUFFER,this.vbuffer);
context.bufferData(gl.ARRAY_BUFFER,vertices,gl.STATIC_DRAW);
}
}
class Triangle2 extends c2.Element {
render (context,d,i) {
mvMatrix[0] = 1.0/100.0
mvMatrix[5] = +this.v;
mvMatrix[12] = (this.x+i)/100.0*1.2+.1;
mvMatrix[13] = this.v/1.0-.5;
gl.uniformMatrix4fv(mvMatrixUniform,false,mvMatrix);
gl.uniform1f(valueUniform,this.v);
//gl.uniform1f(xUniform,this.x+i);
gl.drawElements(gl.TRIANGLES,36,gl.UNSIGNED_SHORT,0);
}
};
Triangle2.attributes({
x : c2.types.float,
v : c2.types.float
})
selection = context.selectAll(Triangle2).data(data,(d)=>d.id);
selection.enter().append(Triangle2)
.attr('t',0)
.attr('v',0)
//.attr('x',0)
.attr('x',(d, i)=>i/1000)
.attr('scale',1/data.length)
.merge(selection)
.call(
c2.animate()
.ease(d3.easeElastic)
.duration(2000)
//.delay((d,i)=>i)
.to('v',(d)=>yScale(d.value))
//.to('x',(d)=>xScale(d.id))
//.to('t',Math.PI*2)
)
//.transition()
}()
var pressed = false,
lastMovementX,
lastMovementY;
window.addEventListener('mousedown',(e) => {
if (e.button === 0) {
pressed = true;
lastMovementX = lastMovementY = 0;
}
})
window.addEventListener('mouseup',(e) => {
if (e.button === 0) {
pressed = false;
}
})
window.addEventListener('mousemove',(e) => {
if (pressed) {
mat4.rotate(pMatrix,pMatrix,(e.movementX)*Math.PI/360,[0,1,0]);
mat4.rotate(pMatrix,pMatrix,(e.movementY)*Math.PI/360,[1,0,0]);
//console.error(e.movementX);
//mat4.rotate(mvMatrix,mvMatrix,(e.movementY-lastMovementY)/30,[0,1,0]);
lastMovementY = e.movementY;
lastMovementX = e.movementX;
context.node().invalidate();
}
});
window.addEventListener('wheel',(e) => {
const delta = e.deltaY > 0 ? 1.1 : 0.9;
if (e.deltaY) {
mat4.scale(pMatrix,pMatrix,[delta,delta,delta]);
}
context.node().invalidate();
})