index41
const PX_RATIO = window.devicePixelRatio
Math.map = (n, start, stop, start2, stop2) => {
const newval = (n - start) / (stop - start) * (stop2 - start2) + start2
return newval
}
Math.dist = (a, b) => {
let dx = a.x - b.x,
dy = a.y - b.y;
return Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));
}
class Text {
constructor(txt, args) {
if (args === undefined) args = {}
this.canvas = document.createElement("canvas")
document.body.appendChild(this.canvas)
this.canvas.style.visibility = "hidden"
this.context = this.canvas.getContext("2d")
this.center = {
x: 0,
y: 0
}
this.pos = {
x: 0,
y: 0
}
this.mouse = {
x: window.innerWidth / 2,
y: window.innerHeight / 2
}
this.fontSize = 100
this.lineHeight = this.fontSize * 0.9
this.font = this.fontSize + "px Oswald"
this.fillStyle = args.color || "#fff"
this.txt = txt.toUpperCase() || "Oswald"
this.friction = 0.1
this.addEvents()
this.resize()
}
get texture() {
return this.canvas
}
resize() {
this.render()
this.height = this.fontSize
this.canvas.width = 650
this.canvas.height = this.height
this.center = {
x: (window.innerWidth / 2) * PX_RATIO,
y: (window.innerHeight / 2) * PX_RATIO
}
this.diagonal = Math.dist(this.center, {
x: window.innerWidth * PX_RATIO,
y: window.innerHeight * PX_RATIO
})
}
addEvents() {
document.addEventListener('mousemove', this.onMouseMove.bind(this), false)
document.addEventListener('touchmove', this.onMouseMove.bind(this), false)
}
onMouseMove(e) {
if (e.touches) e = e.touches[0]
this.mouse.x = e.clientX * PX_RATIO
this.mouse.y = e.clientY * PX_RATIO
}
update(args) {
this.pos.x += (this.mouse.x - this.pos.x) * this.friction
this.pos.y += (this.mouse.y - this.pos.y) * this.friction
let dist = Math.dist(this.pos, this.center)
this.dist = dist / this.diagonal
this.wght = Math.map(dist, 0, this.diagonal, 700, 100)
}
render() {
this.update()
this.context.fillStyle = "#000"
this.context.fillRect(0, 0, this.canvas.width, this.canvas.height)
this.context.fillStyle = this.fillStyle
this.context.font = this.font
this.width = this.context.measureText(this.text).width
this.context.fillText(this.txt, (420 - this.width) / 2, this.lineHeight)
this.canvas.style.fontVariationSettings = "'wght' " + this.wght.toFixed(2)
}
}
class VariableText {
constructor(_text) {
this.camera = new THREE.PerspectiveCamera(45, this.rect.width / this.rect.height, 1, 1000)
this.camera.position.z = 10
this.scene = new THREE.Scene()
this.text = new Text(_text)
this.texture = new THREE.CanvasTexture(this.text.texture)
this.texture.minFilter = THREE.NearestFilter
this.geometry = new THREE.BoxGeometry(4, 1, 4, 8, 5, 8)
this.mesh = new THREE.Mesh(this.geometry, this.material)
this.scene.add(this.mesh)
this.mouse = {
x: 1,
y: 1
}
this.setRenderer()
this.addEvents()
this.animate()
}
get rect() {
return document.body.getBoundingClientRect()
}
onMouseMove(e) {
if (e.touches) e = e.touches[0]
this.mouse = {
x: (e.clientX - this.center.x) * 0.0035,
y: (e.clientY - this.center.y) / 50
}
}
addEvents() {
window.addEventListener('resize', () => this.onWindowResize(), false)
document.addEventListener('mousemove', (e) => this.onMouseMove(e), false)
document.addEventListener('touchmove', (e) => this.onMouseMove(e), false)
}
get material() {
return new THREE.ShaderMaterial({
vertexShader: document.getElementById('vertexShader').textContent,
fragmentShader: document.getElementById('fragmentShader').textContent,
transparent: true,
uniforms: {
uTime: {
value: 0
},
mouse: {
value: 1.0
},
uTexture: {
value: this.texture
}
},
})
}
setRenderer() {
this.renderer = new THREE.WebGLRenderer({
antialias: true,
alpha: true
})
this.renderer.setPixelRatio(window.devicePixelRatio)
this.renderer.setSize(this.rect.width, this.rect.height)
document.body.appendChild(this.renderer.domElement)
this.onWindowResize()
}
onWindowResize() {
this.center = {
x: this.rect.width / 2,
y: this.rect.height / 2
}
this.text.resize()
this.camera.aspect = this.rect.width / this.rect.height
this.camera.updateProjectionMatrix()
this.renderer.setSize(this.rect.width, this.rect.height)
}
animate() {
requestAnimationFrame(() => this.animate())
this.text.render()
this.render()
}
render(delta) {
let time = new Date().getTime() * 0.001
this.mesh.material.uniforms.mouse.value = this.text.dist
this.mesh.material.uniforms.uTime.value = Math.sin(time)
this.texture.needsUpdate = true
this.camera.position.x += (this.mouse.x - this.camera.position.x) * .05;
this.mesh.rotation.y += (-this.mouse.x - this.mesh.rotation.y) * .05;
this.camera.lookAt(this.scene.position)
this.renderer.render(this.scene, this.camera)
}
}
window.onload = () => {
const _text = new VariableText("Webstoryboy")
}