You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
230 lines
7.7 KiB
230 lines
7.7 KiB
<!DOCTYPE html> |
|
<html lang="en"> |
|
|
|
<head> |
|
<meta charset="UTF-8"> |
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" /> |
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"> |
|
<title>Leon Sans - Metaball PIXI</title> |
|
<style> |
|
html, |
|
body { |
|
width: 100%; |
|
height: 100%; |
|
overflow: hidden; |
|
outline: 0; |
|
margin: 0; |
|
padding: 0; |
|
cursor: move; |
|
} |
|
</style> |
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js"></script> |
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.3/TweenMax.min.js"></script> |
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/5.0.4/pixi.min.js"></script> |
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.6/dat.gui.js"></script> |
|
</head> |
|
|
|
<body> |
|
<script src="../dist/leon.js"></script> |
|
<script src="js/util.js"></script> |
|
<script> |
|
let container, texture, particleCon; |
|
let leon, controll, weightControll; |
|
const particleTotal = 10000; |
|
let particles = []; |
|
|
|
function init() { |
|
generatePixi(0x000000); |
|
|
|
texture = PIXI.Texture.from('data/drop-alpha.png'); |
|
particleCon = new PIXI.ParticleContainer(particleTotal, { |
|
vertices: false, |
|
scale: true, |
|
position: true, |
|
rotation: false, |
|
uvs: false, |
|
alpha: false |
|
}); |
|
stage.addChild(particleCon); |
|
|
|
let p, i; |
|
for (i = 0; i < particleTotal; i++) { |
|
p = new PIXI.Sprite(texture); |
|
p.x = sw / 2; |
|
p.y = sh / 2; |
|
p.anchor.set(0.5); |
|
p.scale.x = p.scale.y = 0; |
|
particleCon.addChild(p); |
|
particles.push(p); |
|
} |
|
|
|
const blurFilter = new PIXI.filters.BlurFilter(); |
|
blurFilter.blur = 10; |
|
blurFilter.autoFit = true; |
|
|
|
const fragSource = [ |
|
'precision mediump float;', |
|
'varying vec2 vTextureCoord;', |
|
'uniform sampler2D uSampler;', |
|
'uniform float threshold;', |
|
'uniform float mr;', |
|
'uniform float mg;', |
|
'uniform float mb;', |
|
'void main(void)', |
|
'{', |
|
' vec4 color = texture2D(uSampler, vTextureCoord);', |
|
' vec3 mcolor = vec3(mr, mg, mb);', |
|
' if (color.a > threshold) {', |
|
' gl_FragColor = vec4(mcolor, 1.0);', |
|
' } else {', |
|
' gl_FragColor = vec4(vec3(0.0), 0.0);', |
|
' }', |
|
'}' |
|
].join('\n'); |
|
|
|
const uniformsData = { |
|
threshold: 0.5, |
|
mr: 255.0/255.0, |
|
mg: 255.0/255.0, |
|
mb: 255.0/255.0, |
|
}; |
|
|
|
const thresholdFilter = new PIXI.Filter(null, fragSource, uniformsData); |
|
stage.filters = [blurFilter, thresholdFilter]; |
|
stage.filterArea = renderer.screen; |
|
|
|
controll = { |
|
weight: 3, |
|
color: {}, |
|
outline: true, |
|
drawing: () => { |
|
let i; |
|
for (i = 0; i < particleTotal; i++) { |
|
TweenMax.killTweensOf(particles[i].scale); |
|
TweenMax.set(particles[i].scale, { |
|
x: 0, |
|
y: 0 |
|
}); |
|
TweenMax.to(particles[i].scale, 3, { |
|
delay: 0.001 * i, |
|
x: particles[i].saveScale, |
|
y: particles[i].saveScale, |
|
ease: Circ.easeOut |
|
}); |
|
} |
|
} |
|
}; |
|
|
|
leon = new LeonSans({ |
|
text: 'TOP\n678', |
|
size: getSize(400), |
|
weight: 700, |
|
pathGap: -1, |
|
isPath: true, |
|
tracking: 0 |
|
}); |
|
leon.on('update', (model) => { |
|
update(); |
|
}); |
|
|
|
const gui = new dat.GUI(); |
|
gui.add(leon, 'text'); |
|
const sizeControll = gui.add(leon, 'size', 200, 1000); |
|
gui.add(leon, 'tracking', -6, 10); |
|
gui.add(leon, 'leading', -8, 10); |
|
weightControll = gui.add(controll, 'weight', 1, 9); |
|
gui.add(controll, 'drawing'); |
|
const colorControll = gui.add(controll, 'color', [ 'white', 'black', 'red'] ); |
|
|
|
sizeControll.onChange((value) => { |
|
sizeWeight(); |
|
}); |
|
|
|
weightControll.onChange((value) => { |
|
update(); |
|
}); |
|
|
|
colorControll.onChange((value) => { |
|
if (value == 'white') { |
|
renderer.backgroundColor = 0x000000; |
|
uniformsData.mr = 255.0/255.0; |
|
uniformsData.mg = 255.0/255.0; |
|
uniformsData.mb = 255.0/255.0; |
|
} else if (value == 'black') { |
|
renderer.backgroundColor = 0xffffff; |
|
uniformsData.mr = 0.0/255.0; |
|
uniformsData.mg = 0.0/255.0; |
|
uniformsData.mb = 0.0/255.0; |
|
} else if (value == 'red') { |
|
renderer.backgroundColor = 0xe4c143; |
|
uniformsData.mr = 244.0/255.0; |
|
uniformsData.mg = 46.0/255.0; |
|
uniformsData.mb = 33.0/255.0; |
|
} |
|
}); |
|
colorControll.setValue('white'); |
|
|
|
requestAnimationFrame(animate); |
|
|
|
sizeWeight(); |
|
|
|
TweenMax.delayedCall(0.1, () => { |
|
controll.drawing(); |
|
}); |
|
} |
|
|
|
function sizeWeight() { |
|
let w; |
|
if (leon.size > 400) { |
|
w = (1.5 - 3) / (1000 - 400) * (leon.size - 400) + 3; |
|
} else { |
|
w = (3 - 6) / (400 - 200) * (leon.size - 200) + 6; |
|
} |
|
weightControll.setValue(w); |
|
} |
|
|
|
function update() { |
|
const total = leon.paths.length; |
|
const sw2 = sw / 2; |
|
const sh2 = sh / 2; |
|
let i, p, pos, scale; |
|
for (i = 0; i < particleTotal; i++) { |
|
p = particles[i]; |
|
TweenMax.killTweensOf(p.scale); |
|
if (i < total) { |
|
pos = leon.paths[i]; |
|
if (pos.type == 'a') { |
|
scale = controll.weight * 0.025* leon.scale; |
|
} else { |
|
scale = controll.weight * 0.01* leon.scale; |
|
} |
|
p.saveScale = scale; |
|
p.x = pos.x; |
|
p.y = pos.y; |
|
p.scale.x = p.scale.y = scale; |
|
} else { |
|
p.saveScale = 0; |
|
p.x = -1000; |
|
p.y = -1000; |
|
p.scale.x = p.scale.y = 0; |
|
} |
|
} |
|
} |
|
|
|
function animate(t) { |
|
requestAnimationFrame(animate); |
|
|
|
const x = (sw - leon.rect.w) / 2; |
|
const y = (sh - leon.rect.h) / 2; |
|
leon.position(x + moveX, y + moveY); |
|
|
|
renderer.render(stage); |
|
} |
|
|
|
window.onload = () => { |
|
init(); |
|
}; |
|
</script> |
|
</body> |
|
|
|
</html> |