From c293006ba43944ffeb4dcab17b2256f3a5491a36 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Thu, 17 Jan 2019 15:10:19 +0100 Subject: build cloud --- site/assets/cloud/.gitignore | 1 + site/assets/cloud/.npmignore | 4 + site/assets/cloud/LICENSE | 21 +++++ site/assets/cloud/README.md | 109 +++++++++++++++++++++++ site/assets/cloud/THREE.TextSprite.js | 1 + site/assets/cloud/demo/script.js | 129 ++++++++++++++++++++++++++++ site/assets/cloud/index.html | 31 +++++++ site/assets/cloud/package.json | 40 +++++++++ site/assets/cloud/rollup.config.js | 25 ++++++ site/assets/cloud/src/getOptimalFontSize.js | 18 ++++ site/assets/cloud/src/index.js | 78 +++++++++++++++++ site/assets/css/css.css | 15 +++- site/assets/js/app/face.js | 68 ++++++++------- 13 files changed, 505 insertions(+), 35 deletions(-) create mode 100644 site/assets/cloud/.gitignore create mode 100644 site/assets/cloud/.npmignore create mode 100644 site/assets/cloud/LICENSE create mode 100644 site/assets/cloud/README.md create mode 100644 site/assets/cloud/THREE.TextSprite.js create mode 100644 site/assets/cloud/demo/script.js create mode 100644 site/assets/cloud/index.html create mode 100644 site/assets/cloud/package.json create mode 100644 site/assets/cloud/rollup.config.js create mode 100644 site/assets/cloud/src/getOptimalFontSize.js create mode 100644 site/assets/cloud/src/index.js (limited to 'site/assets') diff --git a/site/assets/cloud/.gitignore b/site/assets/cloud/.gitignore new file mode 100644 index 00000000..2ccbe465 --- /dev/null +++ b/site/assets/cloud/.gitignore @@ -0,0 +1 @@ +/node_modules/ diff --git a/site/assets/cloud/.npmignore b/site/assets/cloud/.npmignore new file mode 100644 index 00000000..dcaf4a28 --- /dev/null +++ b/site/assets/cloud/.npmignore @@ -0,0 +1,4 @@ +/demo/ +/index.html +/rollup.config.js +/src/ diff --git a/site/assets/cloud/LICENSE b/site/assets/cloud/LICENSE new file mode 100644 index 00000000..edeba37c --- /dev/null +++ b/site/assets/cloud/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017-2018 Sergej Sintschilin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/site/assets/cloud/README.md b/site/assets/cloud/README.md new file mode 100644 index 00000000..de6e882e --- /dev/null +++ b/site/assets/cloud/README.md @@ -0,0 +1,109 @@ +# THREE.TextSprite + +`class THREE.TextSprite extends THREE.Sprite` + +An instance of `TextSprite` automatically computes the optimal font size depending on the distance to the camera and the size of the renderer canvas. + +## demo + +[Try it out!](https://seregpie.github.io/THREE.TextSprite/) + +## dependencies + +- [THREE.TextTexture](https://github.com/SeregPie/THREE.TextTexture) + +## setup + +### npm + +```shell +npm install three.textsprite +``` + +### ES module + +```javascript +import TextSprite from 'three.textsprite'; +``` + +### browser + +```html + + + +``` + +The class `TextSprite` will be available under the namespace `THREE`. + +## members + +``` +.constructor({ + material, + maxFontSize, + minFontSize, + redrawInterval, + textSize, + texture, +}) +``` + +| argument | description | +| ---: | :--- | +| `material` | The parameters to pass to the constructor of [`SpriteMaterial`](https://threejs.org/docs/index.html#api/materials/SpriteMaterial). | +| `texture` | The parameters to pass to the constructor of [`TextTexture`](https://github.com/SeregPie/THREE.TextTexture). | + +```javascript +let sprite = new THREE.TextSprite({ + material: { + color: 0xffbbff, + fog: true, + }, + redrawInterval: 250, + textSize: 10, + texture: { + text: 'Carpe Diem', + fontFamily: 'Arial, Helvetica, sans-serif', + }, +}); +scene.add(sprite); +``` + +--- + +`.isTextSprite = true` + +Used to check whether this is an instance of `TextSprite`. + +You should not change this, as it is used internally for optimisation. + +--- + +`.textSize = 1` + +The size of the text. + +--- + +`.redrawInterval = 1` + +The minimum time that must elapse before the canvas is redrawn. If 0, the canvas is redrawn immediately whenever `TextSprite` is rendered, otherwise the redrawing is deferred. + +--- + +`.minFontSize = 0` + +The minimum font size. + +--- + +`.maxFontSize = Infinity` + +The maximum font size. + +--- + +`.dispose()` + +Disposes the texture and the material. diff --git a/site/assets/cloud/THREE.TextSprite.js b/site/assets/cloud/THREE.TextSprite.js new file mode 100644 index 00000000..525d22cd --- /dev/null +++ b/site/assets/cloud/THREE.TextSprite.js @@ -0,0 +1 @@ +(function(a,b){"object"==typeof exports&&"undefined"!=typeof module?module.exports=b(require("three"),require("three.texttexture")):"function"==typeof define&&define.amd?define(["three","three.texttexture"],b):(a.THREE=a.THREE||{},a.THREE.TextSprite=b(a.THREE,a.THREE.TextTexture))})(this,function(a,b){"use strict";function c(a,b,c){var g=Math.round;if(b.domElement.width&&b.domElement.height&&a.material.map.textLines.length){var h=a.getWorldPosition(d).distanceTo(c.getWorldPosition(e));if(h){var i=a.getWorldScale(f).y*b.domElement.height/h;if(i)return g(i/a.material.map.imageHeight)}}return 0}b=b&&b.hasOwnProperty("default")?b["default"]:b;var d=new a.Vector3,e=new a.Vector3,f=new a.Vector3,g=function(d){function e(c){void 0===c&&(c={});var e=c.textSize;void 0===e&&(e=1);var f=c.redrawInterval;void 0===f&&(f=1);var g=c.minFontSize;void 0===g&&(g=0);var h=c.maxFontSize;void 0===h&&(h=1/0);var i=c.material;void 0===i&&(i={});var j=c.texture;void 0===j&&(j={}),d.call(this,new a.SpriteMaterial(Object.assign({},i,{map:new b(j)}))),this.textSize=e,this.redrawInterval=f,this.minFontSize=g,this.maxFontSize=h,this.lastRedraw=0}d&&(e.__proto__=d),e.prototype=Object.create(d&&d.prototype),e.prototype.constructor=e;var f={isTextSprite:{configurable:!0}};return f.isTextSprite.get=function(){return!0},e.prototype.onBeforeRender=function(a,b,c){this.redraw(a,c)},e.prototype.updateScale=function(){this.scale.set(this.material.map.imageAspect,1,1).multiplyScalar(this.textSize*this.material.map.imageHeight)},e.prototype.updateMatrix=function(){for(var a=[],b=arguments.length;b--;)a[b]=arguments[b];return this.updateScale(),d.prototype.updateMatrix.apply(this,a)},e.prototype.redraw=function(a,b){var c=this;this.lastRedraw+this.redrawInterval + + + + + THREE.TextSprite + + + + + + + + + + + + diff --git a/site/assets/cloud/package.json b/site/assets/cloud/package.json new file mode 100644 index 00000000..f7556104 --- /dev/null +++ b/site/assets/cloud/package.json @@ -0,0 +1,40 @@ +{ + "name": "three.textsprite", + "version": "18.10.24", + "description": "Automatically computes the optimal font size depending on the distance to the camera and the size of the renderer canvas.", + "keywords": [ + "3d", + "canvas", + "class", + "font", + "group", + "object", + "plugin", + "resolution", + "scale", + "size", + "text", + "texture", + "three" + ], + "license": "MIT", + "author": "Sergej Sintschilin ", + "main": "THREE.TextSprite.js", + "repository": "https://github.com/SeregPie/THREE.TextSprite.git", + "scripts": { + "build": "rollup -c", + "dev": "rollup -c -w", + "prepublishOnly": "npm run build" + }, + "dependencies": { + "three.texttexture": "^18.10.24" + }, + "devDependencies": { + "rollup": "^0.66.6", + "rollup-plugin-babel-minify": "^6.1.1", + "rollup-plugin-buble": "^0.19.4" + }, + "peerDependencies": { + "three": "^0.97.0" + } +} diff --git a/site/assets/cloud/rollup.config.js b/site/assets/cloud/rollup.config.js new file mode 100644 index 00000000..57415169 --- /dev/null +++ b/site/assets/cloud/rollup.config.js @@ -0,0 +1,25 @@ +import buble from 'rollup-plugin-buble'; +import minify from 'rollup-plugin-babel-minify'; +import path from 'path'; + +import {main} from './package.json'; + +let globals = { + 'three': 'THREE', + 'three.texttexture': 'THREE.TextTexture', +}; + +export default { + input: 'src/index.js', + external: Object.keys(globals), + output: { + file: main, + format: 'umd', + name: path.basename(main, path.extname(main)), + globals, + }, + plugins: [ + buble({objectAssign: 'Object.assign'}), + minify({comments: false}), + ], +}; diff --git a/site/assets/cloud/src/getOptimalFontSize.js b/site/assets/cloud/src/getOptimalFontSize.js new file mode 100644 index 00000000..02787516 --- /dev/null +++ b/site/assets/cloud/src/getOptimalFontSize.js @@ -0,0 +1,18 @@ +import {Vector3} from 'three'; + +let objectWorldPosition = new Vector3(); +let cameraWorldPosition = new Vector3(); +let objectWorldScale = new Vector3(); + +export default function(object, renderer, camera) { + if (renderer.domElement.width && renderer.domElement.height && object.material.map.textLines.length) { + let distance = object.getWorldPosition(objectWorldPosition).distanceTo(camera.getWorldPosition(cameraWorldPosition)); + if (distance) { + let heightInPixels = object.getWorldScale(objectWorldScale).y * renderer.domElement.height / distance; + if (heightInPixels) { + return Math.round(heightInPixels / object.material.map.imageHeight); + } + } + } + return 0; +} diff --git a/site/assets/cloud/src/index.js b/site/assets/cloud/src/index.js new file mode 100644 index 00000000..270891d5 --- /dev/null +++ b/site/assets/cloud/src/index.js @@ -0,0 +1,78 @@ +import { + Math as THREE_Math, + Sprite, + SpriteMaterial, +} from 'three'; +import TextTexture from 'three.texttexture'; + +import getOptimalFontSize from './getOptimalFontSize'; + +export default class extends Sprite { + constructor({ + textSize = 1, + redrawInterval = 1, + minFontSize = 0, + maxFontSize = Infinity, + material = {}, + texture = {}, + } = {}) { + super(new SpriteMaterial({ + ...material, + map: new TextTexture(texture), + })); + this.textSize = textSize; + this.redrawInterval = redrawInterval; + this.minFontSize = minFontSize; + this.maxFontSize = maxFontSize; + this.lastRedraw = 0; + } + + get isTextSprite() { + return true; + } + + onBeforeRender(renderer, scene, camera) { + this.redraw(renderer, camera); + } + + updateScale() { + this.scale + .set(this.material.map.imageAspect, 1, 1) + .multiplyScalar(this.textSize * this.material.map.imageHeight); + } + + updateMatrix(...args) { + this.updateScale(); + return super.updateMatrix(...args); + } + + redraw(renderer, camera) { + if (this.lastRedraw + this.redrawInterval < Date.now()) { + if (this.redrawInterval) { + setTimeout(() => { + this.redrawNow(renderer, camera); + }, 1); + } else { + this.redrawNow(renderer, camera); + } + } + } + + redrawNow(renderer, camera) { + this.updateScale(); + this.material.map.autoRedraw = true; + this.material.map.fontSize = THREE_Math.clamp( + THREE_Math.ceilPowerOfTwo( + getOptimalFontSize(this, renderer, camera) + ), + this.minFontSize, + this.maxFontSize, + ); + this.lastRedraw = Date.now(); + } + + dispose() { + this.material.map.dispose(); + this.material.dispose(); + } +} diff --git a/site/assets/css/css.css b/site/assets/css/css.css index 8239cfc7..18959c12 100644 --- a/site/assets/css/css.css +++ b/site/assets/css/css.css @@ -376,11 +376,17 @@ section.fullwidth .image { /* home page */ .hero { - position: relative; width: 100%; - max-width: 1200px; + background: black; + background: linear-gradient(#000,#222); height: 50vw; max-height: 70vh; +} +.hero .inner { + position: relative; + width: 100%; + max-width: 1200px; + height: 100%; display: flex; align-items: center; margin: 0 auto; @@ -393,7 +399,7 @@ section.fullwidth .image { max-height: 70vh; top: 0; right: 0; - z-index: -1; + z-index: 0; text-align: center; } .currentFace { @@ -451,6 +457,9 @@ section.fullwidth .image { .desktop .intro .under a:hover { color: #fff; } +.dataset-intro h2 { + margin-top: 40px; +} /* intro - list of datasets */ diff --git a/site/assets/js/app/face.js b/site/assets/js/app/face.js index f3f1f2bf..1818e9aa 100644 --- a/site/assets/js/app/face.js +++ b/site/assets/js/app/face.js @@ -1,4 +1,5 @@ -var face = (function(){ +/* eslint-disable */ +var faceInit = function () { var container = document.querySelector("#face_container") var camera, controls, scene, renderer var mouse = new THREE.Vector2(0.5, 0.5) @@ -16,6 +17,7 @@ var face = (function(){ return a })() var last_t = 0, start_t = 0 + var bgColor = 0x000000 // 0x191919 var colors = [ 0xff3333, 0xff8833, @@ -32,32 +34,33 @@ var face = (function(){ 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() - }) + .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 w = window.innerWidth * 2/3 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 + camera.position.z = 200 scene = new THREE.Scene() - scene.background = new THREE.Color(0x191919) + // scene.background = new THREE.Color(bgColor) - renderer = new THREE.WebGLRenderer({ antialias: true }) + renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true }) renderer.setPixelRatio(window.devicePixelRatio) renderer.setSize(w, h) + renderer.setClearColor(0x000000, 0); container.appendChild(renderer.domElement) document.body.addEventListener('mousemove', onMouseMove) // renderer.domElement.addEventListener('mousedown', swap) @@ -75,7 +78,7 @@ var face = (function(){ // console.log("done") // } // }) - setInterval(swap, 5000) + swap() } function build(points) { var matrix = new THREE.Matrix4() @@ -125,27 +128,28 @@ var face = (function(){ 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 + swapFrom = swapTo || faces[0] swapTo = faces[swap_count] setCurrentFace(face_names[swap_count]) + oktween.add({ + from: { n: 0 }, + to: { n: 1 }, + duration: 1000, + easing: oktween.easing.quad_in_out, + update: function(obj){ + lerpPoints(obj.n, swapFrom, swapTo, faceBuffer) + updateFace(faceBuffer) + }, + finished: function(){ + setTimeout(swap, 2000) + } + }) } 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) @@ -214,7 +218,6 @@ var face = (function(){ } 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 @@ -224,4 +227,5 @@ var face = (function(){ // scene.rotation.y += 0.01 last_t = t } -})() +} +faceInit() \ No newline at end of file -- cgit v1.2.3-70-g09d2 From aa905ff8a384fbc6f9283bbdabb65bb0ae8bb0dd Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Thu, 17 Jan 2019 15:13:14 +0100 Subject: mv --- site/assets/cloud/.gitignore | 1 - site/assets/cloud/.npmignore | 4 - site/assets/cloud/LICENSE | 21 ---- site/assets/cloud/README.md | 109 ------------------- site/assets/cloud/THREE.TextSprite.js | 1 - site/assets/cloud/demo/script.js | 129 ----------------------- site/assets/cloud/index.html | 31 ------ site/assets/cloud/package.json | 40 ------- site/assets/cloud/rollup.config.js | 25 ----- site/assets/cloud/src/getOptimalFontSize.js | 18 ---- site/assets/cloud/src/index.js | 78 -------------- site/assets/demo/cloud/.gitignore | 1 + site/assets/demo/cloud/.npmignore | 4 + site/assets/demo/cloud/LICENSE | 21 ++++ site/assets/demo/cloud/README.md | 109 +++++++++++++++++++ site/assets/demo/cloud/THREE.TextSprite.js | 1 + site/assets/demo/cloud/demo/script.js | 129 +++++++++++++++++++++++ site/assets/demo/cloud/index.html | 31 ++++++ site/assets/demo/cloud/package.json | 40 +++++++ site/assets/demo/cloud/rollup.config.js | 25 +++++ site/assets/demo/cloud/src/getOptimalFontSize.js | 18 ++++ site/assets/demo/cloud/src/index.js | 78 ++++++++++++++ 22 files changed, 457 insertions(+), 457 deletions(-) delete mode 100644 site/assets/cloud/.gitignore delete mode 100644 site/assets/cloud/.npmignore delete mode 100644 site/assets/cloud/LICENSE delete mode 100644 site/assets/cloud/README.md delete mode 100644 site/assets/cloud/THREE.TextSprite.js delete mode 100644 site/assets/cloud/demo/script.js delete mode 100644 site/assets/cloud/index.html delete mode 100644 site/assets/cloud/package.json delete mode 100644 site/assets/cloud/rollup.config.js delete mode 100644 site/assets/cloud/src/getOptimalFontSize.js delete mode 100644 site/assets/cloud/src/index.js create mode 100644 site/assets/demo/cloud/.gitignore create mode 100644 site/assets/demo/cloud/.npmignore create mode 100644 site/assets/demo/cloud/LICENSE create mode 100644 site/assets/demo/cloud/README.md create mode 100644 site/assets/demo/cloud/THREE.TextSprite.js create mode 100644 site/assets/demo/cloud/demo/script.js create mode 100644 site/assets/demo/cloud/index.html create mode 100644 site/assets/demo/cloud/package.json create mode 100644 site/assets/demo/cloud/rollup.config.js create mode 100644 site/assets/demo/cloud/src/getOptimalFontSize.js create mode 100644 site/assets/demo/cloud/src/index.js (limited to 'site/assets') diff --git a/site/assets/cloud/.gitignore b/site/assets/cloud/.gitignore deleted file mode 100644 index 2ccbe465..00000000 --- a/site/assets/cloud/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/node_modules/ diff --git a/site/assets/cloud/.npmignore b/site/assets/cloud/.npmignore deleted file mode 100644 index dcaf4a28..00000000 --- a/site/assets/cloud/.npmignore +++ /dev/null @@ -1,4 +0,0 @@ -/demo/ -/index.html -/rollup.config.js -/src/ diff --git a/site/assets/cloud/LICENSE b/site/assets/cloud/LICENSE deleted file mode 100644 index edeba37c..00000000 --- a/site/assets/cloud/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2017-2018 Sergej Sintschilin - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/site/assets/cloud/README.md b/site/assets/cloud/README.md deleted file mode 100644 index de6e882e..00000000 --- a/site/assets/cloud/README.md +++ /dev/null @@ -1,109 +0,0 @@ -# THREE.TextSprite - -`class THREE.TextSprite extends THREE.Sprite` - -An instance of `TextSprite` automatically computes the optimal font size depending on the distance to the camera and the size of the renderer canvas. - -## demo - -[Try it out!](https://seregpie.github.io/THREE.TextSprite/) - -## dependencies - -- [THREE.TextTexture](https://github.com/SeregPie/THREE.TextTexture) - -## setup - -### npm - -```shell -npm install three.textsprite -``` - -### ES module - -```javascript -import TextSprite from 'three.textsprite'; -``` - -### browser - -```html - - - -``` - -The class `TextSprite` will be available under the namespace `THREE`. - -## members - -``` -.constructor({ - material, - maxFontSize, - minFontSize, - redrawInterval, - textSize, - texture, -}) -``` - -| argument | description | -| ---: | :--- | -| `material` | The parameters to pass to the constructor of [`SpriteMaterial`](https://threejs.org/docs/index.html#api/materials/SpriteMaterial). | -| `texture` | The parameters to pass to the constructor of [`TextTexture`](https://github.com/SeregPie/THREE.TextTexture). | - -```javascript -let sprite = new THREE.TextSprite({ - material: { - color: 0xffbbff, - fog: true, - }, - redrawInterval: 250, - textSize: 10, - texture: { - text: 'Carpe Diem', - fontFamily: 'Arial, Helvetica, sans-serif', - }, -}); -scene.add(sprite); -``` - ---- - -`.isTextSprite = true` - -Used to check whether this is an instance of `TextSprite`. - -You should not change this, as it is used internally for optimisation. - ---- - -`.textSize = 1` - -The size of the text. - ---- - -`.redrawInterval = 1` - -The minimum time that must elapse before the canvas is redrawn. If 0, the canvas is redrawn immediately whenever `TextSprite` is rendered, otherwise the redrawing is deferred. - ---- - -`.minFontSize = 0` - -The minimum font size. - ---- - -`.maxFontSize = Infinity` - -The maximum font size. - ---- - -`.dispose()` - -Disposes the texture and the material. diff --git a/site/assets/cloud/THREE.TextSprite.js b/site/assets/cloud/THREE.TextSprite.js deleted file mode 100644 index 525d22cd..00000000 --- a/site/assets/cloud/THREE.TextSprite.js +++ /dev/null @@ -1 +0,0 @@ -(function(a,b){"object"==typeof exports&&"undefined"!=typeof module?module.exports=b(require("three"),require("three.texttexture")):"function"==typeof define&&define.amd?define(["three","three.texttexture"],b):(a.THREE=a.THREE||{},a.THREE.TextSprite=b(a.THREE,a.THREE.TextTexture))})(this,function(a,b){"use strict";function c(a,b,c){var g=Math.round;if(b.domElement.width&&b.domElement.height&&a.material.map.textLines.length){var h=a.getWorldPosition(d).distanceTo(c.getWorldPosition(e));if(h){var i=a.getWorldScale(f).y*b.domElement.height/h;if(i)return g(i/a.material.map.imageHeight)}}return 0}b=b&&b.hasOwnProperty("default")?b["default"]:b;var d=new a.Vector3,e=new a.Vector3,f=new a.Vector3,g=function(d){function e(c){void 0===c&&(c={});var e=c.textSize;void 0===e&&(e=1);var f=c.redrawInterval;void 0===f&&(f=1);var g=c.minFontSize;void 0===g&&(g=0);var h=c.maxFontSize;void 0===h&&(h=1/0);var i=c.material;void 0===i&&(i={});var j=c.texture;void 0===j&&(j={}),d.call(this,new a.SpriteMaterial(Object.assign({},i,{map:new b(j)}))),this.textSize=e,this.redrawInterval=f,this.minFontSize=g,this.maxFontSize=h,this.lastRedraw=0}d&&(e.__proto__=d),e.prototype=Object.create(d&&d.prototype),e.prototype.constructor=e;var f={isTextSprite:{configurable:!0}};return f.isTextSprite.get=function(){return!0},e.prototype.onBeforeRender=function(a,b,c){this.redraw(a,c)},e.prototype.updateScale=function(){this.scale.set(this.material.map.imageAspect,1,1).multiplyScalar(this.textSize*this.material.map.imageHeight)},e.prototype.updateMatrix=function(){for(var a=[],b=arguments.length;b--;)a[b]=arguments[b];return this.updateScale(),d.prototype.updateMatrix.apply(this,a)},e.prototype.redraw=function(a,b){var c=this;this.lastRedraw+this.redrawInterval - - - - - THREE.TextSprite - - - - - - - - - - - - diff --git a/site/assets/cloud/package.json b/site/assets/cloud/package.json deleted file mode 100644 index f7556104..00000000 --- a/site/assets/cloud/package.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "name": "three.textsprite", - "version": "18.10.24", - "description": "Automatically computes the optimal font size depending on the distance to the camera and the size of the renderer canvas.", - "keywords": [ - "3d", - "canvas", - "class", - "font", - "group", - "object", - "plugin", - "resolution", - "scale", - "size", - "text", - "texture", - "three" - ], - "license": "MIT", - "author": "Sergej Sintschilin ", - "main": "THREE.TextSprite.js", - "repository": "https://github.com/SeregPie/THREE.TextSprite.git", - "scripts": { - "build": "rollup -c", - "dev": "rollup -c -w", - "prepublishOnly": "npm run build" - }, - "dependencies": { - "three.texttexture": "^18.10.24" - }, - "devDependencies": { - "rollup": "^0.66.6", - "rollup-plugin-babel-minify": "^6.1.1", - "rollup-plugin-buble": "^0.19.4" - }, - "peerDependencies": { - "three": "^0.97.0" - } -} diff --git a/site/assets/cloud/rollup.config.js b/site/assets/cloud/rollup.config.js deleted file mode 100644 index 57415169..00000000 --- a/site/assets/cloud/rollup.config.js +++ /dev/null @@ -1,25 +0,0 @@ -import buble from 'rollup-plugin-buble'; -import minify from 'rollup-plugin-babel-minify'; -import path from 'path'; - -import {main} from './package.json'; - -let globals = { - 'three': 'THREE', - 'three.texttexture': 'THREE.TextTexture', -}; - -export default { - input: 'src/index.js', - external: Object.keys(globals), - output: { - file: main, - format: 'umd', - name: path.basename(main, path.extname(main)), - globals, - }, - plugins: [ - buble({objectAssign: 'Object.assign'}), - minify({comments: false}), - ], -}; diff --git a/site/assets/cloud/src/getOptimalFontSize.js b/site/assets/cloud/src/getOptimalFontSize.js deleted file mode 100644 index 02787516..00000000 --- a/site/assets/cloud/src/getOptimalFontSize.js +++ /dev/null @@ -1,18 +0,0 @@ -import {Vector3} from 'three'; - -let objectWorldPosition = new Vector3(); -let cameraWorldPosition = new Vector3(); -let objectWorldScale = new Vector3(); - -export default function(object, renderer, camera) { - if (renderer.domElement.width && renderer.domElement.height && object.material.map.textLines.length) { - let distance = object.getWorldPosition(objectWorldPosition).distanceTo(camera.getWorldPosition(cameraWorldPosition)); - if (distance) { - let heightInPixels = object.getWorldScale(objectWorldScale).y * renderer.domElement.height / distance; - if (heightInPixels) { - return Math.round(heightInPixels / object.material.map.imageHeight); - } - } - } - return 0; -} diff --git a/site/assets/cloud/src/index.js b/site/assets/cloud/src/index.js deleted file mode 100644 index 270891d5..00000000 --- a/site/assets/cloud/src/index.js +++ /dev/null @@ -1,78 +0,0 @@ -import { - Math as THREE_Math, - Sprite, - SpriteMaterial, -} from 'three'; -import TextTexture from 'three.texttexture'; - -import getOptimalFontSize from './getOptimalFontSize'; - -export default class extends Sprite { - constructor({ - textSize = 1, - redrawInterval = 1, - minFontSize = 0, - maxFontSize = Infinity, - material = {}, - texture = {}, - } = {}) { - super(new SpriteMaterial({ - ...material, - map: new TextTexture(texture), - })); - this.textSize = textSize; - this.redrawInterval = redrawInterval; - this.minFontSize = minFontSize; - this.maxFontSize = maxFontSize; - this.lastRedraw = 0; - } - - get isTextSprite() { - return true; - } - - onBeforeRender(renderer, scene, camera) { - this.redraw(renderer, camera); - } - - updateScale() { - this.scale - .set(this.material.map.imageAspect, 1, 1) - .multiplyScalar(this.textSize * this.material.map.imageHeight); - } - - updateMatrix(...args) { - this.updateScale(); - return super.updateMatrix(...args); - } - - redraw(renderer, camera) { - if (this.lastRedraw + this.redrawInterval < Date.now()) { - if (this.redrawInterval) { - setTimeout(() => { - this.redrawNow(renderer, camera); - }, 1); - } else { - this.redrawNow(renderer, camera); - } - } - } - - redrawNow(renderer, camera) { - this.updateScale(); - this.material.map.autoRedraw = true; - this.material.map.fontSize = THREE_Math.clamp( - THREE_Math.ceilPowerOfTwo( - getOptimalFontSize(this, renderer, camera) - ), - this.minFontSize, - this.maxFontSize, - ); - this.lastRedraw = Date.now(); - } - - dispose() { - this.material.map.dispose(); - this.material.dispose(); - } -} diff --git a/site/assets/demo/cloud/.gitignore b/site/assets/demo/cloud/.gitignore new file mode 100644 index 00000000..2ccbe465 --- /dev/null +++ b/site/assets/demo/cloud/.gitignore @@ -0,0 +1 @@ +/node_modules/ diff --git a/site/assets/demo/cloud/.npmignore b/site/assets/demo/cloud/.npmignore new file mode 100644 index 00000000..dcaf4a28 --- /dev/null +++ b/site/assets/demo/cloud/.npmignore @@ -0,0 +1,4 @@ +/demo/ +/index.html +/rollup.config.js +/src/ diff --git a/site/assets/demo/cloud/LICENSE b/site/assets/demo/cloud/LICENSE new file mode 100644 index 00000000..edeba37c --- /dev/null +++ b/site/assets/demo/cloud/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017-2018 Sergej Sintschilin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/site/assets/demo/cloud/README.md b/site/assets/demo/cloud/README.md new file mode 100644 index 00000000..de6e882e --- /dev/null +++ b/site/assets/demo/cloud/README.md @@ -0,0 +1,109 @@ +# THREE.TextSprite + +`class THREE.TextSprite extends THREE.Sprite` + +An instance of `TextSprite` automatically computes the optimal font size depending on the distance to the camera and the size of the renderer canvas. + +## demo + +[Try it out!](https://seregpie.github.io/THREE.TextSprite/) + +## dependencies + +- [THREE.TextTexture](https://github.com/SeregPie/THREE.TextTexture) + +## setup + +### npm + +```shell +npm install three.textsprite +``` + +### ES module + +```javascript +import TextSprite from 'three.textsprite'; +``` + +### browser + +```html + + + +``` + +The class `TextSprite` will be available under the namespace `THREE`. + +## members + +``` +.constructor({ + material, + maxFontSize, + minFontSize, + redrawInterval, + textSize, + texture, +}) +``` + +| argument | description | +| ---: | :--- | +| `material` | The parameters to pass to the constructor of [`SpriteMaterial`](https://threejs.org/docs/index.html#api/materials/SpriteMaterial). | +| `texture` | The parameters to pass to the constructor of [`TextTexture`](https://github.com/SeregPie/THREE.TextTexture). | + +```javascript +let sprite = new THREE.TextSprite({ + material: { + color: 0xffbbff, + fog: true, + }, + redrawInterval: 250, + textSize: 10, + texture: { + text: 'Carpe Diem', + fontFamily: 'Arial, Helvetica, sans-serif', + }, +}); +scene.add(sprite); +``` + +--- + +`.isTextSprite = true` + +Used to check whether this is an instance of `TextSprite`. + +You should not change this, as it is used internally for optimisation. + +--- + +`.textSize = 1` + +The size of the text. + +--- + +`.redrawInterval = 1` + +The minimum time that must elapse before the canvas is redrawn. If 0, the canvas is redrawn immediately whenever `TextSprite` is rendered, otherwise the redrawing is deferred. + +--- + +`.minFontSize = 0` + +The minimum font size. + +--- + +`.maxFontSize = Infinity` + +The maximum font size. + +--- + +`.dispose()` + +Disposes the texture and the material. diff --git a/site/assets/demo/cloud/THREE.TextSprite.js b/site/assets/demo/cloud/THREE.TextSprite.js new file mode 100644 index 00000000..525d22cd --- /dev/null +++ b/site/assets/demo/cloud/THREE.TextSprite.js @@ -0,0 +1 @@ +(function(a,b){"object"==typeof exports&&"undefined"!=typeof module?module.exports=b(require("three"),require("three.texttexture")):"function"==typeof define&&define.amd?define(["three","three.texttexture"],b):(a.THREE=a.THREE||{},a.THREE.TextSprite=b(a.THREE,a.THREE.TextTexture))})(this,function(a,b){"use strict";function c(a,b,c){var g=Math.round;if(b.domElement.width&&b.domElement.height&&a.material.map.textLines.length){var h=a.getWorldPosition(d).distanceTo(c.getWorldPosition(e));if(h){var i=a.getWorldScale(f).y*b.domElement.height/h;if(i)return g(i/a.material.map.imageHeight)}}return 0}b=b&&b.hasOwnProperty("default")?b["default"]:b;var d=new a.Vector3,e=new a.Vector3,f=new a.Vector3,g=function(d){function e(c){void 0===c&&(c={});var e=c.textSize;void 0===e&&(e=1);var f=c.redrawInterval;void 0===f&&(f=1);var g=c.minFontSize;void 0===g&&(g=0);var h=c.maxFontSize;void 0===h&&(h=1/0);var i=c.material;void 0===i&&(i={});var j=c.texture;void 0===j&&(j={}),d.call(this,new a.SpriteMaterial(Object.assign({},i,{map:new b(j)}))),this.textSize=e,this.redrawInterval=f,this.minFontSize=g,this.maxFontSize=h,this.lastRedraw=0}d&&(e.__proto__=d),e.prototype=Object.create(d&&d.prototype),e.prototype.constructor=e;var f={isTextSprite:{configurable:!0}};return f.isTextSprite.get=function(){return!0},e.prototype.onBeforeRender=function(a,b,c){this.redraw(a,c)},e.prototype.updateScale=function(){this.scale.set(this.material.map.imageAspect,1,1).multiplyScalar(this.textSize*this.material.map.imageHeight)},e.prototype.updateMatrix=function(){for(var a=[],b=arguments.length;b--;)a[b]=arguments[b];return this.updateScale(),d.prototype.updateMatrix.apply(this,a)},e.prototype.redraw=function(a,b){var c=this;this.lastRedraw+this.redrawInterval + + + + + Megapixels Datasets + + + + + + + + + + + + diff --git a/site/assets/demo/cloud/package.json b/site/assets/demo/cloud/package.json new file mode 100644 index 00000000..f7556104 --- /dev/null +++ b/site/assets/demo/cloud/package.json @@ -0,0 +1,40 @@ +{ + "name": "three.textsprite", + "version": "18.10.24", + "description": "Automatically computes the optimal font size depending on the distance to the camera and the size of the renderer canvas.", + "keywords": [ + "3d", + "canvas", + "class", + "font", + "group", + "object", + "plugin", + "resolution", + "scale", + "size", + "text", + "texture", + "three" + ], + "license": "MIT", + "author": "Sergej Sintschilin ", + "main": "THREE.TextSprite.js", + "repository": "https://github.com/SeregPie/THREE.TextSprite.git", + "scripts": { + "build": "rollup -c", + "dev": "rollup -c -w", + "prepublishOnly": "npm run build" + }, + "dependencies": { + "three.texttexture": "^18.10.24" + }, + "devDependencies": { + "rollup": "^0.66.6", + "rollup-plugin-babel-minify": "^6.1.1", + "rollup-plugin-buble": "^0.19.4" + }, + "peerDependencies": { + "three": "^0.97.0" + } +} diff --git a/site/assets/demo/cloud/rollup.config.js b/site/assets/demo/cloud/rollup.config.js new file mode 100644 index 00000000..57415169 --- /dev/null +++ b/site/assets/demo/cloud/rollup.config.js @@ -0,0 +1,25 @@ +import buble from 'rollup-plugin-buble'; +import minify from 'rollup-plugin-babel-minify'; +import path from 'path'; + +import {main} from './package.json'; + +let globals = { + 'three': 'THREE', + 'three.texttexture': 'THREE.TextTexture', +}; + +export default { + input: 'src/index.js', + external: Object.keys(globals), + output: { + file: main, + format: 'umd', + name: path.basename(main, path.extname(main)), + globals, + }, + plugins: [ + buble({objectAssign: 'Object.assign'}), + minify({comments: false}), + ], +}; diff --git a/site/assets/demo/cloud/src/getOptimalFontSize.js b/site/assets/demo/cloud/src/getOptimalFontSize.js new file mode 100644 index 00000000..02787516 --- /dev/null +++ b/site/assets/demo/cloud/src/getOptimalFontSize.js @@ -0,0 +1,18 @@ +import {Vector3} from 'three'; + +let objectWorldPosition = new Vector3(); +let cameraWorldPosition = new Vector3(); +let objectWorldScale = new Vector3(); + +export default function(object, renderer, camera) { + if (renderer.domElement.width && renderer.domElement.height && object.material.map.textLines.length) { + let distance = object.getWorldPosition(objectWorldPosition).distanceTo(camera.getWorldPosition(cameraWorldPosition)); + if (distance) { + let heightInPixels = object.getWorldScale(objectWorldScale).y * renderer.domElement.height / distance; + if (heightInPixels) { + return Math.round(heightInPixels / object.material.map.imageHeight); + } + } + } + return 0; +} diff --git a/site/assets/demo/cloud/src/index.js b/site/assets/demo/cloud/src/index.js new file mode 100644 index 00000000..270891d5 --- /dev/null +++ b/site/assets/demo/cloud/src/index.js @@ -0,0 +1,78 @@ +import { + Math as THREE_Math, + Sprite, + SpriteMaterial, +} from 'three'; +import TextTexture from 'three.texttexture'; + +import getOptimalFontSize from './getOptimalFontSize'; + +export default class extends Sprite { + constructor({ + textSize = 1, + redrawInterval = 1, + minFontSize = 0, + maxFontSize = Infinity, + material = {}, + texture = {}, + } = {}) { + super(new SpriteMaterial({ + ...material, + map: new TextTexture(texture), + })); + this.textSize = textSize; + this.redrawInterval = redrawInterval; + this.minFontSize = minFontSize; + this.maxFontSize = maxFontSize; + this.lastRedraw = 0; + } + + get isTextSprite() { + return true; + } + + onBeforeRender(renderer, scene, camera) { + this.redraw(renderer, camera); + } + + updateScale() { + this.scale + .set(this.material.map.imageAspect, 1, 1) + .multiplyScalar(this.textSize * this.material.map.imageHeight); + } + + updateMatrix(...args) { + this.updateScale(); + return super.updateMatrix(...args); + } + + redraw(renderer, camera) { + if (this.lastRedraw + this.redrawInterval < Date.now()) { + if (this.redrawInterval) { + setTimeout(() => { + this.redrawNow(renderer, camera); + }, 1); + } else { + this.redrawNow(renderer, camera); + } + } + } + + redrawNow(renderer, camera) { + this.updateScale(); + this.material.map.autoRedraw = true; + this.material.map.fontSize = THREE_Math.clamp( + THREE_Math.ceilPowerOfTwo( + getOptimalFontSize(this, renderer, camera) + ), + this.minFontSize, + this.maxFontSize, + ); + this.lastRedraw = Date.now(); + } + + dispose() { + this.material.map.dispose(); + this.material.dispose(); + } +} -- cgit v1.2.3-70-g09d2 From cacd7cc5a9296a192171e8046e12f62c7165f2e9 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Thu, 17 Jan 2019 15:52:15 +0100 Subject: build --- client/faceSearch/faceSearch.query.js | 2 +- client/nameSearch/nameSearch.query.js | 2 +- site/assets/css/css.css | 8 +++++--- site/assets/js/app/face.js | 21 +++++++++++++++++++++ site/public/index.html | 26 +++++++++++++++++++------- site/templates/home.html | 26 +++++++++++++++++++------- 6 files changed, 66 insertions(+), 19 deletions(-) (limited to 'site/assets') diff --git a/client/faceSearch/faceSearch.query.js b/client/faceSearch/faceSearch.query.js index 2d140813..de7e47b6 100644 --- a/client/faceSearch/faceSearch.query.js +++ b/client/faceSearch/faceSearch.query.js @@ -47,7 +47,7 @@ class FaceSearchQuery extends Component {

Search by Image

-

Searching {13456} images

+

Searching {13233} images

{'Use facial recognition to reverse search into the LFW dataset '} {'and see if it contains your photos.'} diff --git a/client/nameSearch/nameSearch.query.js b/client/nameSearch/nameSearch.query.js index 99c1da84..c0798c58 100644 --- a/client/nameSearch/nameSearch.query.js +++ b/client/nameSearch/nameSearch.query.js @@ -20,7 +20,7 @@ class NameSearchQuery extends Component { return (

Search by Name

-

Searching {13456} identities

+

Searching {13233} identities

{'Enter your name to see if you were included in this dataset..'}

diff --git a/site/assets/css/css.css b/site/assets/css/css.css index 18959c12..4689f67b 100644 --- a/site/assets/css/css.css +++ b/site/assets/css/css.css @@ -394,11 +394,11 @@ section.fullwidth .image { #face_container { pointer-events: none; position: absolute; - width: 50vw; + width: 66vw; height: 50vw; max-height: 70vh; top: 0; - right: 0; + right: -16vw; z-index: 0; text-align: center; } @@ -460,7 +460,9 @@ section.fullwidth .image { .dataset-intro h2 { margin-top: 40px; } - +.content .dataset-intro .first_paragraph { + margin-top: 10px; +} /* intro - list of datasets */ .dataset-list { diff --git a/site/assets/js/app/face.js b/site/assets/js/app/face.js index 1818e9aa..ab3d950f 100644 --- a/site/assets/js/app/face.js +++ b/site/assets/js/app/face.js @@ -16,6 +16,7 @@ var faceInit = function () { } return a })() + var lastSprite var last_t = 0, start_t = 0 var bgColor = 0x000000 // 0x191919 var colors = [ @@ -149,6 +150,26 @@ var faceInit = function () { function setCurrentFace(name) { name = name.replace('.png', '').split('_').filter(s => !s.match(/\d+/)).join(' ') currentFace.innerHTML = name + // if (lastSprite) { + // scene.remove(lastSprite) + // } + // var sprite = new THREE.TextSprite({ + // textSize: 12, + // redrawInterval: 1000, + // material: { + // color: 0xcccccc, + // }, + // texture: { + // text: name, + // fontFamily: '"Roboto", "Helvetica", sans-serif', + // }, + // }); + // sprite.position + // .setX(0) + // .setY(0) + // .setZ(0) + // scene.add(sprite); + // lastSprite = sprite } function updateFace(points) { updateCubeGeometry(points) diff --git a/site/public/index.html b/site/public/index.html index a9f16f30..df5121a8 100644 --- a/site/public/index.html +++ b/site/public/index.html @@ -38,7 +38,7 @@
@@ -64,15 +64,24 @@
-

Regular Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

-

Regular Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

-

Regular Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

+

+ MegaPixels is an online art project that explores the history of facial recognition from the perspective of datasets. MegaPixels aims to unravel the meanings behind the data and expose the darker corners of the biometric industry that have contributed to its growth. +

+

+ Through a mix of case studies, visualizations, and interactive tools, Megapixels will use facial recognition datasets to tell the history of modern biometrics. Many people have contributed to the development of facial recignition technology, both wittingly and unwittingly. Not only scientists, but also celebrities and regular internet users have played a part. +

+

+ Facial recognition is a mess of contradictinos. It works, yet it doesn't actually work. It's cheap and accessible, but also expensive and out of control. Facial recognition research has achieved headline grabbing superhuman accuracies over 99.9%, yet in practice it's also dangerously inaccurate. +

+

+ During a trial installation at Sudkreuz station in Berlin in 2018, 20% of the matches were wrong, a number so low that it should not have any connection to law enforcement or justice. And in London, the Metropolitan police had been using facial recognition software that mistakenly identified an alarming 98% of people as criminals, which perhaps is a crime itself. +

-
+

Dataset Portraits

- We have prepared detailed studies of some of the more noteworthy datasets. + We have prepared detailed case studies of some of the more noteworthy datasets, including tools to help you learn what is contained in these datasets, and even whether your own face has been used to train these algorithms.

@@ -110,7 +119,10 @@ - + + + + diff --git a/site/templates/home.html b/site/templates/home.html index 03a61af2..a8695b4e 100644 --- a/site/templates/home.html +++ b/site/templates/home.html @@ -12,7 +12,7 @@
@@ -38,15 +38,24 @@ -

Regular Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

-

Regular Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

-

Regular Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

+

+ MegaPixels is an online art project that explores the history of facial recognition from the perspective of datasets. MegaPixels aims to unravel the meanings behind the data and expose the darker corners of the biometric industry that have contributed to its growth. +

+

+ Through a mix of case studies, visualizations, and interactive tools, Megapixels will use facial recognition datasets to tell the history of modern biometrics. Many people have contributed to the development of facial recignition technology, both wittingly and unwittingly. Not only scientists, but also celebrities and regular internet users have played a part. +

+

+ Facial recognition is a mess of contradictinos. It works, yet it doesn't actually work. It's cheap and accessible, but also expensive and out of control. Facial recognition research has achieved headline grabbing superhuman accuracies over 99.9%, yet in practice it's also dangerously inaccurate. +

+

+ During a trial installation at Sudkreuz station in Berlin in 2018, 20% of the matches were wrong, a number so low that it should not have any connection to law enforcement or justice. And in London, the Metropolitan police had been using facial recognition software that mistakenly identified an alarming 98% of people as criminals, which perhaps is a crime itself. +

-
+

Dataset Portraits

- We have prepared detailed studies of some of the more noteworthy datasets. + We have prepared detailed case studies of some of the more noteworthy datasets, including tools to help you learn what is contained in these datasets, and even whether your own face has been used to train these algorithms.

@@ -63,7 +72,10 @@ {% endblock %} {% block scripts %} - + + + + -- cgit v1.2.3-70-g09d2 From 8580197b2e7b72cfeebeb8483a50908d0601706b Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Thu, 17 Jan 2019 15:53:53 +0100 Subject: load besser --- site/assets/css/applets.css | 3 +++ 1 file changed, 3 insertions(+) (limited to 'site/assets') diff --git a/site/assets/css/applets.css b/site/assets/css/applets.css index 0c566a9f..1b4bd7d2 100644 --- a/site/assets/css/applets.css +++ b/site/assets/css/applets.css @@ -1,3 +1,6 @@ +.applet_container { + min-height: 340px; +} .applet { margin-bottom: 40px; transition: opacity 0.2s cubic-bezier(0,0,1,1); -- cgit v1.2.3-70-g09d2 From 0bbcee858eebc5d659c490f30fb94a9e3c79312f Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Thu, 17 Jan 2019 16:03:05 +0100 Subject: text rotation --- site/assets/css/applets.css | 3 +++ site/assets/css/css.css | 3 +++ site/assets/js/app/face.js | 1 + 3 files changed, 7 insertions(+) (limited to 'site/assets') diff --git a/site/assets/css/applets.css b/site/assets/css/applets.css index 1b4bd7d2..1e57578e 100644 --- a/site/assets/css/applets.css +++ b/site/assets/css/applets.css @@ -57,6 +57,9 @@ .results > div:nth-child(3n+1) { margin-left: 0; } +.applet h2 { + font-size: 20pt; +} .query h2 { margin-top: 0; padding-top: 0; } diff --git a/site/assets/css/css.css b/site/assets/css/css.css index 4689f67b..8b99f740 100644 --- a/site/assets/css/css.css +++ b/site/assets/css/css.css @@ -401,6 +401,8 @@ section.fullwidth .image { right: -16vw; z-index: 0; text-align: center; + perspective: 500px; + perspective-origin: 50% 80%; } .currentFace { position: absolute; @@ -408,6 +410,7 @@ section.fullwidth .image { width: 100%; left: 0; text-align: center; + font-size: 26px; } .intro { max-width: 640px; diff --git a/site/assets/js/app/face.js b/site/assets/js/app/face.js index ab3d950f..0d3ce232 100644 --- a/site/assets/js/app/face.js +++ b/site/assets/js/app/face.js @@ -245,6 +245,7 @@ var faceInit = function () { 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 + currentFace.style.transform = "translateZ(0) rotateY(" + (scene.rotation.y/2) + "rad)" // scene.rotation.y += 0.01 last_t = t } -- cgit v1.2.3-70-g09d2 From f85178189b2675edd967bb4c80acd7be3194fe80 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Thu, 17 Jan 2019 16:07:57 +0100 Subject: better css --- site/assets/css/css.css | 1 + site/assets/js/app/face.js | 1 + 2 files changed, 2 insertions(+) (limited to 'site/assets') diff --git a/site/assets/css/css.css b/site/assets/css/css.css index 8b99f740..50958427 100644 --- a/site/assets/css/css.css +++ b/site/assets/css/css.css @@ -6,6 +6,7 @@ html, body { min-height: 100%; font-family: 'Roboto', sans-serif; color: #b8b8b8; + overflow-x: hidden; } html { background: #191919; diff --git a/site/assets/js/app/face.js b/site/assets/js/app/face.js index 0d3ce232..0a87d2b2 100644 --- a/site/assets/js/app/face.js +++ b/site/assets/js/app/face.js @@ -9,6 +9,7 @@ var faceInit = function () { var SWAP_TIME = 500 var cubes = [], meshes = [] var currentFace = document.querySelector('.currentFace') + var introEl = document.querySelector('.intro') var faceBuffer = (function () { var a = new Array(FACE_POINT_COUNT) for (let i = 0; i < FACE_POINT_COUNT; i++) { -- cgit v1.2.3-70-g09d2 From 270499f33acbc61eb2389bfb923832a851366a37 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Thu, 17 Jan 2019 17:03:49 +0100 Subject: border --- site/assets/css/applets.css | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'site/assets') diff --git a/site/assets/css/applets.css b/site/assets/css/applets.css index 1e57578e..e450b46e 100644 --- a/site/assets/css/applets.css +++ b/site/assets/css/applets.css @@ -31,6 +31,25 @@ /* search results */ +.name_search, .face_search { + box-shadow: inset 0 0 40px #000; + background: #111; + padding: 20px 0; + /*background: black;*/ + width: 100%; +} +.name_search { + margin-top: 0px; + margin-bottom: 20px; +} +.face_search .applet { + max-width: 640px; + margin: 0 auto; +} +.name_search .applet { + max-width: 640px; + margin: 0 auto; +} .results { margin-top: 10px; padding-bottom: 10px; -- cgit v1.2.3-70-g09d2 From 37c1cd8f75e05490067d132f60f7e378809c6b49 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Thu, 17 Jan 2019 17:13:52 +0100 Subject: border --- client/index.js | 2 +- site/assets/css/applets.css | 6 ++++++ site/public/datasets/lfw/index.html | 31 ++----------------------------- 3 files changed, 9 insertions(+), 30 deletions(-) (limited to 'site/assets') diff --git a/client/index.js b/client/index.js index 2c003888..c9335f14 100644 --- a/client/index.js +++ b/client/index.js @@ -36,7 +36,7 @@ function appendApplets(applets) { appendTable(el, payload) break case 'map': - el.parentNode.classList.add('fullwidth') + el.parentNode.classList.add('wide') appendMap(el, payload) el.classList.add('loaded') break diff --git a/site/assets/css/applets.css b/site/assets/css/applets.css index e450b46e..f437d1e8 100644 --- a/site/assets/css/applets.css +++ b/site/assets/css/applets.css @@ -132,6 +132,12 @@ max-width: 40px; } +.map, .map .applet { + height: 500px; +} +.map { + margin-bottom: 20px; +} /* tabulator */ diff --git a/site/public/datasets/lfw/index.html b/site/public/datasets/lfw/index.html index 6526c4f8..057413ae 100644 --- a/site/public/datasets/lfw/index.html +++ b/site/public/datasets/lfw/index.html @@ -66,40 +66,13 @@

According to BiometricUpdate.com [^lfw_pingan], LFW is "the most widely used evaluation set in the field of facial recognition, LFW attracts a few dozen teams from around the globe including Google, Facebook, Microsoft Research Asia, Baidu, Tencent, SenseTime, Face++ and Chinese University of Hong Kong."

According to researchers at the Baidu Research – Institute of Deep Learning "LFW has been the most popular evaluation benchmark for face recognition, and played a very important role in facilitating the face recognition society to improve algorithm. [^lfw_baidu]."

In addition to commercial use as an evaluation tool, alll of the faces in LFW dataset are prepackaged into a popular machine learning code framework called scikit-learn.

- - - - - - - - - - - - - - - - - - - - - - - - -
CompanyCountryIndustries
AratekChinaBiometric sensors for telecom, civil identification, finance, education, POS, and transportation
AratekChinaBiometric sensors for telecom, civil identification, finance, education, POS, and transportation
AratekChinaBiometric sensors for telecom, civil identification, finance, education, POS, and transportation
-

Add 2-4 screenshots of companies mentioning LFW here

 "PING AN Tech facial recognition receives high score in latest LFW test results"
"PING AN Tech facial recognition receives high score in latest LFW test results"
 "Face Recognition Performance in LFW benchmark"
"Face Recognition Performance in LFW benchmark"
 "The 1st place in face verification challenge, LFW"
"The 1st place in face verification challenge, LFW"

In benchmarking, companies use a dataset to evaluate their algorithms which are typically trained on other data. After training, researchers will use LFW as a benchmark to compare results with other algorithms.

For example, Baidu (est. net worth $13B) uses LFW to report results for their "Targeting Ultimate Accuracy: Face Recognition via Deep Embedding". According to the three Baidu researchers who produced the paper:

Citations

-

Overall, LFW has at least 456 citations from 123 countries. Sed ut perspiciatis, unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam eaque ipsa, quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt, explicabo. Nemo enim ipsam voluptatem, quia voluptas sit, aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos.

-

Sed ut perspiciatis, unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam eaque ipsa, quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt, explicabo. Nemo enim ipsam voluptatem, quia voluptas sit, aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos.

-
Distribution of citations per year per country for the top 5 countries with citations for the LFW Dataset
Distribution of citations per year per country for the top 5 countries with citations for the LFW Dataset

Conclusion

+

Overall, LFW has at least 116 citations from 11 countries.

+

Conclusion

The LFW face recognition training and evaluation dataset is a historically important face dataset as it was the first popular dataset to be created entirely from Internet images, paving the way for a global trend towards downloading anyone’s face from the Internet and adding it to a dataset. As will be evident with other datasets, LFW’s approach has now become the norm.

For all the 5,000 people in this datasets, their face is forever a part of facial recognition history. It would be impossible to remove anyone from the dataset because it is so ubiquitous. For their rest of the lives and forever after, these 5,000 people will continue to be used for training facial recognition surveillance.

Code

-- cgit v1.2.3-70-g09d2