summaryrefslogtreecommitdiff
path: root/site/assets
diff options
context:
space:
mode:
authorJules Laplace <julescarbon@gmail.com>2018-12-06 19:39:29 +0100
committerJules Laplace <julescarbon@gmail.com>2018-12-06 19:39:29 +0100
commit2d950c3fa3b8107f941a80f88127ab45e371d128 (patch)
tree239d6b0162b96153d5fc624f1f7ebe6218f51b3e /site/assets
parent1f97c63136a24ae288f7c946f23b1c7519b2c6e0 (diff)
homepage css
Diffstat (limited to 'site/assets')
-rw-r--r--site/assets/css/css.css93
-rw-r--r--site/assets/js/app/face.js213
-rw-r--r--site/assets/js/app/site.js3
3 files changed, 304 insertions, 5 deletions
diff --git a/site/assets/css/css.css b/site/assets/css/css.css
index 843809a8..9ac35699 100644
--- a/site/assets/css/css.css
+++ b/site/assets/css/css.css
@@ -5,9 +5,11 @@ html, body {
width: 100%;
min-height: 100%;
font-family: 'Roboto', sans-serif;
- background: #191919;
color: #b8b8b8;
}
+html {
+ background: #191919;
+}
/* header */
@@ -119,12 +121,14 @@ h1 {
font-size: 24pt;
margin: 75px 0 10px;
padding: 0;
+ transition: color 0.2s cubic-bezier(0,0,1,1);
}
h2, h3 {
margin: 0 0 20px 0;
padding: 0;
font-size: 11pt;
font-weight: 500;
+ transition: color 0.2s cubic-bezier(0,0,1,1);
}
th, .gray, h2, h3 {
@@ -281,6 +285,9 @@ section.wide .image {
max-width: 620px;
margin: 10px auto 0 auto;
}
+
+/* blog index */
+
.research_index {
margin-top: 40px;
}
@@ -289,10 +296,88 @@ section.wide .image {
}
.research_index h1 {
margin-top: 20px;
+ text-decoration: underline;
+}
+.desktop .research_index section:hover h1 {
+ color: #fff;
+}
+.research_index section:hover h2 {
+ color: #ddd;
}
-/* blogpost index */
+/* home page */
-.blogposts div {
- margin-bottom: 5px;
+.hero {
+ position: relative;
+ width: 100%;
+ max-width: 1200px;
+ height: 50vw;
+ max-height: 70vh;
+ display: flex;
+ align-items: center;
+ margin: 0 auto;
+}
+#face_container {
+ pointer-events: none;
+ position: absolute;
+ width: 50vw;
+ height: 50vw;
+ max-height: 70vh;
+ top: 0;
+ right: 0;
+ z-index: -1;
+ text-align: center;
+}
+.currentFace {
+ position: absolute;
+ bottom: 50px;
+ width: 100%;
+ left: 0;
+ text-align: center;
+}
+.intro {
+ max-width: 640px;
+ padding: 75px 0 75px 10px;
+ z-index: 1;
+}
+.intro .headline {
+ font-family: 'Roboto Mono', monospace;
+ font-size: 16pt;
+}
+.intro .buttons {
+ margin: 40px 0;
+}
+.intro button {
+ font-family: 'Roboto', sans-serif;
+ padding: 8px 12px;
+ border-radius: 6px;
+ border: 1px solid transparent;
+ cursor: pointer;
+ font-size: 11pt;
+ margin-right: 10px;
+ transition: color 0.1s cubic-bezier(0,0,1,1), background-color 0.1s cubic-bezier(0,0,1,1);
+}
+.intro button.normal {
+ background: #191919;
+ border-color: #444;
+ color: #ddd;
+}
+.intro button.important {
+ background: #444;
+ border-color: #444;
+ color: #ddd;
+}
+.desktop .intro button:hover {
+ background: #666;
+ border-color: #666;
+ color: #fff;
+}
+.intro .under {
+ color: #888;
+}
+.intro .under a {
+ color: #bbb;
+}
+.desktop .intro .under a:hover {
+ color: #fff;
} \ No newline at end of file
diff --git a/site/assets/js/app/face.js b/site/assets/js/app/face.js
new file mode 100644
index 00000000..e8bcd313
--- /dev/null
+++ b/site/assets/js/app/face.js
@@ -0,0 +1,213 @@
+var face = (function(){
+ var container = document.querySelector("#face_container")
+ var camera, controls, scene, renderer
+ var mouse = new THREE.Vector2(0.5, 0.5)
+ var mouseTarget = new THREE.Vector2(0.5, 0.5)
+ var POINT_SCALE = 1.8
+ var FACE_POINT_COUNT = 68
+ var SWAP_TIME = 500
+ var cubesĀ = [], meshes = []
+ var currentFace = document.querySelector('.currentFace')
+ var faceBuffer = (function () {
+ var a = new Array(FACE_POINT_COUNT)
+ for (let i = 0; i < FACE_POINT_COUNT; i++) {
+ a[i] = new THREE.Vector3()
+ }
+ return a
+ })()
+ var last_t = 0, start_t = 0
+ var colors = [
+ 0xff3333,
+ 0xff8833,
+ 0xffff33,
+ 0x338833,
+ 0x3388ff,
+ 0x3333ff,
+ 0x8833ff,
+ 0xff3388,
+ 0xffffff,
+ ]
+ var swapping = false, swap_count = 0, swapFrom, swapTo, face_names, faces
+ init()
+
+ function init() {
+ fetch("/assets/data/3dlm_0_10.json")
+ .then(req => req.json())
+ .then(data => {
+ face_names = Object.keys(data)
+ faces = face_names.map(name => recenter(data[name]))
+ setup()
+ build(faces[0])
+ updateFace(faces[0])
+ setCurrentFace(face_names[0])
+ swapTo = faces[0]
+ animate()
+ })
+ }
+ function setup() {
+ var w = window.innerWidth / 2
+ var h = Math.min(window.innerWidth / 2, window.innerHeight * 0.7)
+ camera = new THREE.PerspectiveCamera(70, w/h, 1, 10000)
+ camera.position.x = 0
+ camera.position.y = 0
+ camera.position.z = 250
+
+ scene = new THREE.Scene()
+ scene.background = new THREE.Color(0x191919)
+
+ renderer = new THREE.WebGLRenderer({ antialias: true })
+ renderer.setPixelRatio(window.devicePixelRatio)
+ renderer.setSize(w, h)
+ container.appendChild(renderer.domElement)
+ document.body.addEventListener('mousemove', onMouseMove)
+ // renderer.domElement.addEventListener('mousedown', swap)
+ setInterval(swap, 5000)
+ }
+ function build(points) {
+ var matrix = new THREE.Matrix4()
+ var quaternion = new THREE.Quaternion()
+
+ for (var i = 0; i < FACE_POINT_COUNT; i++) {
+ var p = points[i]
+ var geometry = new THREE.BoxBufferGeometry()
+ var position = new THREE.Vector3(p[0], p[1], p[2])
+ var rotation = new THREE.Euler()
+ var scale = new THREE.Vector3()
+ var color = new THREE.Color()
+ scale.x = scale.y = scale.z = POINT_SCALE
+ quaternion.setFromEuler(rotation, false)
+ matrix.compose(position, quaternion, scale)
+ geometry.applyMatrix(matrix)
+ material = new THREE.MeshBasicMaterial({ color: color.setHex(0xffffff) })
+ cube = new THREE.Mesh(geometry, material)
+ scene.add(cube)
+ cubes.push(cube)
+ }
+
+ meshes = getLineGeometry(points).map((geometry, i) => {
+ var color = new THREE.Color()
+ var material = new MeshLineMaterial({
+ color: color.setHex(colors[i % colors.length]),
+ })
+ var line = new MeshLine()
+ line.setGeometry(geometry, _ => 1.5)
+ var mesh = new THREE.Mesh(line.geometry, material)
+ mesh.geometry.dynamic = true
+ scene.add(mesh)
+ return [line, mesh]
+ })
+ }
+ function lerpPoints(n, A, B, C) {
+ for (let i = 0, len = A.length; i < len; i++) {
+ lerpPoint(n, A[i], B[i], C[i])
+ }
+ }
+ function lerpPoint(n, A, B, C) {
+ C.x = lerp(n, A.x, B.x)
+ C.y = lerp(n, A.y, B.y)
+ C.z = lerp(n, A.z, B.z)
+ }
+ function lerp(n, a, b) {
+ return (b-a) * n + a
+ }
+ function swap(){
+ if (swapping) return
+ start_t = last_t
+ swapping = true
+ swap_count = (swap_count + 1) % faces.length
+ swapFrom = swapTo
+ swapTo = faces[swap_count]
+ setCurrentFace(face_names[swap_count])
+ }
+ function setCurrentFace(name) {
+ name = name.replace('.png', '').split('_').filter(s => !s.match(/\d+/)).join(' ')
+ currentFace.innerHTML = name
+ }
+ function update_swap(t){
+ var n = (t - start_t) / SWAP_TIME
+ if (n > 1) {
+ swapping = false
+ n = 1
+ }
+ lerpPoints(n, swapFrom, swapTo, faceBuffer)
+ updateFace(faceBuffer)
+ }
+ function updateFace(points) {
+ updateCubeGeometry(points)
+ updateLineGeometry(points)
+ }
+ function updateCubeGeometry(points) {
+ cubes.forEach((cube, i) => {
+ const p = points[i]
+ cube.position.set(p.x, p.y, p.z)
+ })
+ }
+ function updateLineGeometry(points) {
+ getLineGeometry(points).map((geometry, i) => {
+ var [line, mesh] = meshes[i]
+ line.setGeometry(geometry, _ => 1.5)
+ mesh.geometry.vertices = line.geometry.vertices
+ mesh.geometry.verticesNeedUpdate = true
+ })
+ }
+ function getLineGeometry(points) {
+ return [
+ points.slice(0, 17),
+ points.slice(17, 22),
+ points.slice(22, 27),
+ points.slice(27, 31),
+ points.slice(31, 36),
+ points.slice(36, 42),
+ points.slice(42, 48),
+ points.slice(48)
+ ].map((a, i) => {
+ var geometry = new THREE.Geometry()
+ a.forEach(p => geometry.vertices.push(p))
+ if (i > 4) {
+ geometry.vertices.push(a[0])
+ }
+ return geometry
+ })
+ }
+ function getBounds(obj) {
+ return obj.reduce((a, p) => {
+ return [
+ Math.min(a[0], p[0]),
+ Math.max(a[1], p[0]),
+ Math.min(a[2], p[1]),
+ Math.max(a[3], p[1]),
+ Math.min(a[4], p[2]),
+ Math.max(a[5], p[2]),
+ ]
+ }, [Infinity, -Infinity, Infinity, -Infinity, Infinity, -Infinity])
+ }
+ function recenter(obj) {
+ const bounds = getBounds(obj)
+ const x_width = (bounds[1] - bounds[0]) / 2
+ const y_width = (bounds[3] - bounds[2]) / -3
+ const z_width = (bounds[5] - bounds[4]) / 2
+ return obj.map(p => {
+ p[0] = p[0] - bounds[0] - x_width
+ p[1] = -p[1] + bounds[1] + y_width
+ p[2] = p[2] - bounds[2] + z_width
+ return new THREE.Vector3(p[0], p[1], p[2])
+ })
+ }
+ //
+ function onMouseMove(e) {
+ mouse.x = e.clientX / window.innerWidth
+ mouse.y = e.clientY / window.innerHeight
+ }
+ function animate(t) {
+ requestAnimationFrame(animate)
+ if (swapping) update_swap(t)
+ renderer.render(scene, camera)
+ scene.rotation.y += 0.01 * Math.PI
+ mouseTarget.x += (mouse.x - mouseTarget.x) * 0.1
+ mouseTarget.y += (mouse.y - mouseTarget.y) * 0.1
+ scene.rotation.x = (mouseTarget.y - 0.5) * Math.PI / 2
+ // scene.rotation.y = (mouseTarget.x - 0.5) * Math.PI
+ scene.rotation.y += 0.01
+ last_t = t
+ }
+})()
diff --git a/site/assets/js/app/site.js b/site/assets/js/app/site.js
index 12bee3ec..eb6886c2 100644
--- a/site/assets/js/app/site.js
+++ b/site/assets/js/app/site.js
@@ -7,7 +7,8 @@ const isDesktop = !isMobile
const htmlClassList = document.body.parentNode.classList
htmlClassList.add(isDesktop ? 'desktop' : 'mobile')
-function toArray(A) { return Array.prototype.slice.apply(A) }
+function toArray(a) { return Array.prototype.slice.apply(a) }
+function choice(a) { return a[Math.floor(Math.random()*a.length)]}
var site = (function(){
var site = {}