c2
Version:
d3 component canvas
249 lines (223 loc) • 7.72 kB
JavaScript
function reset (context) {
context.canvas.width = context.canvas.width;
context.clearColor(0,0,0,1.0);
//context.clearDepth(1.0);
context.clear(context.COLOR_BUFFER_BIT);
}
const canvas = document.querySelector('canvas'),
context = d3.select(canvas)
.attr('width',window.innerWidth)
.attr('height',window.innerHeight)
.select(c2.ContextWebGL)
.on('tick',function () {
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,-1])
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.create();
//mat4.rotate(mvMatrix,mvMatrix,-1,[1,1,1]);
!function init () {
var model = new Float32Array([
//front
-0.5, 0.5, 0.0,
0.5, -0.5, 0.0,
-0.5, -0.5, 0.0,
0.5, 0.5, 0.0,
-0.5, 0.5, 0.0,
0.5, -0.5, 0.0,
//right side
0.5, -0.5, 0.0,
0.5, 0.5, 0.0,
0.5, 0.5, -0.0525,
0.5,-0.5,0,
0.5,-0.5,-0.0525,
0.5,0.5,-0.0525,
//top
0.5,0.5,-0.0525,
-0.5,0.5,0,
-0.5,0.5,-0.0525,
0.5,0.5,-0.0525,
0.5,0.5,0,
-0.5,0.5,0,
//left side
-0.5, -0.5, 0.0,
-0.5, 0.5, 0.0,
-0.5, 0.5, -0.0525,
-0.5,-0.5,0,
-0.5,-0.5,-0.0525,
-0.5,0.5,-0.0525
]),
itemSize = 3,
numItems = model.length / itemSize,
pMatrixUniform,
mvMatrixUniform,
Triangle,
selection,
xScale,yScale;
gl.shaderSource(vertex_shader,`
attribute vec3 aVertexPosition;
uniform float value;
uniform float x;
uniform mat4 uPMatrix;
uniform mat4 uMVMatrix;
varying float t;
void main () {
//mat4 dup = mat4(uMVMatrix);
//dup[0][0] = 2.0/100.0;
//dup[1][1] = value/1.0;
//dup[3][0] = x/100.0*1.2+.1;
//dup[3][1] = value/2.0-.5;
//gl_Position = uPMatrix*dup* vec4(aVertexPosition,1.0);
gl_Position = uPMatrix*uMVMatrix* vec4(aVertexPosition,1.0);
t = value*aVertexPosition.z*1.0;
}
`);
gl.shaderSource(fragment_shader,`
#ifdef GL_ES
precision highp float;
#endif
varying float t;
//uniform vec4 uColor;
void main () {
gl_FragColor = vec4(0,0,1.0-t,0.3);
//gl_FragColor = vec4(0,0,max(sin(t*3.14+3.14),.5),1);
}
`);
gl.compileShader(vertex_shader);
gl.compileShader(fragment_shader);
gl.attachShader(program,vertex_shader);
gl.attachShader(program,fragment_shader);
gl.linkProgram(program);
vbuffer = gl.createBuffer();
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');
var 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');
gl.enableVertexAttribArray(program.aVertexPosition);
gl.vertexAttribPointer(program.aVertexPosition,itemSize,gl.FLOAT,false,0,0);
gl.enable(gl.BLEND);
//gl.enable(gl.DEPTH_TEST);
gl.viewport(0,0,window.innerWidth,window.innerHeight)
//gl.depthFunc(gl.LEQUAL);
gl.blendFunc(gl.SRC_ALPHA,gl.ONE_MINUS_SRC_ALPHA);
var data = [];
for (var i=0,ln=100000;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]);
Triangle = c2.element(function (context,d,i) {
//const next = mat4.create();
//mat4.scale(next,next,[this.scale,yScale(this.v),this.scale]);
//mat4.translate(next,next,[xScale(i)+i,0,0]);
//gl.uniformMatrix4fv(mvMatrixUniform,false,mvMatrix);
//dup[0][0] = 2.0/100.0;
//dup[1][1] = value/1.0;
//dup[3][0] = x/100.0*1.2+.1;
//dup[3][1] = value/2.0-.5;
gl.uniformMatrix4fv(pMatrixUniform,false,pMatrix);
mvMatrix[0] = 2.0/100.0
mvMatrix[5] = this.v;
mvMatrix[12] = (this.x+i)/100.0*1.2+.1;
mvMatrix[13] = this.v/2.0-.5;
gl.uniformMatrix4fv(mvMatrixUniform,false,mvMatrix);
//gl.uniform1f(valueUniform,this.v);
//gl.uniform1f(xUniform,this.x+i);
gl.bindBuffer(gl.ARRAY_BUFFER, vbuffer);
gl.drawArrays(gl.TRIANGLES,0,numItems);
}).attributes({
v : c2.types.float,
x : c2.types.float
});
class Triangle2 extends c2.Element {
render (context,d,i) {
gl.uniformMatrix4fv(pMatrixUniform,false,pMatrix);
mvMatrix[0] = 2.0/100.0
mvMatrix[5] = this.v;
mvMatrix[12] = (this.x+i)/100.0*1.2+.1;
mvMatrix[13] = this.v/2.0-.5;
gl.uniformMatrix4fv(mvMatrixUniform,false,mvMatrix);
//gl.uniform1f(valueUniform,this.v);
//gl.uniform1f(xUniform,this.x+i);
gl.bindBuffer(gl.ARRAY_BUFFER, vbuffer);
gl.drawArrays(gl.TRIANGLES,0,numItems);
}
};
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)=>xScale(d.id))
.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();
})