<script id="fragmentShader" type="x-shader/x-fragment">
precision mediump float;
uniform float time;
uniform float mouseX;
uniform float mouseY;
uniform sampler2D texture;
varying vec2 vUv;
void main() {
float d = -distance(vec2(mouseX,mouseY), gl_FragCoord.xy);
float r = dot(gl_FragCoord.xy, vec2(0.005,0.005))/d;
vec2 tex = vec2(vUv.x + r, vUv.y + r);
gl_FragColor = vec4(texture2D(texture, tex).rgb, 1.0);
}
</script>
<script id="vertexShader" type="x-shader/x-vertex">
precision mediump float;
varying vec2 vUv;
uniform float time;
void main() {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
</script>
<div class="stage"></div>
<canvas class="noise-canvas"></canvas>
.noise-canvas{
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
width: 100%;
height: 100%;
opacity: 0.3;
z-index: 2;
}
View Compiled
'use strict'
console.clear();
const APP_CONFIG = {
debug: false,
gridDebugSize: {
x: 10,
y: 10
},
fontSize: 600,
axisHelperSize: 10
}
class App {
constructor(){
_.bindAll(this, 'animate', 'onResize', 'onMouseMove');
this.time = 0;
this.planeHeight = 50;
this.ratio = window.innerWidth / window.innerHeight;
this.planeWidth = this.planeHeight*this.ratio;
//SET-UP CAMERA
this.cameraOpts = {
aspect: window.innerWidth / window.innerHeight,
near: 0.1,
far : 10000,
z: this.planeHeight
}
let fov = 2 * Math.atan( this.planeHeight / ( 2 * this.cameraOpts.z ) ) * ( 180 / Math.PI );
this.camera = new THREE.PerspectiveCamera(fov, this.cameraOpts.aspect, this.cameraOpts.near, this.cameraOpts.far);
this.camera.position.z = this.cameraOpts.z;
//SET-UP STAGE
this.stage = new THREE.Scene();
this.stage.add(this.camera);
//SET-UP RENDERER
this.renderer = new THREE.WebGLRenderer({ antialias: true});
this.renderer.setSize(window.innerWidth, window.innerHeight);
this.start();
}
start(){
if (APP_CONFIG.debug){
this.debug();
}
let texture = new THREE.Texture(this.createCanvas("Interactive Art Director"));
texture.needsUpdate = true;
let planeGeometry = new THREE.PlaneGeometry(this.planeWidth, this.planeHeight, 0, 0);
this.uniforms = {
texture: {
type: 't',
value: texture
},
time: {
type: "f",
value: this.time
},
mouseX: {
type: "f",
value: 0
},
mouseY: {
type: "f",
value: 0
}
}
var vertShader = document.getElementById('vertexShader').innerHTML;
var fragShader = document.getElementById('fragmentShader').innerHTML;
let planeMaterial = new THREE.ShaderMaterial({
uniforms: this.uniforms,
vertexShader: vertShader,
fragmentShader: fragShader,
wireframe : false,
wireframeLinewidth : 2,
transparent : true
});
this.plane = new THREE.Mesh(planeGeometry, planeMaterial);
this.stage.add(this.plane);
let container = document.querySelector('.stage');
container.appendChild(this.renderer.domElement);
TweenMax.ticker.addEventListener('tick', this.animate);
//ADD EVENTS LISTENER
this.listen();
}
createCanvas(text){
this.canvas = document.createElement( 'canvas' );
this.canvas.height = 4096;
this.canvas.width = this.canvas.height*this.ratio;
let context = this.canvas.getContext( '2d' );
context.beginPath();
context.rect(0, 0, this.canvas.width, this.canvas.height);
context.fillStyle = '#202020';
context.fill();
context.closePath();
context.beginPath();
context.font = 'Bold '+ APP_CONFIG.fontSize +'px Avenir';
context.fillStyle = '#262626';
let width = context.measureText(text).width;
context.fillText(text, this.canvas.width/2 - width/2, this.canvas.height/2);
context.fill();
return this.canvas;
}
debug(){
let gridHelper = new THREE.GridHelper( APP_CONFIG.gridDebugSize.x, APP_CONFIG.gridDebugSize.y );
this.stage.add( gridHelper );
let axisHelper = new THREE.AxisHelper( APP_CONFIG.axisHelperSize );
this.stage.add( axisHelper );
}
listen(){
let lazyLayout = _.debounce(this.onResize, 300);
window.addEventListener('resize', lazyLayout);
window.addEventListener('mousemove', this.onMouseMove);
}
onResize(e){
this.renderer.setSize(window.innerWidth, window.innerHeight);
this.camera.updateProjectionMatrix();
}
onMouseMove(e){
this.mousePos = {
x: e.clientX,
y: e.clientY
}
}
animate(){
if(this.mousePos){
this.uniforms.mouseX.value = this.mousePos.x;
this.uniforms.mouseY.value = window.innerHeight - this.mousePos.y;
}
this.renderer.render(this.stage, this.camera);
this.uniforms.time.value += 0.1;
}
}
new App();
View Compiled
This Pen doesn't use any external CSS resources.