From e06d59b3e174a036b6b4f79589781000dfaced6b Mon Sep 17 00:00:00 2001 From: Augustus Yuan Date: Sat, 21 Feb 2026 01:48:20 -0800 Subject: [PATCH 1/3] Refine homepage layout with centered profile and canvas animation --- Gulpfile.js | 143 ---- README.md | 20 +- android-chrome-192x192.png | Bin 5173 -> 0 bytes android-chrome-512x512.png | Bin 18538 -> 0 bytes apple-touch-icon.png | Bin 4555 -> 0 bytes build/css/style.css | 2 - build/css/style.css.map | 1 - build/img/social-icons.svg | 1 - build/js/main.js | 1517 ---------------------------------- build/js/main.min.js | 1 - build/js/quote.js | 94 --- build/js/quote.min.js | 1 - favicon-16x16.png | Bin 362 -> 0 bytes favicon-32x32.png | Bin 646 -> 0 bytes favicon.ico | Bin 15406 -> 0 bytes index.html | 76 +- js/main.js | 368 --------- js/quote.js | 67 -- json/quotes.json | 23 - llms.txt | 25 - package.json | 47 +- postcss.config.js | 6 + public/CNAME | 1 + quotes.html | 17 - sass/mixins/_breakpoint.scss | 10 - sass/modules/_extras.scss | 37 - sass/modules/_header.scss | 63 -- sass/modules/_hero.scss | 126 --- sass/modules/_reset.scss | 22 - sass/style.scss | 14 - site.webmanifest | 1 - src/App.jsx | 101 +++ src/index.css | 106 +++ src/main.jsx | 10 + svg/codepen.svg | 1 - svg/evernote.svg | 1 - svg/github.svg | 1 - svg/jsfiddle.svg | 1 - svg/linkedin.svg | 1 - svg/mail.svg | 1 - svg/stackoverflow.svg | 6 - svg/twitch.svg | 6 - svg/twitter.svg | 1 - tailwind.config.js | 8 + vendor/CanvasRenderer.js | 1094 ------------------------ vendor/Projector.js | 921 --------------------- vendor/stats.min.js | 5 - vite.config.js | 3 + 48 files changed, 279 insertions(+), 4671 deletions(-) delete mode 100644 Gulpfile.js delete mode 100644 android-chrome-192x192.png delete mode 100644 android-chrome-512x512.png delete mode 100644 apple-touch-icon.png delete mode 100644 build/css/style.css delete mode 100644 build/css/style.css.map delete mode 100644 build/img/social-icons.svg delete mode 100644 build/js/main.js delete mode 100644 build/js/main.min.js delete mode 100644 build/js/quote.js delete mode 100644 build/js/quote.min.js delete mode 100644 favicon-16x16.png delete mode 100644 favicon-32x32.png delete mode 100644 favicon.ico delete mode 100644 js/main.js delete mode 100644 js/quote.js delete mode 100644 json/quotes.json delete mode 100644 llms.txt create mode 100644 postcss.config.js create mode 100644 public/CNAME delete mode 100644 quotes.html delete mode 100644 sass/mixins/_breakpoint.scss delete mode 100644 sass/modules/_extras.scss delete mode 100644 sass/modules/_header.scss delete mode 100644 sass/modules/_hero.scss delete mode 100644 sass/modules/_reset.scss delete mode 100644 sass/style.scss delete mode 100644 site.webmanifest create mode 100644 src/App.jsx create mode 100644 src/index.css create mode 100644 src/main.jsx delete mode 100644 svg/codepen.svg delete mode 100644 svg/evernote.svg delete mode 100644 svg/github.svg delete mode 100644 svg/jsfiddle.svg delete mode 100644 svg/linkedin.svg delete mode 100644 svg/mail.svg delete mode 100644 svg/stackoverflow.svg delete mode 100644 svg/twitch.svg delete mode 100644 svg/twitter.svg create mode 100644 tailwind.config.js delete mode 100644 vendor/CanvasRenderer.js delete mode 100644 vendor/Projector.js delete mode 100644 vendor/stats.min.js create mode 100644 vite.config.js diff --git a/Gulpfile.js b/Gulpfile.js deleted file mode 100644 index 7d5b89c..0000000 --- a/Gulpfile.js +++ /dev/null @@ -1,143 +0,0 @@ -var gulp = require('gulp'), - minifyCSS = require('gulp-minify-css'), - sass = require('gulp-sass'), - postcss = require('gulp-postcss'), - browserify = require('gulp-browserify'), - browserSync = require('browser-sync'), - uglify = require('gulp-uglify'), - rename = require('gulp-rename'), - notify = require('gulp-notify'), - replace = require('gulp-replace'), - inject = require('gulp-inject'), - svgstore = require('gulp-svgstore'), - svgmin = require('gulp-svgmin'), - plumber = require('gulp-plumber'), - eslint = require('gulp-eslint'), - jsonlint = require('gulp-jsonlint'), - beep = require('beepbeep'), - colors = require('colors'), - path = require('path'), - sourcemaps = require('gulp-sourcemaps'), - autoprefixer = require('autoprefixer'), - merge = require('merge-stream');; - -// error handling convenience wrapper -gulp.plumbedSrc = function(){ - return gulp.src.apply(gulp, arguments) - .pipe(plumber({ - errorHandler: function(err) { - beep(); - console.log('ERROR:'.bold.red); - console.log(JSON.stringify(err, null, 2).bold.red); - this.emit('end'); - } - })); -}; - -gulp.task('browser-sync', function() { - browserSync({ - server: { - baseDir: './' - }, - host: 'localhost', - port: 8000, - open: false - }); -}); - -gulp.task('sass', function () { - return gulp.plumbedSrc('./sass/**/*.scss') - .pipe(sass()) - .pipe(minifyCSS()) - .pipe(sourcemaps.init()) - .pipe(postcss([autoprefixer({ - browsers: ['last 2 versions'] - } - )])) - .pipe(sourcemaps.write('.')) - .pipe(gulp.dest('./build/css/')) - .pipe(notify({ message: 'CSS complete' })); -}); - -gulp.task('svgstore', function () { - var svgSprite = gulp.plumbedSrc('./svg/*.svg') - .pipe(svgmin(function (file) { - var prefix = path.basename(file.relative, path.extname(file.relative)); - return { - plugins: [{ - cleanupIDs: { - prefix: prefix + '-', - minify: true - } - }] - } - })) - .pipe(rename({prefix: 'svg-'})) - .pipe(svgstore({inlineSvg: true})) - .pipe(rename("social-icons.svg")) - .pipe(gulp.dest('./build/img')); - - return gulp.plumbedSrc('./index.html') - .pipe(inject(svgSprite, { - transform: function(filePath, file) { - return file.contents.toString(); - } - })) - .pipe(gulp.dest('./')); -}); - -gulp.task('scripts', function() { - var mainJS = gulp.plumbedSrc('./js/main.js') - .pipe(browserify()) - .pipe(gulp.dest('./build/js/')) - .pipe(uglify()) - .pipe(rename({ - extname: '.min.js' - })) - .pipe(replace('./build/js/*.min.js')) - .pipe(gulp.dest('./build/js')) - .pipe(notify({ message: 'JS files complete' })); - - var quoteJS = gulp.plumbedSrc('./js/quote.js') - .pipe(browserify()) - .pipe(gulp.dest('./build/js/')) - .pipe(uglify()) - .pipe(rename({ - extname: '.min.js' - })) - .pipe(replace('./build/js/*.min.js')) - .pipe(gulp.dest('./build/js')) - .pipe(notify({ message: 'JS files complete' })); - - return merge(mainJS, quoteJS); -}); - -gulp.task('scripts-watch', ['scripts'], function() { - browserSync.reload(); -}); - -gulp.task('sass-watch', ['sass'], function() { - browserSync.reload(); -}); - -gulp.task('eslint', function() { - return gulp.plumbedSrc('./js/**/*.js') - .pipe(eslint()) - .pipe(eslint.format()) - .pipe(eslint.failAfterError()) - .pipe(notify({ message: 'ESLint complete' })); -}); - -gulp.task('jsonlint', function() { - return gulp.plumbedSrc('./json/**/*.json') - .pipe(jsonlint()) - .pipe(jsonlint.failAfterError()) - .pipe(notify({ message: 'JSONLint complete' })); -}); - -gulp.task('watch', ['browser-sync'], function() { - gulp.watch('./sass/**/*.scss', ['sass-watch']); - gulp.watch('./js/*.js', ['eslint', 'scripts-watch']); -}); - -gulp.task('default', ['watch']); diff --git a/README.md b/README.md index d96abed..2f41f32 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,18 @@ -augbog.github.io -================ +# augustusyuan.com -Icons supplied from [simpleicons](https://simpleicons.org). \ No newline at end of file +Modern personal website rebuilt with React + Vite + Tailwind CSS. + +## Development + +```bash +npm install +npm run dev +``` + +## Production build + +```bash +npm run build +``` + +The custom domain is preserved by committing `CNAME` and copying it from `public/CNAME` into the built output. diff --git a/android-chrome-192x192.png b/android-chrome-192x192.png deleted file mode 100644 index 94126be88f9555df9510cedbc4c3907c24a803fe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5173 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 Oz3t+ZC6yY?t*w?);6Emjd#o7yoG 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 diff --git a/build/css/style.css b/build/css/style.css deleted file mode 100644 index 5d44643..0000000 --- a/build/css/style.css +++ /dev/null @@ -1,2 +0,0 @@ -.hero,header{-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;font-family:"Helvetica Neue",helvetica,arial,sans-serif}.profile,header .profile{border-radius:50%}header{font-weight:200;position:absolute;top:0;width:100%;height:auto;z-index:3}header .header-container{display:-ms-flexbox;display:flex;margin:0 20px}header .left-align{-ms-flex-item-align:start;align-self:flex-start}header .right-align{margin-left:auto}header .secondary-nav{line-height:22px}header .mail-icon{width:15px;height:22px;vertical-align:bottom}header li{display:inline-block;height:auto;margin:0 20px}header li:first-child{margin-left:0}header li:last-child{margin-right:0}.hero{position:relative;overflow:hidden}.hero .content{position:fixed;text-align:center;width:100%;top:50%;left:50%;transform:translate(-50%,-50%);background:rgba(255,255,255,.7);padding:20px 0}.hero .evernote:focus,.hero .evernote:hover,.hero .icon:focus,.hero .icon:hover,.hero .twitch:focus,.hero .twitch:hover{transition:transform .1s ease-out 0s;transform:scale(1.2)}.hero .heading{max-width:80%;margin-left:auto;margin-right:auto;font-size:36px;font-weight:400;letter-spacing:-.5px;margin-bottom:5px}.hero .heading.quote{font-size:26px;max-width:60%}@media only screen and (max-width:600px){header{text-align:center}.hero .heading.quote{font-size:24px;max-width:80%}}.hero .job-title{font-size:20px;font-weight:200;margin-bottom:10px;vertical-align:middle}.hero .description{font-size:20px;font-weight:200;margin:0 0 20px}.hero svg{width:inherit;height:inherit}.hero .icon{display:inline-block;width:20px;height:20px;margin:0 10px}@media only screen and (max-width:600px){.hero .icon{width:30px;height:30px}}.hero .evernote,.hero .twitch{display:inline-block;width:25px;height:25px;vertical-align:bottom}.hero .evernote{fill:#666}.hero .twitch{fill:#9146ff}.hero .twitter{fill:#5EA9DD}.hero .linkedin{fill:#0077B5}.profile{width:100px}.score{font-family:monospace;font-size:30px;font-weight:800}.js-score-hidden{display:none}body,h1,h2{margin:0}ul{padding:0}li{list-style-type:none}a,a:link,a:visited{color:inherit;text-decoration:none;border-bottom:1px solid transparent}.animate-link{border-bottom:.5px solid transparent}.animate-link:hover{cursor:pointer;transition:border-color .5s ease-in 0s;border-color:rgba(0,0,0,.2)}body{transition:all .5s ease-in 0s}@media (prefers-color-scheme:dark){body{color:#fff!important;font-weight:800!important}body .github use,body .mail-icon use{fill:#fff!important}body .content{background:0 0!important}body .description,body .email,body .job-title{font-weight:400!important}} -/*# sourceMappingURL=style.css.map */ diff --git a/build/css/style.css.map b/build/css/style.css.map deleted file mode 100644 index c2a2028..0000000 --- a/build/css/style.css.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["style.css"],"names":[],"mappings":"AAAA,aAAa,mCAAmC,kCAAkC,uDAAuD,CAAC,yBAAyB,iBAAiB,CAAC,OAAO,gBAAgB,kBAAkB,MAAM,WAAW,YAAY,SAAS,CAAC,yBAAyB,oBAAa,AAAb,aAAa,aAAa,CAAC,mBAAmB,0BAAqB,AAArB,qBAAqB,CAAC,oBAAoB,gBAAgB,CAAC,sBAAsB,gBAAgB,CAAC,kBAAkB,WAAW,YAAY,qBAAqB,CAAC,UAAU,qBAAqB,YAAY,aAAa,CAAC,sBAAsB,aAAa,CAAC,qBAAqB,cAAc,CAAC,MAAM,kBAAkB,eAAe,CAAC,eAAe,eAAe,kBAAkB,WAAW,QAAQ,SAAS,+BAA+B,gCAAgC,cAAc,CAAC,wHAAwH,qCAAqC,oBAAoB,CAAC,eAAe,cAAc,iBAAiB,kBAAkB,eAAe,gBAAgB,qBAAqB,iBAAiB,CAAC,qBAAqB,eAAe,aAAa,CAAC,yCAAyC,OAAO,iBAAiB,CAAC,qBAAqB,eAAe,aAAa,CAAC,CAAC,iBAAiB,eAAe,gBAAgB,mBAAmB,qBAAqB,CAAC,mBAAmB,eAAe,gBAAgB,eAAe,CAAC,UAAU,cAAc,cAAc,CAAC,YAAY,qBAAqB,WAAW,YAAY,aAAa,CAAC,yCAAyC,YAAY,WAAW,WAAW,CAAC,CAAC,8BAA8B,qBAAqB,WAAW,YAAY,qBAAqB,CAAC,gBAAgB,SAAS,CAAC,cAAc,YAAY,CAAC,eAAe,YAAY,CAAC,gBAAgB,YAAY,CAAC,SAAS,WAAW,CAAC,OAAO,sBAAsB,eAAe,eAAe,CAAC,iBAAiB,YAAY,CAAC,WAAW,QAAQ,CAAC,GAAG,SAAS,CAAC,GAAG,oBAAoB,CAAC,mBAAmB,cAAc,qBAAqB,mCAAmC,CAAC,cAAc,oCAAoC,CAAC,oBAAoB,eAAe,uCAAuC,2BAA2B,CAAC,KAAK,6BAA6B,CAAC,mCAAmC,KAAK,qBAAqB,yBAAyB,CAAC,qCAAqC,mBAAmB,CAAC,cAAc,wBAAwB,CAAC,8CAA8C,yBAAyB,CAAC,CAAC","file":"style.css","sourcesContent":[".hero,header{-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;font-family:\"Helvetica Neue\",helvetica,arial,sans-serif}.profile,header .profile{border-radius:50%}header{font-weight:200;position:absolute;top:0;width:100%;height:auto;z-index:3}header .header-container{display:flex;margin:0 20px}header .left-align{align-self:flex-start}header .right-align{margin-left:auto}header .secondary-nav{line-height:22px}header .mail-icon{width:15px;height:22px;vertical-align:bottom}header li{display:inline-block;height:auto;margin:0 20px}header li:first-child{margin-left:0}header li:last-child{margin-right:0}.hero{position:relative;overflow:hidden}.hero .content{position:fixed;text-align:center;width:100%;top:50%;left:50%;transform:translate(-50%,-50%);background:rgba(255,255,255,.7);padding:20px 0}.hero .evernote:focus,.hero .evernote:hover,.hero .icon:focus,.hero .icon:hover,.hero .twitch:focus,.hero .twitch:hover{transition:transform .1s ease-out 0s;transform:scale(1.2)}.hero .heading{max-width:80%;margin-left:auto;margin-right:auto;font-size:36px;font-weight:400;letter-spacing:-.5px;margin-bottom:5px}.hero .heading.quote{font-size:26px;max-width:60%}@media only screen and (max-width:600px){header{text-align:center}.hero .heading.quote{font-size:24px;max-width:80%}}.hero .job-title{font-size:20px;font-weight:200;margin-bottom:10px;vertical-align:middle}.hero .description{font-size:20px;font-weight:200;margin:0 0 20px}.hero svg{width:inherit;height:inherit}.hero .icon{display:inline-block;width:20px;height:20px;margin:0 10px}@media only screen and (max-width:600px){.hero .icon{width:30px;height:30px}}.hero .evernote,.hero .twitch{display:inline-block;width:25px;height:25px;vertical-align:bottom}.hero .evernote{fill:#666}.hero .twitch{fill:#9146ff}.hero .twitter{fill:#5EA9DD}.hero .linkedin{fill:#0077B5}.profile{width:100px}.score{font-family:monospace;font-size:30px;font-weight:800}.js-score-hidden{display:none}body,h1,h2{margin:0}ul{padding:0}li{list-style-type:none}a,a:link,a:visited{color:inherit;text-decoration:none;border-bottom:1px solid transparent}.animate-link{border-bottom:.5px solid transparent}.animate-link:hover{cursor:pointer;transition:border-color .5s ease-in 0s;border-color:rgba(0,0,0,.2)}body{transition:all .5s ease-in 0s}@media (prefers-color-scheme:dark){body{color:#fff!important;font-weight:800!important}body .github use,body .mail-icon use{fill:#fff!important}body .content{background:0 0!important}body .description,body .email,body .job-title{font-weight:400!important}}"]} \ No newline at end of file diff --git a/build/img/social-icons.svg b/build/img/social-icons.svg deleted file mode 100644 index c3745de..0000000 --- a/build/img/social-icons.svg +++ /dev/null @@ -1 +0,0 @@ -Evernote iconTwitch icon \ No newline at end of file diff --git a/build/js/main.js b/build/js/main.js deleted file mode 100644 index 43dbe6f..0000000 --- a/build/js/main.js +++ /dev/null @@ -1,1517 +0,0 @@ -(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o= 600 ? 5 : 10; - var NUM_OF_CUBES = window.innerWidth >= 600 ? 1000 : 250; - var SATISFIABLE_CUBE_SCORE = 15; - var filterCoordinates = []; - var pivot = new THREE.Group(); - var themeIndex = 0; - - var darkModeMedia = window.matchMedia('(prefers-color-scheme: dark)'); - - var cubeScore = 0; - var lineMaterial = new THREE.LineBasicMaterial({ - color: 0xffffff, - linewidth: 2 - }); - - var pivotInterval, pivotTimeout; - - var socialThemes = { - "twitter": ["#1DA1F2", "#14171A", "#657786", "#AAB8C2"], - "twitch": ["#9146ff"], - "github": ["#333", "#6e5494", "#c6e48b", "#7bc96f", "#239a3b", "#196127"], - "evernote": ['#00A82D'], - "stackoverflow": ["#f48024", "#222426", "#bcbbbb"], - "linkedin": ["#0077B5", "#00A0DC", "#313335", "#86888A"] - } - - var themes = [ - ["#042A2B", "#5EB1BF", "#CDEDF6", "#EF7B45", "#D84727"], - ["#E3E7D3", "#BDC2BF", "#989C94", "#25291C", "#E6E49F"], - ["#EAF2E3", "#61E8E1", "#F25757", "F2E863", "F2CD60"], - ['#E28413', '#F56416', '#DD4B1A', '#EF271B', '#EA1744'], - ['#86583E', '#AF2A42', '#61643F', '#AFBE96', '#F0EEE1'], - ['#D44A98', '#60B9CB', '#FFFB53'], //cmyk - ]; - - init(); - animate(); - document.getElementById("hero").appendChild(renderer.domElement); - var keepScoreElement = document.getElementsByClassName('js-increment')[0]; - - if (window.innerWidth >= 600) { - var themeHoversItemContainer = document.getElementsByClassName('content')[0]; - themeHoversItemContainer.addEventListener('mouseover', function(e) { - if (e.target && e.target.getAttribute('data-brand')) { - themifyCubes(socialThemes[e.target.getAttribute('data-brand')]); - } - }); - } - - function init() { - camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 10000 ); - camera.position.y = 300; - camera.position.z = window.innerWidth >= 600 ? 500 : 200; - - scene = new THREE.Scene(); - scene.add(pivot); - - raycaster = new THREE.Raycaster(); - mouse = new THREE.Vector2(); - - renderer = new THREE.WebGLRenderer(); - renderer.setClearColor(darkModeMedia.matches ? "black" : "white"); - renderer.setPixelRatio( window.devicePixelRatio ); - renderer.setSize( window.innerWidth, window.innerHeight ); - - var geometry = new THREE.BoxGeometry( CUBE_SIZE, CUBE_SIZE, CUBE_SIZE ); - geometry.colorsNeedUpdate = true; - - for (var i = 0; i < NUM_OF_CUBES; i++) { - var randomColor = Math.random() * 0xffffff; - // generate random coordinates that are not already occupied yet - var coordinates = generateRandomCoords(filterCoordinates); - objects[i] = new THREE.Mesh( geometry, new THREE.MeshBasicMaterial( { color: new THREE.Color(randomColor), opacity: 0.6, transparent: true, depthWrite: false } ) ); - objects[i].position.set(coordinates.x, coordinates.y, coordinates.z); - - // add to filter so we do not generate conflicting coordinates again - filterCoordinates.push(coordinates); - - // modify rotation - objects[i].rotation.x = Math.random() * 2 * Math.PI; - objects[i].rotation.y = Math.random() * 2 * Math.PI; - pivot.add( objects[i] ); - - var edges = new THREE.EdgesGeometry( geometry ); - var line = new THREE.LineSegments(edges, lineMaterial); - objects[i].add(line); - } - - document.addEventListener( 'keyup', onKeyUp, false ); - document.addEventListener('mousemove', onDocumentMouseMove, false); - - if (window.DeviceOrientationEvent) { - window.addEventListener( 'deviceorientation', onDeviceOrientation, false ); - } - window.addEventListener( 'resize', onWindowResize, false ); - - // Detect dark mode only supported in Safari 12.1 - if (darkModeMedia.matches) { - setColorScheme({ darkMode: true, shouldTransition: false }); - } - darkModeMedia.addListener(function(e) { - var colorSchemeOptions = { - darkMode: darkModeMedia.matches, - shouldTransition: true, - } - setColorScheme(colorSchemeOptions); - //darkModeMedia.matches ? darkMode() : lightMode(); - }); - - if (window.innerWidth > 600 || !window.DeviceOrientationEvent) { - if (pivotInterval) { - clearInterval(pivotInterval); - } - if (pivotTimeout) { - clearTimeout(pivotTimeout); - } - // set time shift - pivotInterval = setInterval(function() { - PIVOT_SPEED = 0.2; - var pivotTimeout = setTimeout(function() { - PIVOT_SPEED = 0.02; - }, 750) - }, 12000); - } - } - - function onWindowResize() { - if (pivotInterval) { - clearInterval(pivotInterval); - } - if (pivotTimeout) { - clearTimeout(pivotTimeout); - } - - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize( window.innerWidth, window.innerHeight ); - renderer.render( scene, camera ); - } - - function onKeyUp(e) { - themeIndex = (themeIndex + 1) % themes.length; - if (e.key.includes('Arrow')) { - themifyCubes(themes[themeIndex]); - } - } - - function onDeviceOrientation( event ) { - // set camera to change its view based on gyroscope - // NOTE: adding 100 to beta starts the phone as if it were vertical - var vectorAngle = new THREE.Vector3( - RADIUS * Math.sin(THREE.Math.degToRad( event.alpha ))*-1, - RADIUS * Math.sin(THREE.Math.degToRad( event.beta + 100 ))*-1, - scene.position.z - ) - camera.lookAt(vectorAngle); - - raycaster.setFromCamera( mouse, camera ); - renderer.render( scene, camera ); - } - - function onDocumentMouseMove(event) { - event.preventDefault(); - mouse.x = event.clientX / window.innerWidth * 2 - 1; - mouse.y = -(event.clientY / window.innerHeight) * 2 + 1; - - // if user hovers over specific cube, TWEEN scale to make it pop - raycaster.setFromCamera(mouse, camera); - var intersects = raycaster.intersectObjects(objects); - - // check we have intersects and that the uuid of the object is not already tweening - if (intersects.length > 0) { - if (!INTERSECTED[intersects[0].object.uuid]) { - INTERSECTED[intersects[0].object.uuid] = intersects[0].object; - var scaleTween = new TWEEN.Tween(intersects[0].object.scale) - .to({ x: 3, y: 3, z: 3 }, 500) - .easing(TWEEN.Easing.Elastic.Out); - var rotationTween = new TWEEN.Tween(intersects[0].object.rotation) - .to({ x: Math.random(), y: Math.random(), z: Math.random() }, 500) - .easing(TWEEN.Easing.Elastic.Out) - var shrinkTween = new TWEEN.Tween(intersects[0].object.scale) - .to({ x: 1, y: 1, z: 1 }, 500) - .delay(1000) - .easing(TWEEN.Easing.Elastic.Out) - .onComplete(function(tween) { - var uuid = Object.keys(INTERSECTED).shift(); - delete INTERSECTED[uuid]; - }); - scaleTween.chain(shrinkTween).start(); - rotationTween.start(); - incrementScore(); - } - } - } - - function animate() { - requestAnimationFrame( animate ); - TWEEN.update(); - render(); - } - - function render() { - // in order to prevent the theta from forever growing which could hit Number.MAX_SAFE_INTEGER, - // go reverse and interchange - if (multiplier > 0 && theta >= 100) { - multiplier = -1; - } else if (multiplier < 0 && theta <= 0) { - multiplier = 1; - } - theta += PIVOT_SPEED * multiplier; - - pivot.rotation.set( - Math.sin( THREE.Math.degToRad( theta )), - Math.sin( THREE.Math.degToRad( theta )), - Math.sin( THREE.Math.degToRad( theta )) - ); - - raycaster.setFromCamera( mouse, camera ); - renderer.render( scene, camera ); - } - - // generate random coordinates based on page and size of cubes - // TODO: handle filtering of coordinates - function generateRandomCoords(filterCoordinates) { - var coords = { - x: (Math.random() * 800 - 200), - y: (Math.random() * 800 - 200), - z: (Math.random() * 800 - 200) - }; - - return coords; - } - - // takes in an array of hex colors and applies the theme equally to the cubes - function themifyCubes(theme) { - if (!theme) { - for (var i = 0; i < objects.length; i++) { - var randomColor = Math.random() * 0xffffff; - objects[i].material.color.set(new THREE.Color(randomColor)); - } - } else { - for (var i = 0; i < objects.length; i++) { - var hexColor = parseInt(theme[i % theme.length].replace("#", "0x"), 16); - objects[i].material.color.set(new THREE.Color(hexColor)); - } - } - } - - /** - * Sets the color scheme - * options: { darkMode: boolean, shouldTransition: boolean } - */ - function setColorScheme(options) { - var whiteClearColor = new THREE.Color("white"); - var darkClearColor = new THREE.Color("black"); - var firstClearColor = options.darkMode ? whiteClearColor : darkClearColor; - var transitionedClearColor = options.darkMode ? darkClearColor : whiteClearColor; - if (options.shouldTransition) { - var colorModeTween = new TWEEN.Tween(firstClearColor) - .to(transitionedClearColor, 500).onUpdate(function() { - renderer.setClearColor(firstClearColor); - }).start(); - } else { - renderer.setClearColor(transitionedClearColor); - } - if (options.darkMode) { - document.body.classList.add("dark-mode"); - } else { - document.body.classList.remove("dark-mode"); - } - lineMaterial = new THREE.LineBasicMaterial({ - color: options.darkMode ? 0x000000 : 0xffffff, - linewidth: 2 - }); - var geometry = new THREE.BoxGeometry( CUBE_SIZE, CUBE_SIZE, CUBE_SIZE ); - geometry.colorsNeedUpdate = true; - var edges = new THREE.EdgesGeometry( geometry ); - for (var i = 0; i < objects.length; i++) { - var line = new THREE.LineSegments(edges, lineMaterial); - objects[i].add(line); - } - render(); - } - - // flicker cubes through all the themes twice! :) - function flickerCubes() { - var ran = false; - var i = 0; - var index = 0; - while (i++ < themes.length) { - var theme = themes[i]; - if (i === themes.length - 1 && !ran) { - ran = true; - i = 0; - } else if (i === themes.length - 1) { - theme = false; - } - (function(i) { - setTimeout(function() { - themifyCubes(theme); - }, index++ * 200); - })(i); - } - } - - // Handy function to handle logarithmic function - function getBaseLog(x, y) { - return Math.log(y) / Math.log(x); - } - - // Blow up all the cubes in logarithmic fashion so as time goes on, we blow up more - function blowUpCubes() { - var shrinkTweens = []; - for (var i = 0; i < objects.length; i+=2) { - var delay = Math.floor(getBaseLog(2, i) * 200); - var scaleTween = new TWEEN.Tween(objects[i].scale) - .delay(delay) - .to({ x: 3, y: 3, z: 3 }, 500) - .easing(TWEEN.Easing.Elastic.Out).onComplete(function() { - shrinkTween.start(); - }); - var rotationTween = new TWEEN.Tween(objects[i].rotation) - .delay(delay) - .to({ x: Math.random(), y: Math.random(), z: Math.random() }, 500) - .easing(TWEEN.Easing.Elastic.Out) - var shrinkTween = new TWEEN.Tween(objects[i].scale) - .delay(Math.floor(getBaseLog(2, Math.floor(objects.length / 2)) * 200)) - .to({ x: 1, y: 1, z: 1 }, 500) - .easing(TWEEN.Easing.Elastic.Out); - scaleTween.chain(shrinkTween).start(); - rotationTween.start(); - } - } - - function incrementScore() { - cubeScore++; - keepScoreElement.innerText = cubeScore; - if (cubeScore >= SATISFIABLE_CUBE_SCORE && document.getElementsByClassName('js-score-hidden').length > 0) { - document.getElementsByClassName('js-score-hidden')[0].classList.remove('js-score-hidden'); - } else if (cubeScore % 100 === 0) { - flickerCubes(); - } - } -})(); - -},{"./quote.js":2,"@tweenjs/tween.js":4,"konami-komando":5}],2:[function(require,module,exports){ -(function() { - var quotes = require('../json/quotes.json'); - var quoteTrigger = document.getElementById('quotes'); - - String.prototype.typeout = function(targetElem) { - var timer; - var str = this.split(''); - var strCopy = str.slice(0); - clearTimeout(timer); - var ll = ''; - (function shuffle(start){ - // This code is run options.fps times per second - // and updates the contents of the page element - var i, len = strCopy.length; - if(start>=len){ - return targetElem.innerHTML = str.join('').toString();// you can use your selectors - } - ll = ll + strCopy[start]; - targetElem.innerHTML = ll; // you can use your selectors - timer = setTimeout(function(){ - shuffle(start+1); - }, 50); - })(0); - } - - function triggerQuoteAnimation() { - var heading = document.getElementsByClassName('heading')[0]; - var description = document.getElementsByClassName('description')[0]; - var jobTitle = document.getElementsByClassName("job-title")[0]; - heading.className = 'heading quote'; - description.className = 'description author'; - jobTitle.style.display = 'none'; - - var oHeading = heading.innerText; - var oDescription = description.innerText; - for (var i=0; i<=quotes.length; i++) { - (function(i) { - if (i == quotes.length) { - setTimeout(function(e) { - heading.className = 'heading'; - description.className = 'description'; - description.innerHTML = ''; - oHeading.typeout(heading); - }, 10000*i); - setTimeout(function(e) { - oDescription.typeout(description); - jobTitle.style = ''; - }, 10000*i+2000); - quoteTrigger.removeEventListener('click', triggerQuoteAnimation); - } else { - var quote = new String(quotes[i].quote); - var author = new String(quotes[i].author); - setTimeout(function(e) { - var moddedQuote = '“' + quote + '”'; - moddedQuote.typeout(heading); - description.innerHTML = ''; - }, 10000*i); - setTimeout(function(e) { - author.typeout(description); - }, 10000*i+2000); - } - })(i); - } - } - - quoteTrigger.addEventListener('click', triggerQuoteAnimation); -})(); -},{"../json/quotes.json":3}],3:[function(require,module,exports){ -module.exports=[ - { - "quote" : "Fairy tales are more than true — not because they tell us dragons exist, but because they tell us dragons can be beaten.", - "author": "G. K. Chesterton" - }, - { - "quote" : "Don't go through life, grow through life.", - "author": "Eric Butterworth" - }, - { - "quote" : "Wisdom is knowing what to do next, skill is knowing how to do it, and virtue is doing it.", - "author": "David Starr Jordan" - }, - { - "quote": "Never doubt that a small group of thoughtful, committed, citizens can change the world. Indeed, it is the only thing that ever has.", - "author": "Margaret Mead" - }, - { - "quote": "When we speak we are afraid our words will not be heard or welcomed. But when we are silent, we are still afraid. So it is better to speak.", - "author": "Audre Lorde" - } -] - - -},{}],4:[function(require,module,exports){ -(function (process){ -/** - * Tween.js - Licensed under the MIT license - * https://github.com/tweenjs/tween.js - * ---------------------------------------------- - * - * See https://github.com/tweenjs/tween.js/graphs/contributors for the full list of contributors. - * Thank you all, you're awesome! - */ - - -var _Group = function () { - this._tweens = {}; - this._tweensAddedDuringUpdate = {}; -}; - -_Group.prototype = { - getAll: function () { - - return Object.keys(this._tweens).map(function (tweenId) { - return this._tweens[tweenId]; - }.bind(this)); - - }, - - removeAll: function () { - - this._tweens = {}; - - }, - - add: function (tween) { - - this._tweens[tween.getId()] = tween; - this._tweensAddedDuringUpdate[tween.getId()] = tween; - - }, - - remove: function (tween) { - - delete this._tweens[tween.getId()]; - delete this._tweensAddedDuringUpdate[tween.getId()]; - - }, - - update: function (time, preserve) { - - var tweenIds = Object.keys(this._tweens); - - if (tweenIds.length === 0) { - return false; - } - - time = time !== undefined ? time : TWEEN.now(); - - // Tweens are updated in "batches". If you add a new tween during an update, then the - // new tween will be updated in the next batch. - // If you remove a tween during an update, it may or may not be updated. However, - // if the removed tween was added during the current batch, then it will not be updated. - while (tweenIds.length > 0) { - this._tweensAddedDuringUpdate = {}; - - for (var i = 0; i < tweenIds.length; i++) { - - var tween = this._tweens[tweenIds[i]]; - - if (tween && tween.update(time) === false) { - tween._isPlaying = false; - - if (!preserve) { - delete this._tweens[tweenIds[i]]; - } - } - } - - tweenIds = Object.keys(this._tweensAddedDuringUpdate); - } - - return true; - - } -}; - -var TWEEN = new _Group(); - -TWEEN.Group = _Group; -TWEEN._nextId = 0; -TWEEN.nextId = function () { - return TWEEN._nextId++; -}; - - -// Include a performance.now polyfill. -// In node.js, use process.hrtime. -if (typeof (self) === 'undefined' && typeof (process) !== 'undefined' && process.hrtime) { - TWEEN.now = function () { - var time = process.hrtime(); - - // Convert [seconds, nanoseconds] to milliseconds. - return time[0] * 1000 + time[1] / 1000000; - }; -} -// In a browser, use self.performance.now if it is available. -else if (typeof (self) !== 'undefined' && - self.performance !== undefined && - self.performance.now !== undefined) { - // This must be bound, because directly assigning this function - // leads to an invocation exception in Chrome. - TWEEN.now = self.performance.now.bind(self.performance); -} -// Use Date.now if it is available. -else if (Date.now !== undefined) { - TWEEN.now = Date.now; -} -// Otherwise, use 'new Date().getTime()'. -else { - TWEEN.now = function () { - return new Date().getTime(); - }; -} - - -TWEEN.Tween = function (object, group) { - this._object = object; - this._valuesStart = {}; - this._valuesEnd = {}; - this._valuesStartRepeat = {}; - this._duration = 1000; - this._repeat = 0; - this._repeatDelayTime = undefined; - this._yoyo = false; - this._isPlaying = false; - this._reversed = false; - this._delayTime = 0; - this._startTime = null; - this._easingFunction = TWEEN.Easing.Linear.None; - this._interpolationFunction = TWEEN.Interpolation.Linear; - this._chainedTweens = []; - this._onStartCallback = null; - this._onStartCallbackFired = false; - this._onUpdateCallback = null; - this._onRepeatCallback = null; - this._onCompleteCallback = null; - this._onStopCallback = null; - this._group = group || TWEEN; - this._id = TWEEN.nextId(); - -}; - -TWEEN.Tween.prototype = { - getId: function () { - return this._id; - }, - - isPlaying: function () { - return this._isPlaying; - }, - - to: function (properties, duration) { - - this._valuesEnd = Object.create(properties); - - if (duration !== undefined) { - this._duration = duration; - } - - return this; - - }, - - duration: function duration(d) { - this._duration = d; - return this; - }, - - start: function (time) { - - this._group.add(this); - - this._isPlaying = true; - - this._onStartCallbackFired = false; - - this._startTime = time !== undefined ? typeof time === 'string' ? TWEEN.now() + parseFloat(time) : time : TWEEN.now(); - this._startTime += this._delayTime; - - for (var property in this._valuesEnd) { - - // Check if an Array was provided as property value - if (this._valuesEnd[property] instanceof Array) { - - if (this._valuesEnd[property].length === 0) { - continue; - } - - // Create a local copy of the Array with the start value at the front - this._valuesEnd[property] = [this._object[property]].concat(this._valuesEnd[property]); - - } - - // If `to()` specifies a property that doesn't exist in the source object, - // we should not set that property in the object - if (this._object[property] === undefined) { - continue; - } - - // Save the starting value. - this._valuesStart[property] = this._object[property]; - - if ((this._valuesStart[property] instanceof Array) === false) { - this._valuesStart[property] *= 1.0; // Ensures we're using numbers, not strings - } - - this._valuesStartRepeat[property] = this._valuesStart[property] || 0; - - } - - return this; - - }, - - stop: function () { - - if (!this._isPlaying) { - return this; - } - - this._group.remove(this); - this._isPlaying = false; - - if (this._onStopCallback !== null) { - this._onStopCallback(this._object); - } - - this.stopChainedTweens(); - return this; - - }, - - end: function () { - - this.update(Infinity); - return this; - - }, - - stopChainedTweens: function () { - - for (var i = 0, numChainedTweens = this._chainedTweens.length; i < numChainedTweens; i++) { - this._chainedTweens[i].stop(); - } - - }, - - group: function (group) { - this._group = group; - return this; - }, - - delay: function (amount) { - - this._delayTime = amount; - return this; - - }, - - repeat: function (times) { - - this._repeat = times; - return this; - - }, - - repeatDelay: function (amount) { - - this._repeatDelayTime = amount; - return this; - - }, - - yoyo: function (yoyo) { - - this._yoyo = yoyo; - return this; - - }, - - easing: function (easingFunction) { - - this._easingFunction = easingFunction; - return this; - - }, - - interpolation: function (interpolationFunction) { - - this._interpolationFunction = interpolationFunction; - return this; - - }, - - chain: function () { - - this._chainedTweens = arguments; - return this; - - }, - - onStart: function (callback) { - - this._onStartCallback = callback; - return this; - - }, - - onUpdate: function (callback) { - - this._onUpdateCallback = callback; - return this; - - }, - - onRepeat: function onRepeat(callback) { - - this._onRepeatCallback = callback; - return this; - - }, - - onComplete: function (callback) { - - this._onCompleteCallback = callback; - return this; - - }, - - onStop: function (callback) { - - this._onStopCallback = callback; - return this; - - }, - - update: function (time) { - - var property; - var elapsed; - var value; - - if (time < this._startTime) { - return true; - } - - if (this._onStartCallbackFired === false) { - - if (this._onStartCallback !== null) { - this._onStartCallback(this._object); - } - - this._onStartCallbackFired = true; - } - - elapsed = (time - this._startTime) / this._duration; - elapsed = (this._duration === 0 || elapsed > 1) ? 1 : elapsed; - - value = this._easingFunction(elapsed); - - for (property in this._valuesEnd) { - - // Don't update properties that do not exist in the source object - if (this._valuesStart[property] === undefined) { - continue; - } - - var start = this._valuesStart[property] || 0; - var end = this._valuesEnd[property]; - - if (end instanceof Array) { - - this._object[property] = this._interpolationFunction(end, value); - - } else { - - // Parses relative end values with start as base (e.g.: +10, -3) - if (typeof (end) === 'string') { - - if (end.charAt(0) === '+' || end.charAt(0) === '-') { - end = start + parseFloat(end); - } else { - end = parseFloat(end); - } - } - - // Protect against non numeric properties. - if (typeof (end) === 'number') { - this._object[property] = start + (end - start) * value; - } - - } - - } - - if (this._onUpdateCallback !== null) { - this._onUpdateCallback(this._object, elapsed); - } - - if (elapsed === 1) { - - if (this._repeat > 0) { - - if (isFinite(this._repeat)) { - this._repeat--; - } - - // Reassign starting values, restart by making startTime = now - for (property in this._valuesStartRepeat) { - - if (typeof (this._valuesEnd[property]) === 'string') { - this._valuesStartRepeat[property] = this._valuesStartRepeat[property] + parseFloat(this._valuesEnd[property]); - } - - if (this._yoyo) { - var tmp = this._valuesStartRepeat[property]; - - this._valuesStartRepeat[property] = this._valuesEnd[property]; - this._valuesEnd[property] = tmp; - } - - this._valuesStart[property] = this._valuesStartRepeat[property]; - - } - - if (this._yoyo) { - this._reversed = !this._reversed; - } - - if (this._repeatDelayTime !== undefined) { - this._startTime = time + this._repeatDelayTime; - } else { - this._startTime = time + this._delayTime; - } - - if (this._onRepeatCallback !== null) { - this._onRepeatCallback(this._object); - } - - return true; - - } else { - - if (this._onCompleteCallback !== null) { - - this._onCompleteCallback(this._object); - } - - for (var i = 0, numChainedTweens = this._chainedTweens.length; i < numChainedTweens; i++) { - // Make the chained tweens start exactly at the time they should, - // even if the `update()` method was called way past the duration of the tween - this._chainedTweens[i].start(this._startTime + this._duration); - } - - return false; - - } - - } - - return true; - - } -}; - - -TWEEN.Easing = { - - Linear: { - - None: function (k) { - - return k; - - } - - }, - - Quadratic: { - - In: function (k) { - - return k * k; - - }, - - Out: function (k) { - - return k * (2 - k); - - }, - - InOut: function (k) { - - if ((k *= 2) < 1) { - return 0.5 * k * k; - } - - return - 0.5 * (--k * (k - 2) - 1); - - } - - }, - - Cubic: { - - In: function (k) { - - return k * k * k; - - }, - - Out: function (k) { - - return --k * k * k + 1; - - }, - - InOut: function (k) { - - if ((k *= 2) < 1) { - return 0.5 * k * k * k; - } - - return 0.5 * ((k -= 2) * k * k + 2); - - } - - }, - - Quartic: { - - In: function (k) { - - return k * k * k * k; - - }, - - Out: function (k) { - - return 1 - (--k * k * k * k); - - }, - - InOut: function (k) { - - if ((k *= 2) < 1) { - return 0.5 * k * k * k * k; - } - - return - 0.5 * ((k -= 2) * k * k * k - 2); - - } - - }, - - Quintic: { - - In: function (k) { - - return k * k * k * k * k; - - }, - - Out: function (k) { - - return --k * k * k * k * k + 1; - - }, - - InOut: function (k) { - - if ((k *= 2) < 1) { - return 0.5 * k * k * k * k * k; - } - - return 0.5 * ((k -= 2) * k * k * k * k + 2); - - } - - }, - - Sinusoidal: { - - In: function (k) { - - return 1 - Math.cos(k * Math.PI / 2); - - }, - - Out: function (k) { - - return Math.sin(k * Math.PI / 2); - - }, - - InOut: function (k) { - - return 0.5 * (1 - Math.cos(Math.PI * k)); - - } - - }, - - Exponential: { - - In: function (k) { - - return k === 0 ? 0 : Math.pow(1024, k - 1); - - }, - - Out: function (k) { - - return k === 1 ? 1 : 1 - Math.pow(2, - 10 * k); - - }, - - InOut: function (k) { - - if (k === 0) { - return 0; - } - - if (k === 1) { - return 1; - } - - if ((k *= 2) < 1) { - return 0.5 * Math.pow(1024, k - 1); - } - - return 0.5 * (- Math.pow(2, - 10 * (k - 1)) + 2); - - } - - }, - - Circular: { - - In: function (k) { - - return 1 - Math.sqrt(1 - k * k); - - }, - - Out: function (k) { - - return Math.sqrt(1 - (--k * k)); - - }, - - InOut: function (k) { - - if ((k *= 2) < 1) { - return - 0.5 * (Math.sqrt(1 - k * k) - 1); - } - - return 0.5 * (Math.sqrt(1 - (k -= 2) * k) + 1); - - } - - }, - - Elastic: { - - In: function (k) { - - if (k === 0) { - return 0; - } - - if (k === 1) { - return 1; - } - - return -Math.pow(2, 10 * (k - 1)) * Math.sin((k - 1.1) * 5 * Math.PI); - - }, - - Out: function (k) { - - if (k === 0) { - return 0; - } - - if (k === 1) { - return 1; - } - - return Math.pow(2, -10 * k) * Math.sin((k - 0.1) * 5 * Math.PI) + 1; - - }, - - InOut: function (k) { - - if (k === 0) { - return 0; - } - - if (k === 1) { - return 1; - } - - k *= 2; - - if (k < 1) { - return -0.5 * Math.pow(2, 10 * (k - 1)) * Math.sin((k - 1.1) * 5 * Math.PI); - } - - return 0.5 * Math.pow(2, -10 * (k - 1)) * Math.sin((k - 1.1) * 5 * Math.PI) + 1; - - } - - }, - - Back: { - - In: function (k) { - - var s = 1.70158; - - return k * k * ((s + 1) * k - s); - - }, - - Out: function (k) { - - var s = 1.70158; - - return --k * k * ((s + 1) * k + s) + 1; - - }, - - InOut: function (k) { - - var s = 1.70158 * 1.525; - - if ((k *= 2) < 1) { - return 0.5 * (k * k * ((s + 1) * k - s)); - } - - return 0.5 * ((k -= 2) * k * ((s + 1) * k + s) + 2); - - } - - }, - - Bounce: { - - In: function (k) { - - return 1 - TWEEN.Easing.Bounce.Out(1 - k); - - }, - - Out: function (k) { - - if (k < (1 / 2.75)) { - return 7.5625 * k * k; - } else if (k < (2 / 2.75)) { - return 7.5625 * (k -= (1.5 / 2.75)) * k + 0.75; - } else if (k < (2.5 / 2.75)) { - return 7.5625 * (k -= (2.25 / 2.75)) * k + 0.9375; - } else { - return 7.5625 * (k -= (2.625 / 2.75)) * k + 0.984375; - } - - }, - - InOut: function (k) { - - if (k < 0.5) { - return TWEEN.Easing.Bounce.In(k * 2) * 0.5; - } - - return TWEEN.Easing.Bounce.Out(k * 2 - 1) * 0.5 + 0.5; - - } - - } - -}; - -TWEEN.Interpolation = { - - Linear: function (v, k) { - - var m = v.length - 1; - var f = m * k; - var i = Math.floor(f); - var fn = TWEEN.Interpolation.Utils.Linear; - - if (k < 0) { - return fn(v[0], v[1], f); - } - - if (k > 1) { - return fn(v[m], v[m - 1], m - f); - } - - return fn(v[i], v[i + 1 > m ? m : i + 1], f - i); - - }, - - Bezier: function (v, k) { - - var b = 0; - var n = v.length - 1; - var pw = Math.pow; - var bn = TWEEN.Interpolation.Utils.Bernstein; - - for (var i = 0; i <= n; i++) { - b += pw(1 - k, n - i) * pw(k, i) * v[i] * bn(n, i); - } - - return b; - - }, - - CatmullRom: function (v, k) { - - var m = v.length - 1; - var f = m * k; - var i = Math.floor(f); - var fn = TWEEN.Interpolation.Utils.CatmullRom; - - if (v[0] === v[m]) { - - if (k < 0) { - i = Math.floor(f = m * (1 + k)); - } - - return fn(v[(i - 1 + m) % m], v[i], v[(i + 1) % m], v[(i + 2) % m], f - i); - - } else { - - if (k < 0) { - return v[0] - (fn(v[0], v[0], v[1], v[1], -f) - v[0]); - } - - if (k > 1) { - return v[m] - (fn(v[m], v[m], v[m - 1], v[m - 1], f - m) - v[m]); - } - - return fn(v[i ? i - 1 : 0], v[i], v[m < i + 1 ? m : i + 1], v[m < i + 2 ? m : i + 2], f - i); - - } - - }, - - Utils: { - - Linear: function (p0, p1, t) { - - return (p1 - p0) * t + p0; - - }, - - Bernstein: function (n, i) { - - var fc = TWEEN.Interpolation.Utils.Factorial; - - return fc(n) / fc(i) / fc(n - i); - - }, - - Factorial: (function () { - - var a = [1]; - - return function (n) { - - var s = 1; - - if (a[n]) { - return a[n]; - } - - for (var i = n; i > 1; i--) { - s *= i; - } - - a[n] = s; - return s; - - }; - - })(), - - CatmullRom: function (p0, p1, p2, p3, t) { - - var v0 = (p2 - p0) * 0.5; - var v1 = (p3 - p1) * 0.5; - var t2 = t * t; - var t3 = t * t2; - - return (2 * p1 - 2 * p2 + v0 + v1) * t3 + (- 3 * p1 + 3 * p2 - 2 * v0 - v1) * t2 + v0 * t + p1; - - } - - } - -}; - -// UMD (Universal Module Definition) -(function (root) { - - if (typeof define === 'function' && define.amd) { - - // AMD - define([], function () { - return TWEEN; - }); - - } else if (typeof module !== 'undefined' && typeof exports === 'object') { - - // Node.js - module.exports = TWEEN; - - } else if (root !== undefined) { - - // Global variable - root.TWEEN = TWEEN; - - } - -})(this); - -}).call(this,require("pBGvAp")) -},{"pBGvAp":6}],5:[function(require,module,exports){ -var konami = function(opts) { - if (typeof opts.once === "undefined") { - opts.once = true; - } - - if (typeof opts.useCapture === "undefined") { - opts.useCapture = true; - } - - if (typeof opts.callback !== "function") { - throw new Error("Konami: callback is not a function."); - return; - } - - var ran = false; - var keypresses = []; - var KONAMI_CODE = [38, 38, 40, 40, 37, 39, 37, 39, 66, 65]; - - document.addEventListener('keydown', function(e) { - if (opts.once && ran) { - return; - } - - var key = (function(e) { - var event = e || window.event; - return (event.keyCode || event.which); - })(e); - - // if first button isn't up, return - if (keypresses.length == 0 && key != 38) { - return; - // if valid konami code character and keypresses available - } else if (keypresses.length < 10 && /37|38|39|40|65|66/.test(key)) { - keypresses.push(key); - if (keypresses.length == 10 - && JSON.stringify(keypresses) == JSON.stringify(KONAMI_CODE)) { - opts.callback(); - if (opts.once) { - ran = true; - } - } - } else { - keypresses = []; - } - }, opts.useCapture); -}; - -module.exports = konami; - -},{}],6:[function(require,module,exports){ -// shim for using process in browser - -var process = module.exports = {}; - -process.nextTick = (function () { - var canSetImmediate = typeof window !== 'undefined' - && window.setImmediate; - var canPost = typeof window !== 'undefined' - && window.postMessage && window.addEventListener - ; - - if (canSetImmediate) { - return function (f) { return window.setImmediate(f) }; - } - - if (canPost) { - var queue = []; - window.addEventListener('message', function (ev) { - var source = ev.source; - if ((source === window || source === null) && ev.data === 'process-tick') { - ev.stopPropagation(); - if (queue.length > 0) { - var fn = queue.shift(); - fn(); - } - } - }, true); - - return function nextTick(fn) { - queue.push(fn); - window.postMessage('process-tick', '*'); - }; - } - - return function nextTick(fn) { - setTimeout(fn, 0); - }; -})(); - -process.title = 'browser'; -process.browser = true; -process.env = {}; -process.argv = []; - -function noop() {} - -process.on = noop; -process.addListener = noop; -process.once = noop; -process.off = noop; -process.removeListener = noop; -process.removeAllListeners = noop; -process.emit = noop; - -process.binding = function (name) { - throw new Error('process.binding is not supported'); -} - -// TODO(shtylman) -process.cwd = function () { return '/' }; -process.chdir = function (dir) { - throw new Error('process.chdir is not supported'); -}; - -},{}]},{},[1]) \ No newline at end of file diff --git a/build/js/main.min.js b/build/js/main.min.js deleted file mode 100644 index 1708427..0000000 --- a/build/js/main.min.js +++ /dev/null @@ -1 +0,0 @@ -!function t(e,n,i){function o(a,s){if(!n[a]){if(!e[a]){var u="function"==typeof require&&require;if(!s&&u)return u(a,!0);if(r)return r(a,!0);throw new Error("Cannot find module '"+a+"'")}var c=n[a]={exports:{}};e[a][0].call(c.exports,function(t){var n=e[a][1][t];return o(n?n:t)},c,c.exports,t,e,n,i)}return n[a].exports}for(var r="function"==typeof require&&require,a=0;a=600?500:200,v=new THREE.Scene,v.add(O),g=new THREE.Raycaster,T=new THREE.Vector2,E=new THREE.WebGLRenderer,E.setClearColor(A.matches?"black":"white"),E.setPixelRatio(window.devicePixelRatio),E.setSize(window.innerWidth,window.innerHeight);var t=new THREE.BoxGeometry(S,S,S);t.colorsNeedUpdate=!0;for(var e=0;e600||!window.DeviceOrientationEvent)&&(_&&clearInterval(_),y&&clearTimeout(y),_=setInterval(function(){k=.2;setTimeout(function(){k=.02},750)},12e3))}function n(){_&&clearInterval(_),y&&clearTimeout(y),m.aspect=window.innerWidth/window.innerHeight,m.updateProjectionMatrix(),E.setSize(window.innerWidth,window.innerHeight),E.render(v,m)}function i(t){H=(H+1)%q.length,t.key.includes("Arrow")&&c(q[H])}function o(t){var e=new THREE.Vector3(I*Math.sin(THREE.Math.degToRad(t.alpha))*-1,I*Math.sin(THREE.Math.degToRad(t.beta+100))*-1,v.position.z);m.lookAt(e),g.setFromCamera(T,m),E.render(v,m)}function r(t){t.preventDefault(),T.x=t.clientX/window.innerWidth*2-1,T.y=2*-(t.clientY/window.innerHeight)+1,g.setFromCamera(T,m);var e=g.intersectObjects(C);if(e.length>0&&!b[e[0].object.uuid]){b[e[0].object.uuid]=e[0].object;var n=new p.Tween(e[0].object.scale).to({x:3,y:3,z:3},500).easing(p.Easing.Elastic.Out),i=new p.Tween(e[0].object.rotation).to({x:Math.random(),y:Math.random(),z:Math.random()},500).easing(p.Easing.Elastic.Out),o=new p.Tween(e[0].object.scale).to({x:1,y:1,z:1},500).delay(1e3).easing(p.Easing.Elastic.Out).onComplete(function(t){var e=Object.keys(b).shift();delete b[e]});n.chain(o).start(),i.start(),w()}}function a(){requestAnimationFrame(a),p.update(),s()}function s(){M>0&&R>=100?M=-1:M<0&&R<=0&&(M=1),R+=k*M,O.rotation.set(Math.sin(THREE.Math.degToRad(R)),Math.sin(THREE.Math.degToRad(R)),Math.sin(THREE.Math.degToRad(R))),g.setFromCamera(T,m),E.render(v,m)}function u(t){var e={x:800*Math.random()-200,y:800*Math.random()-200,z:800*Math.random()-200};return e}function c(t){if(t)for(var e=0;e=F&&document.getElementsByClassName("js-score-hidden").length>0?document.getElementsByClassName("js-score-hidden")[0].classList.remove("js-score-hidden"):x%100===0&&d()}t("./quote.js"),t("konami-komando")({once:!0,useCapture:!0,callback:function(){f()}});var p=t("@tweenjs/tween.js");window.TWEEN=p;var m,v,E,g,_,y,T=new THREE.Vector2,b={},M=1,C=[],k=([.4*Math.random()/20,.4*Math.random()/20,.4*Math.random()/20],.02),I=300,R=0,S=window.innerWidth>=600?5:10,j=window.innerWidth>=600?1e3:250,F=15,B=[],O=new THREE.Group,H=0,A=window.matchMedia("(prefers-color-scheme: dark)"),x=0,L=new THREE.LineBasicMaterial({color:16777215,linewidth:2}),D={twitter:["#1DA1F2","#14171A","#657786","#AAB8C2"],twitch:["#9146ff"],github:["#333","#6e5494","#c6e48b","#7bc96f","#239a3b","#196127"],evernote:["#00A82D"],stackoverflow:["#f48024","#222426","#bcbbbb"],linkedin:["#0077B5","#00A0DC","#313335","#86888A"]},q=[["#042A2B","#5EB1BF","#CDEDF6","#EF7B45","#D84727"],["#E3E7D3","#BDC2BF","#989C94","#25291C","#E6E49F"],["#EAF2E3","#61E8E1","#F25757","F2E863","F2CD60"],["#E28413","#F56416","#DD4B1A","#EF271B","#EA1744"],["#86583E","#AF2A42","#61643F","#AFBE96","#F0EEE1"],["#D44A98","#60B9CB","#FFFB53"]];e(),a(),document.getElementById("hero").appendChild(E.domElement);var P=document.getElementsByClassName("js-increment")[0];if(window.innerWidth>=600){var N=document.getElementsByClassName("content")[0];N.addEventListener("mouseover",function(t){t.target&&t.target.getAttribute("data-brand")&&c(D[t.target.getAttribute("data-brand")])})}}()},{"./quote.js":2,"@tweenjs/tween.js":4,"konami-komando":5}],2:[function(t,e,n){!function(){function e(){var t=document.getElementsByClassName("heading")[0],o=document.getElementsByClassName("description")[0],r=document.getElementsByClassName("job-title")[0];t.className="heading quote",o.className="description author",r.style.display="none";for(var a=t.innerText,s=o.innerText,u=0;u<=n.length;u++)!function(u){if(u==n.length)setTimeout(function(e){t.className="heading",o.className="description",o.innerHTML="",a.typeout(t)},1e4*u),setTimeout(function(t){s.typeout(o),r.style=""},1e4*u+2e3),i.removeEventListener("click",e);else{var c=new String(n[u].quote),h=new String(n[u].author);setTimeout(function(e){var n="“"+c+"”";n.typeout(t),o.innerHTML=""},1e4*u),setTimeout(function(t){h.typeout(o)},1e4*u+2e3)}}(u)}var n=t("../json/quotes.json"),i=document.getElementById("quotes");String.prototype.typeout=function(t){var e,n=this.split(""),i=n.slice(0);clearTimeout(e);var o="";!function r(a){var s=i.length;return a>=s?t.innerHTML=n.join("").toString():(o+=i[a],t.innerHTML=o,void(e=setTimeout(function(){r(a+1)},50)))}(0)},i.addEventListener("click",e)}()},{"../json/quotes.json":3}],3:[function(t,e,n){e.exports=[{quote:"Fairy tales are more than true — not because they tell us dragons exist, but because they tell us dragons can be beaten.",author:"G. K. Chesterton"},{quote:"Don't go through life, grow through life.",author:"Eric Butterworth"},{quote:"Wisdom is knowing what to do next, skill is knowing how to do it, and virtue is doing it.",author:"David Starr Jordan"},{quote:"Never doubt that a small group of thoughtful, committed, citizens can change the world. Indeed, it is the only thing that ever has.",author:"Margaret Mead"},{quote:"When we speak we are afraid our words will not be heard or welcomed. But when we are silent, we are still afraid. So it is better to speak.",author:"Audre Lorde"}]},{}],4:[function(t,e,n){(function(t){var i=function(){this._tweens={},this._tweensAddedDuringUpdate={}};i.prototype={getAll:function(){return Object.keys(this._tweens).map(function(t){return this._tweens[t]}.bind(this))},removeAll:function(){this._tweens={}},add:function(t){this._tweens[t.getId()]=t,this._tweensAddedDuringUpdate[t.getId()]=t},remove:function(t){delete this._tweens[t.getId()],delete this._tweensAddedDuringUpdate[t.getId()]},update:function(t,e){var n=Object.keys(this._tweens);if(0===n.length)return!1;for(t=void 0!==t?t:o.now();n.length>0;){this._tweensAddedDuringUpdate={};for(var i=0;i1?1:n,i=this._easingFunction(n);for(e in this._valuesEnd)if(void 0!==this._valuesStart[e]){var o=this._valuesStart[e]||0,r=this._valuesEnd[e];r instanceof Array?this._object[e]=this._interpolationFunction(r,i):("string"==typeof r&&(r="+"===r.charAt(0)||"-"===r.charAt(0)?o+parseFloat(r):parseFloat(r)),"number"==typeof r&&(this._object[e]=o+(r-o)*i))}if(null!==this._onUpdateCallback&&this._onUpdateCallback(this._object,n),1===n){if(this._repeat>0){isFinite(this._repeat)&&this._repeat--;for(e in this._valuesStartRepeat){if("string"==typeof this._valuesEnd[e]&&(this._valuesStartRepeat[e]=this._valuesStartRepeat[e]+parseFloat(this._valuesEnd[e])),this._yoyo){var a=this._valuesStartRepeat[e];this._valuesStartRepeat[e]=this._valuesEnd[e],this._valuesEnd[e]=a}this._valuesStart[e]=this._valuesStartRepeat[e]}return this._yoyo&&(this._reversed=!this._reversed),void 0!==this._repeatDelayTime?this._startTime=t+this._repeatDelayTime:this._startTime=t+this._delayTime,null!==this._onRepeatCallback&&this._onRepeatCallback(this._object),!0}null!==this._onCompleteCallback&&this._onCompleteCallback(this._object);for(var s=0,u=this._chainedTweens.length;s1?a(t[n],t[n-1],n-i):a(t[r],t[r+1>n?n:r+1],i-r)},Bezier:function(t,e){for(var n=0,i=t.length-1,r=Math.pow,a=o.Interpolation.Utils.Bernstein,s=0;s<=i;s++)n+=r(1-e,i-s)*r(e,s)*t[s]*a(i,s);return n},CatmullRom:function(t,e){var n=t.length-1,i=n*e,r=Math.floor(i),a=o.Interpolation.Utils.CatmullRom;return t[0]===t[n]?(e<0&&(r=Math.floor(i=n*(1+e))),a(t[(r-1+n)%n],t[r],t[(r+1)%n],t[(r+2)%n],i-r)):e<0?t[0]-(a(t[0],t[0],t[1],t[1],-i)-t[0]):e>1?t[n]-(a(t[n],t[n],t[n-1],t[n-1],i-n)-t[n]):a(t[r?r-1:0],t[r],t[n1;i--)n*=i;return t[e]=n,n}}(),CatmullRom:function(t,e,n,i,o){var r=.5*(n-t),a=.5*(i-e),s=o*o,u=o*s;return(2*e-2*n+r+a)*u+(-3*e+3*n-2*r-a)*s+r*o+e}}},function(t){"function"==typeof define&&define.amd?define([],function(){return o}):"undefined"!=typeof e&&"object"==typeof n?e.exports=o:void 0!==t&&(t.TWEEN=o)}(this)}).call(this,t("pBGvAp"))},{pBGvAp:6}],5:[function(t,e,n){var i=function(t){if("undefined"==typeof t.once&&(t.once=!0),"undefined"==typeof t.useCapture&&(t.useCapture=!0),"function"!=typeof t.callback)throw new Error("Konami: callback is not a function.");var e=!1,n=[],i=[38,38,40,40,37,39,37,39,66,65];document.addEventListener("keydown",function(o){if(!t.once||!e){var r=function(t){var e=t||window.event;return e.keyCode||e.which}(o);0==n.length&&38!=r||(n.length<10&&/37|38|39|40|65|66/.test(r)?(n.push(r),10==n.length&&JSON.stringify(n)==JSON.stringify(i)&&(t.callback(),t.once&&(e=!0))):n=[])}},t.useCapture)};e.exports=i},{}],6:[function(t,e,n){function i(){}var o=e.exports={};o.nextTick=function(){var t="undefined"!=typeof window&&window.setImmediate,e="undefined"!=typeof window&&window.postMessage&&window.addEventListener;if(t)return function(t){return window.setImmediate(t)};if(e){var n=[];return window.addEventListener("message",function(t){var e=t.source;if((e===window||null===e)&&"process-tick"===t.data&&(t.stopPropagation(),n.length>0)){var i=n.shift();i()}},!0),function(t){n.push(t),window.postMessage("process-tick","*")}}return function(t){setTimeout(t,0)}}(),o.title="browser",o.browser=!0,o.env={},o.argv=[],o.on=i,o.addListener=i,o.once=i,o.off=i,o.removeListener=i,o.removeAllListeners=i,o.emit=i,o.binding=function(t){throw new Error("process.binding is not supported")},o.cwd=function(){return"/"},o.chdir=function(t){throw new Error("process.chdir is not supported")}},{}]},{},[1]); \ No newline at end of file diff --git a/build/js/quote.js b/build/js/quote.js deleted file mode 100644 index 9fdc6f6..0000000 --- a/build/js/quote.js +++ /dev/null @@ -1,94 +0,0 @@ -(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o=len){ - return targetElem.innerHTML = str.join('').toString();// you can use your selectors - } - ll = ll + strCopy[start]; - targetElem.innerHTML = ll; // you can use your selectors - timer = setTimeout(function(){ - shuffle(start+1); - }, 50); - })(0); - } - - function triggerQuoteAnimation() { - var heading = document.getElementsByClassName('heading')[0]; - var description = document.getElementsByClassName('description')[0]; - var jobTitle = document.getElementsByClassName("job-title")[0]; - heading.className = 'heading quote'; - description.className = 'description author'; - jobTitle.style.display = 'none'; - - var oHeading = heading.innerText; - var oDescription = description.innerText; - for (var i=0; i<=quotes.length; i++) { - (function(i) { - if (i == quotes.length) { - setTimeout(function(e) { - heading.className = 'heading'; - description.className = 'description'; - description.innerHTML = ''; - oHeading.typeout(heading); - }, 10000*i); - setTimeout(function(e) { - oDescription.typeout(description); - jobTitle.style = ''; - }, 10000*i+2000); - quoteTrigger.removeEventListener('click', triggerQuoteAnimation); - } else { - var quote = new String(quotes[i].quote); - var author = new String(quotes[i].author); - setTimeout(function(e) { - var moddedQuote = '“' + quote + '”'; - moddedQuote.typeout(heading); - description.innerHTML = ''; - }, 10000*i); - setTimeout(function(e) { - author.typeout(description); - }, 10000*i+2000); - } - })(i); - } - } - - quoteTrigger.addEventListener('click', triggerQuoteAnimation); -})(); -},{"../json/quotes.json":2}],2:[function(require,module,exports){ -module.exports=[ - { - "quote" : "Fairy tales are more than true — not because they tell us dragons exist, but because they tell us dragons can be beaten.", - "author": "G. K. Chesterton" - }, - { - "quote" : "Don't go through life, grow through life.", - "author": "Eric Butterworth" - }, - { - "quote" : "Wisdom is knowing what to do next, skill is knowing how to do it, and virtue is doing it.", - "author": "David Starr Jordan" - }, - { - "quote": "Never doubt that a small group of thoughtful, committed, citizens can change the world. Indeed, it is the only thing that ever has.", - "author": "Margaret Mead" - }, - { - "quote": "When we speak we are afraid our words will not be heard or welcomed. But when we are silent, we are still afraid. So it is better to speak.", - "author": "Audre Lorde" - } -] - - -},{}]},{},[1]) \ No newline at end of file diff --git a/build/js/quote.min.js b/build/js/quote.min.js deleted file mode 100644 index f7d8720..0000000 --- a/build/js/quote.min.js +++ /dev/null @@ -1 +0,0 @@ -!function e(t,n,o){function r(u,a){if(!n[u]){if(!t[u]){var s="function"==typeof require&&require;if(!a&&s)return s(u,!0);if(i)return i(u,!0);throw new Error("Cannot find module '"+u+"'")}var l=n[u]={exports:{}};t[u][0].call(l.exports,function(e){var n=t[u][1][e];return r(n?n:e)},l,l.exports,e,t,n,o)}return n[u].exports}for(var i="function"==typeof require&&require,u=0;u=a?e.innerHTML=n.join("").toString():(r+=o[u],e.innerHTML=r,void(t=setTimeout(function(){i(u+1)},50)))}(0)},o.addEventListener("click",t)}()},{"../json/quotes.json":2}],2:[function(e,t,n){t.exports=[{quote:"Fairy tales are more than true — not because they tell us dragons exist, but because they tell us dragons can be beaten.",author:"G. K. Chesterton"},{quote:"Don't go through life, grow through life.",author:"Eric Butterworth"},{quote:"Wisdom is knowing what to do next, skill is knowing how to do it, and virtue is doing it.",author:"David Starr Jordan"},{quote:"Never doubt that a small group of thoughtful, committed, citizens can change the world. Indeed, it is the only thing that ever has.",author:"Margaret Mead"},{quote:"When we speak we are afraid our words will not be heard or welcomed. But when we are silent, we are still afraid. So it is better to speak.",author:"Audre Lorde"}]},{}]},{},[1]); \ No newline at end of file diff --git a/favicon-16x16.png b/favicon-16x16.png deleted file mode 100644 index 2a1b9071bbceaedc878c67b004c89689a2e4eb1f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 362 zcmV-w0hRuVP)YU6o=2bH!X?AlrB;oL^O*p$xL6&ECN5FBDGJj3 zGbJSV2r0(m(m)+O+d23CJ}&os2xAtGnTHH;-EpSNoNXcw`cXv$6sO{9V^x340=JJ( zN6((LYuW6g~G%ff=yiN903|253!$CTa*SOw_ovMqRWEe}eu1S2b~?D}RECYbAA|N$JwB z#6>C5MM0AmP-8#9w$XtOgSPJ)nv{rPNEeX0n7e%M-gC}7_a*ld_Bd#d`C$wAzZ}Tq z7j6pB4Q34V<8KgQQ-Yr-V?$4N@LLYda7jzpie3;0+VBgW*LvWoZXt{#!L!<;?Xz{P+G zCX6Rf*#c|_YzJ%yYzJ%yEF5@OaUrwToQA!RBbo=Y!WXXgFLP zK0P#4*X> zvQe6uo4+Q6c+pf`Gd3Wl>{vt~XqtwfdKF)nRxH6I$B)6IsW8lXXB;Bzb9*3!XmVYr zOm1O{h(>q&>FQGZ1~%7%Q6y8#x2qY+?MIcoWkcukGAs65Tf@>vCfZ&2uxU}J3F5D1jM0-nIwMwX( z#QCY4#G58gV#ojX&N_DNUEAFs+cZ=mMJQB3N+ZR?d+Us$k?m~i*h$4$`ZV_Jyq|e9 z^JeFpL=X-MhlQg@1t>d&^G^!Gdx9WzbX0zydQlLrKwW3&*7LUnA$(jAPC*+G0f|aI z6g5B7uD%gGg?J(_9m4>Q#3F=T*X3kw)z~~CL%KwWfetv`gS^&Ohi4Ka>PR!644ooG7K`b z|M!_^Grt%~5JH~9py;afqnQqr3rP>P18j>jETFnd2A9R}=pQ3r*#fpjnTO>s*pfvX z%i;wtzlZTNvgB$h=A?H54qL#sC{rE3ROn?hBYkEnq6UFCjJT9hVL{bdFet7a$^l(E{5DlN$^&~aY{md#XMh22i7Iya};b^KB8@>(|H)| z7qRZYxxUtSDL6$l#NW_9?kBOpWJ6uqq!ptg+QxZls`B?3gQ#C@C>MbJM_1xBE&1po z#A-Xz#Ao%*KXaq5p5PqnkSN+@YeH4Yt6+aUBm3*hv3U4rToiTG13qVMYn2#(Lm_|b zdg`G(19j&icin+;cmVq*Z3VPUY{RmlNZ+u&v$9a|K4WHy7vfOHv1k#>Xaj9AyR0-+ z>5OGF6Q-s3P)lHd?n=L;Gt4e4jjZ%3K3no#vc2EieXn5cP`70tY%#m6WcGja{?s!2 zsGHk|xy|Fx=O0^mTP0tAmHfx^&;K<4W-8-fiuTjrZ+=Tx_86!WbzA!n*xI)Ign|<9 zG_vxh^}KcOACUXyO|-S$KK=&o;7dc5`{7+|s3id1Xrq>GUdJQABhdZ`AWwqH;4Gja zPjbz1!tLzon{alox05Gn%GO}_hI`22ni#qArhEAERnS##N?)5fqAg#`;!sb2%s0M@ z-1TD#-`IUP*Z08Q*7VsLxr;1v`oKfk0rL4x?y1PB_vSP4cY!-tZBiG_0r!J<8shL} zTZsC`oAX~GYkH1+tZC8bf!lYX{}@9B;urQ!&=AZiJCJ~P!&v5lTbl;|?XDx3x0XHR z@51nXXItaI-OX7tl~~L3nwB_DDLtes@;P`vSx5inu%{uGs`L0?zYt=;{uE<}3{~LOS{D8hgdKEM!@ix>I(f>v8r4dh8ORofXPssm~;3S=M zU*8ePDI;f^fwA6=t%@B9{a-Qj5?A2*q^|x3*r*BI7%#cM$DQA z+wa(F#fH^kKQXo#V@;997{|)`U@Gzl*0{j)IPkel&TfhN!`^Y*2tixBy0IO$$9qd% zArEe=i4U3Iti=A9sx$z7DC5}TIw0Zc0|6QQP!~ctZ_0)u{lexw^PQD=$E0V;MQE3S zbH<-IRtE#|`w({(eCdWW(ksm0S|zN5cc70!tFNs*ukB7Z?5`3jDCB*LuXA-icL{kG z_5ug^-umuy+k9XR4vs?f73HWBcwq>sv8C zjPnP;{bw<0XUXGl@9%6{H6}d%JpRqhEk1wv{NeM5zdtlH2bz)P`G@BpK7V-rX=V;I zBl{@%$6T0!zZdAT&hU7S-!H7V&e4J_+B*Mcv$2_^YzE7&~1-Rz+40vBOu$)RgSI>W}FXmEjz!;FhMuPdD + - - - Augustus Yuan. Web Developer. Quote lover. Lifelong Learner. - - - - - - - - - - - - - -
-
- -
    - - -
-
-
-
-
- Augustus profile picture -

Augustus Yuan

-

Software Engineer at HeyGen

-

Web Developer. Quote Lover. Lifelong learner.

- - -
- - - - + + + + Augustus Yuan | Personal Site + + + +
+ + diff --git a/js/main.js b/js/main.js deleted file mode 100644 index 968d3c0..0000000 --- a/js/main.js +++ /dev/null @@ -1,368 +0,0 @@ -(function() { - 'use strict'; - require('./quote.js'); - require("konami-komando")({ - once: true, - useCapture: true, - callback: function() { - blowUpCubes(); - } - }); - var TWEEN = require("@tweenjs/tween.js"); - window.TWEEN = TWEEN; - - var camera, scene, renderer; - - var raycaster; - var mouse = new THREE.Vector2(), INTERSECTED = {}; - var multiplier = 1; - var objects = []; - var rotationSpeed = [(Math.random() * 0.4) / 20, (Math.random() * 0.4) / 20, (Math.random() * 0.4) / 20]; - var PIVOT_SPEED = 0.02; - var RADIUS = 300; - var theta = 0; - var CUBE_SIZE = window.innerWidth >= 600 ? 5 : 10; - var NUM_OF_CUBES = window.innerWidth >= 600 ? 1000 : 250; - var SATISFIABLE_CUBE_SCORE = 15; - var filterCoordinates = []; - var pivot = new THREE.Group(); - var themeIndex = 0; - - var darkModeMedia = window.matchMedia('(prefers-color-scheme: dark)'); - - var cubeScore = 0; - var lineMaterial = new THREE.LineBasicMaterial({ - color: 0xffffff, - linewidth: 2 - }); - - var pivotInterval, pivotTimeout; - - var socialThemes = { - "twitter": ["#1DA1F2", "#14171A", "#657786", "#AAB8C2"], - "twitch": ["#9146ff"], - "github": ["#333", "#6e5494", "#c6e48b", "#7bc96f", "#239a3b", "#196127"], - "evernote": ['#00A82D'], - "stackoverflow": ["#f48024", "#222426", "#bcbbbb"], - "linkedin": ["#0077B5", "#00A0DC", "#313335", "#86888A"] - } - - var themes = [ - ["#042A2B", "#5EB1BF", "#CDEDF6", "#EF7B45", "#D84727"], - ["#E3E7D3", "#BDC2BF", "#989C94", "#25291C", "#E6E49F"], - ["#EAF2E3", "#61E8E1", "#F25757", "F2E863", "F2CD60"], - ['#E28413', '#F56416', '#DD4B1A', '#EF271B', '#EA1744'], - ['#86583E', '#AF2A42', '#61643F', '#AFBE96', '#F0EEE1'], - ['#D44A98', '#60B9CB', '#FFFB53'], //cmyk - ]; - - init(); - animate(); - document.getElementById("hero").appendChild(renderer.domElement); - var keepScoreElement = document.getElementsByClassName('js-increment')[0]; - - if (window.innerWidth >= 600) { - var themeHoversItemContainer = document.getElementsByClassName('content')[0]; - themeHoversItemContainer.addEventListener('mouseover', function(e) { - if (e.target && e.target.getAttribute('data-brand')) { - themifyCubes(socialThemes[e.target.getAttribute('data-brand')]); - } - }); - } - - function init() { - camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 10000 ); - camera.position.y = 300; - camera.position.z = window.innerWidth >= 600 ? 500 : 200; - - scene = new THREE.Scene(); - scene.add(pivot); - - raycaster = new THREE.Raycaster(); - mouse = new THREE.Vector2(); - - renderer = new THREE.WebGLRenderer(); - renderer.setClearColor(darkModeMedia.matches ? "black" : "white"); - renderer.setPixelRatio( window.devicePixelRatio ); - renderer.setSize( window.innerWidth, window.innerHeight ); - - var geometry = new THREE.BoxGeometry( CUBE_SIZE, CUBE_SIZE, CUBE_SIZE ); - geometry.colorsNeedUpdate = true; - - for (var i = 0; i < NUM_OF_CUBES; i++) { - var randomColor = Math.random() * 0xffffff; - // generate random coordinates that are not already occupied yet - var coordinates = generateRandomCoords(filterCoordinates); - objects[i] = new THREE.Mesh( geometry, new THREE.MeshBasicMaterial( { color: new THREE.Color(randomColor), opacity: 0.6, transparent: true, depthWrite: false } ) ); - objects[i].position.set(coordinates.x, coordinates.y, coordinates.z); - - // add to filter so we do not generate conflicting coordinates again - filterCoordinates.push(coordinates); - - // modify rotation - objects[i].rotation.x = Math.random() * 2 * Math.PI; - objects[i].rotation.y = Math.random() * 2 * Math.PI; - pivot.add( objects[i] ); - - var edges = new THREE.EdgesGeometry( geometry ); - var line = new THREE.LineSegments(edges, lineMaterial); - objects[i].add(line); - } - - document.addEventListener( 'keyup', onKeyUp, false ); - document.addEventListener('mousemove', onDocumentMouseMove, false); - - if (window.DeviceOrientationEvent) { - window.addEventListener( 'deviceorientation', onDeviceOrientation, false ); - } - window.addEventListener( 'resize', onWindowResize, false ); - - // Detect dark mode only supported in Safari 12.1 - if (darkModeMedia.matches) { - setColorScheme({ darkMode: true, shouldTransition: false }); - } - darkModeMedia.addListener(function(e) { - var colorSchemeOptions = { - darkMode: darkModeMedia.matches, - shouldTransition: true, - } - setColorScheme(colorSchemeOptions); - //darkModeMedia.matches ? darkMode() : lightMode(); - }); - - if (window.innerWidth > 600 || !window.DeviceOrientationEvent) { - if (pivotInterval) { - clearInterval(pivotInterval); - } - if (pivotTimeout) { - clearTimeout(pivotTimeout); - } - // set time shift - pivotInterval = setInterval(function() { - PIVOT_SPEED = 0.2; - var pivotTimeout = setTimeout(function() { - PIVOT_SPEED = 0.02; - }, 750) - }, 12000); - } - } - - function onWindowResize() { - if (pivotInterval) { - clearInterval(pivotInterval); - } - if (pivotTimeout) { - clearTimeout(pivotTimeout); - } - - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize( window.innerWidth, window.innerHeight ); - renderer.render( scene, camera ); - } - - function onKeyUp(e) { - themeIndex = (themeIndex + 1) % themes.length; - if (e.key.includes('Arrow')) { - themifyCubes(themes[themeIndex]); - } - } - - function onDeviceOrientation( event ) { - // set camera to change its view based on gyroscope - // NOTE: adding 100 to beta starts the phone as if it were vertical - var vectorAngle = new THREE.Vector3( - RADIUS * Math.sin(THREE.Math.degToRad( event.alpha ))*-1, - RADIUS * Math.sin(THREE.Math.degToRad( event.beta + 100 ))*-1, - scene.position.z - ) - camera.lookAt(vectorAngle); - - raycaster.setFromCamera( mouse, camera ); - renderer.render( scene, camera ); - } - - function onDocumentMouseMove(event) { - event.preventDefault(); - mouse.x = event.clientX / window.innerWidth * 2 - 1; - mouse.y = -(event.clientY / window.innerHeight) * 2 + 1; - - // if user hovers over specific cube, TWEEN scale to make it pop - raycaster.setFromCamera(mouse, camera); - var intersects = raycaster.intersectObjects(objects); - - // check we have intersects and that the uuid of the object is not already tweening - if (intersects.length > 0) { - if (!INTERSECTED[intersects[0].object.uuid]) { - INTERSECTED[intersects[0].object.uuid] = intersects[0].object; - var scaleTween = new TWEEN.Tween(intersects[0].object.scale) - .to({ x: 3, y: 3, z: 3 }, 500) - .easing(TWEEN.Easing.Elastic.Out); - var rotationTween = new TWEEN.Tween(intersects[0].object.rotation) - .to({ x: Math.random(), y: Math.random(), z: Math.random() }, 500) - .easing(TWEEN.Easing.Elastic.Out) - var shrinkTween = new TWEEN.Tween(intersects[0].object.scale) - .to({ x: 1, y: 1, z: 1 }, 500) - .delay(1000) - .easing(TWEEN.Easing.Elastic.Out) - .onComplete(function(tween) { - var uuid = Object.keys(INTERSECTED).shift(); - delete INTERSECTED[uuid]; - }); - scaleTween.chain(shrinkTween).start(); - rotationTween.start(); - incrementScore(); - } - } - } - - function animate() { - requestAnimationFrame( animate ); - TWEEN.update(); - render(); - } - - function render() { - // in order to prevent the theta from forever growing which could hit Number.MAX_SAFE_INTEGER, - // go reverse and interchange - if (multiplier > 0 && theta >= 100) { - multiplier = -1; - } else if (multiplier < 0 && theta <= 0) { - multiplier = 1; - } - theta += PIVOT_SPEED * multiplier; - - pivot.rotation.set( - Math.sin( THREE.Math.degToRad( theta )), - Math.sin( THREE.Math.degToRad( theta )), - Math.sin( THREE.Math.degToRad( theta )) - ); - - raycaster.setFromCamera( mouse, camera ); - renderer.render( scene, camera ); - } - - // generate random coordinates based on page and size of cubes - // TODO: handle filtering of coordinates - function generateRandomCoords(filterCoordinates) { - var coords = { - x: (Math.random() * 800 - 200), - y: (Math.random() * 800 - 200), - z: (Math.random() * 800 - 200) - }; - - return coords; - } - - // takes in an array of hex colors and applies the theme equally to the cubes - function themifyCubes(theme) { - if (!theme) { - for (var i = 0; i < objects.length; i++) { - var randomColor = Math.random() * 0xffffff; - objects[i].material.color.set(new THREE.Color(randomColor)); - } - } else { - for (var i = 0; i < objects.length; i++) { - var hexColor = parseInt(theme[i % theme.length].replace("#", "0x"), 16); - objects[i].material.color.set(new THREE.Color(hexColor)); - } - } - } - - /** - * Sets the color scheme - * options: { darkMode: boolean, shouldTransition: boolean } - */ - function setColorScheme(options) { - var whiteClearColor = new THREE.Color("white"); - var darkClearColor = new THREE.Color("black"); - var firstClearColor = options.darkMode ? whiteClearColor : darkClearColor; - var transitionedClearColor = options.darkMode ? darkClearColor : whiteClearColor; - if (options.shouldTransition) { - var colorModeTween = new TWEEN.Tween(firstClearColor) - .to(transitionedClearColor, 500).onUpdate(function() { - renderer.setClearColor(firstClearColor); - }).start(); - } else { - renderer.setClearColor(transitionedClearColor); - } - if (options.darkMode) { - document.body.classList.add("dark-mode"); - } else { - document.body.classList.remove("dark-mode"); - } - lineMaterial = new THREE.LineBasicMaterial({ - color: options.darkMode ? 0x000000 : 0xffffff, - linewidth: 2 - }); - var geometry = new THREE.BoxGeometry( CUBE_SIZE, CUBE_SIZE, CUBE_SIZE ); - geometry.colorsNeedUpdate = true; - var edges = new THREE.EdgesGeometry( geometry ); - for (var i = 0; i < objects.length; i++) { - var line = new THREE.LineSegments(edges, lineMaterial); - objects[i].add(line); - } - render(); - } - - // flicker cubes through all the themes twice! :) - function flickerCubes() { - var ran = false; - var i = 0; - var index = 0; - while (i++ < themes.length) { - var theme = themes[i]; - if (i === themes.length - 1 && !ran) { - ran = true; - i = 0; - } else if (i === themes.length - 1) { - theme = false; - } - (function(i) { - setTimeout(function() { - themifyCubes(theme); - }, index++ * 200); - })(i); - } - } - - // Handy function to handle logarithmic function - function getBaseLog(x, y) { - return Math.log(y) / Math.log(x); - } - - // Blow up all the cubes in logarithmic fashion so as time goes on, we blow up more - function blowUpCubes() { - var shrinkTweens = []; - for (var i = 0; i < objects.length; i+=2) { - var delay = Math.floor(getBaseLog(2, i) * 200); - var scaleTween = new TWEEN.Tween(objects[i].scale) - .delay(delay) - .to({ x: 3, y: 3, z: 3 }, 500) - .easing(TWEEN.Easing.Elastic.Out).onComplete(function() { - shrinkTween.start(); - }); - var rotationTween = new TWEEN.Tween(objects[i].rotation) - .delay(delay) - .to({ x: Math.random(), y: Math.random(), z: Math.random() }, 500) - .easing(TWEEN.Easing.Elastic.Out) - var shrinkTween = new TWEEN.Tween(objects[i].scale) - .delay(Math.floor(getBaseLog(2, Math.floor(objects.length / 2)) * 200)) - .to({ x: 1, y: 1, z: 1 }, 500) - .easing(TWEEN.Easing.Elastic.Out); - scaleTween.chain(shrinkTween).start(); - rotationTween.start(); - } - } - - function incrementScore() { - cubeScore++; - keepScoreElement.innerText = cubeScore; - if (cubeScore >= SATISFIABLE_CUBE_SCORE && document.getElementsByClassName('js-score-hidden').length > 0) { - document.getElementsByClassName('js-score-hidden')[0].classList.remove('js-score-hidden'); - } else if (cubeScore % 100 === 0) { - flickerCubes(); - } - } -})(); diff --git a/js/quote.js b/js/quote.js deleted file mode 100644 index 73ed10e..0000000 --- a/js/quote.js +++ /dev/null @@ -1,67 +0,0 @@ -(function() { - var quotes = require('../json/quotes.json'); - var quoteTrigger = document.getElementById('quotes'); - - String.prototype.typeout = function(targetElem) { - var timer; - var str = this.split(''); - var strCopy = str.slice(0); - clearTimeout(timer); - var ll = ''; - (function shuffle(start){ - // This code is run options.fps times per second - // and updates the contents of the page element - var i, len = strCopy.length; - if(start>=len){ - return targetElem.innerHTML = str.join('').toString();// you can use your selectors - } - ll = ll + strCopy[start]; - targetElem.innerHTML = ll; // you can use your selectors - timer = setTimeout(function(){ - shuffle(start+1); - }, 50); - })(0); - } - - function triggerQuoteAnimation() { - var heading = document.getElementsByClassName('heading')[0]; - var description = document.getElementsByClassName('description')[0]; - var jobTitle = document.getElementsByClassName("job-title")[0]; - heading.className = 'heading quote'; - description.className = 'description author'; - jobTitle.style.display = 'none'; - - var oHeading = heading.innerText; - var oDescription = description.innerText; - for (var i=0; i<=quotes.length; i++) { - (function(i) { - if (i == quotes.length) { - setTimeout(function(e) { - heading.className = 'heading'; - description.className = 'description'; - description.innerHTML = ''; - oHeading.typeout(heading); - }, 10000*i); - setTimeout(function(e) { - oDescription.typeout(description); - jobTitle.style = ''; - }, 10000*i+2000); - quoteTrigger.removeEventListener('click', triggerQuoteAnimation); - } else { - var quote = new String(quotes[i].quote); - var author = new String(quotes[i].author); - setTimeout(function(e) { - var moddedQuote = '“' + quote + '”'; - moddedQuote.typeout(heading); - description.innerHTML = ''; - }, 10000*i); - setTimeout(function(e) { - author.typeout(description); - }, 10000*i+2000); - } - })(i); - } - } - - quoteTrigger.addEventListener('click', triggerQuoteAnimation); -})(); \ No newline at end of file diff --git a/json/quotes.json b/json/quotes.json deleted file mode 100644 index 23f1c80..0000000 --- a/json/quotes.json +++ /dev/null @@ -1,23 +0,0 @@ -[ - { - "quote" : "Fairy tales are more than true — not because they tell us dragons exist, but because they tell us dragons can be beaten.", - "author": "G. K. Chesterton" - }, - { - "quote" : "Don't go through life, grow through life.", - "author": "Eric Butterworth" - }, - { - "quote" : "Wisdom is knowing what to do next, skill is knowing how to do it, and virtue is doing it.", - "author": "David Starr Jordan" - }, - { - "quote": "Never doubt that a small group of thoughtful, committed, citizens can change the world. Indeed, it is the only thing that ever has.", - "author": "Margaret Mead" - }, - { - "quote": "When we speak we are afraid our words will not be heard or welcomed. But when we are silent, we are still afraid. So it is better to speak.", - "author": "Audre Lorde" - } -] - diff --git a/llms.txt b/llms.txt deleted file mode 100644 index 7badd91..0000000 --- a/llms.txt +++ /dev/null @@ -1,25 +0,0 @@ -# llms.txt -# Instructions for Large Language Models on how to handle this site’s content. -# This file is non-standard and may not be respected by all crawlers. - -# General policy: -# Options: allow / disallow / limited -policy: allow - -# Attribution: -# If using excerpts, always attribute content to this site. -attribution: required - -# Commercial use: -# Disallow training or fine-tuning on this content for commercial purposes. -commercial-use: disallow - -# Research use: -# Allow non-commercial, research-based usage. -research-use: allow - -# Contact for permissions: -contact: hello@augustusyuan.com - -# Last updated: -last-modified: 2025-08-23 \ No newline at end of file diff --git a/package.json b/package.json index 21069f3..5e35df4 100644 --- a/package.json +++ b/package.json @@ -1,42 +1,21 @@ { "name": "augbog.github.io", + "private": true, "version": "1.0.0", - "description": "Augustus Yuan's personal website", - "repository": "augbog.github.io", - "author": "Augustus Yuan", + "type": "module", "scripts": { - "build": "gulp svgstore sass scripts", - "dev": "gulp" - }, - "devDependencies": { - "autoprefixer": "^6.4.0", - "babel-eslint": "^4.1.6", - "beepbeep": "~1.2.0", - "browser-sync": "^2.7.1", - "colors": "~1.1.2", - "eslint": "^6.7.2", - "eslint-plugin-react": "^3.11.3", - "gulp": "^3.8.11", - "gulp-browserify": "^0.5.1", - "gulp-eslint": "^1.1.1", - "gulp-inject": "^4.0.0", - "gulp-jsonlint": "^1.1.2", - "gulp-minify-css": "^1.1.1", - "gulp-notify": "^2.2.0", - "gulp-plumber": "~1.0.1", - "gulp-postcss": "^6.1.1", - "gulp-rename": "^1.2.2", - "gulp-replace": "^0.5.4", - "gulp-sass": "^2.1.1", - "gulp-sourcemaps": "^1.6.0", - "gulp-svgmin": "^1.2.2", - "gulp-svgstore": "^6.0.0", - "gulp-uglify": "^1.2.0", - "merge-stream": "^1.0.1", - "path": "^0.11.14" + "dev": "vite", + "build": "vite build", + "preview": "vite preview" }, "dependencies": { - "@tweenjs/tween.js": "^17.2.0", - "konami-komando": "^1.0.1" + "react": "^19.1.1", + "react-dom": "^19.1.1" + }, + "devDependencies": { + "autoprefixer": "^10.4.20", + "postcss": "^8.5.6", + "tailwindcss": "^3.4.17", + "vite": "^7.1.3" } } diff --git a/postcss.config.js b/postcss.config.js new file mode 100644 index 0000000..2aa7205 --- /dev/null +++ b/postcss.config.js @@ -0,0 +1,6 @@ +export default { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +}; diff --git a/public/CNAME b/public/CNAME new file mode 100644 index 0000000..9a6c58e --- /dev/null +++ b/public/CNAME @@ -0,0 +1 @@ +augustusyuan.com \ No newline at end of file diff --git a/quotes.html b/quotes.html deleted file mode 100644 index 7ea033e..0000000 --- a/quotes.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - - Augustus Yuan - - - - -
- -

-

-
- - - \ No newline at end of file diff --git a/sass/mixins/_breakpoint.scss b/sass/mixins/_breakpoint.scss deleted file mode 100644 index f10e9d2..0000000 --- a/sass/mixins/_breakpoint.scss +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Breakpoint mixin that will apply specific styles depending on - * screen size - * - * @param: target screen size - **/ - -@mixin breakpoint($size) { - @media only screen and (max-width: $size + px) { @content; } -} \ No newline at end of file diff --git a/sass/modules/_extras.scss b/sass/modules/_extras.scss deleted file mode 100644 index 6229810..0000000 --- a/sass/modules/_extras.scss +++ /dev/null @@ -1,37 +0,0 @@ -.animate-link { - border-bottom: 0.5px solid transparent; - &:hover { - cursor: pointer; - transition: border-color 0.5s ease-in 0s; - border-color: rgba(0,0,0,0.2); - } -} - -body { - transition: all 0.5s ease-in 0s; -} - -@mixin darkMode { - color: white !important; - font-weight: 800 !important; - - .github, .mail-icon { - use { - fill: white !important; - } - } - - .content { - background: transparent !important; - } - - .job-title, .description, .email { - font-weight: 400 !important; - } -} - -@media (prefers-color-scheme: dark) { - body { - @include darkMode(); - } -} \ No newline at end of file diff --git a/sass/modules/_header.scss b/sass/modules/_header.scss deleted file mode 100644 index 45c22c6..0000000 --- a/sass/modules/_header.scss +++ /dev/null @@ -1,63 +0,0 @@ -/** - * Header styles - **/ - - header { - font-family: "Helvetica Neue", helvetica, arial, sans-serif; - -webkit-font-smoothing: antialiased; - text-rendering: optimizeLegibility; - font-weight: 200; - - position: absolute; - top: 0; - width: 100%; - height: auto; - z-index: 3; - - @include breakpoint(600) { - text-align: center; - } - - .header-container { - display: flex; - - margin: 0px 20px; - } - - .left-align { - align-self: flex-start; - } - - .right-align { - margin-left: auto; - } - - .secondary-nav { - line-height: 22px; - } - - .mail-icon { - width: 15px; - height: 22px; // set the height so it vertically aligns - vertical-align: bottom; - } - - li { - display: inline-block; - height: auto; - - margin: 0px 20px; - - &:first-child { - margin-left: 0; - } - - &:last-child { - margin-right: 0; - } - } - - .profile { - border-radius: 50%; - } -} \ No newline at end of file diff --git a/sass/modules/_hero.scss b/sass/modules/_hero.scss deleted file mode 100644 index 4668def..0000000 --- a/sass/modules/_hero.scss +++ /dev/null @@ -1,126 +0,0 @@ -/** - * Hero styles - **/ - -.hero { - -webkit-font-smoothing: antialiased; - text-rendering: optimizeLegibility; - font-family: "Helvetica Neue", helvetica, arial, sans-serif; - position: relative; - overflow: hidden; - - .content { - position: fixed; - text-align: center; - width: 100%; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - background: rgba(255,255,255,0.7); - padding: 20px 0px; - } - - .heading { - max-width: 80%; - margin-left: auto; - margin-right: auto; - font-size: 36px; - font-weight: 400; - letter-spacing: -0.5px; - margin-bottom: 5px; - - &.quote { - font-size: 26px; - max-width: 60%; - - @include breakpoint(600) { - font-size: 24px; - max-width: 80%; - } - } - } - - .job-title { - font-size: 20px; - font-weight: 200; - margin-bottom: 10px; - vertical-align: middle; - } - - .description { - font-size: 20px; - font-weight: 200; - margin: 0 0 20px 0; - } - - svg { - width: inherit; - height: inherit; - } - - .icon { - display: inline-block; - width: 20px; - height: 20px; - margin: 0px 10px; - - &:hover, &:focus { - transition: transform 0.1s ease-out 0s; - transform: scale(1.2); - } - - @include breakpoint(600) { - width: 30px; - height: 30px; - } - } - - .evernote { - display: inline-block; - width: 25px; - height: 25px; - fill: #666; - vertical-align: bottom; - - &:hover, &:focus { - transition: transform 0.1s ease-out 0s; - transform: scale(1.2); - } - } - - .twitch { - display: inline-block; - width: 25px; - height: 25px; - fill: #9146ff; - vertical-align: bottom; - - &:hover, &:focus { - transition: transform 0.1s ease-out 0s; - transform: scale(1.2); - } - } - - .twitter { - fill: #5EA9DD; - } - - .linkedin { - fill: #0077B5; - } -} - -.profile { - width: 100px; - border-radius: 50%; -} - -.score { - font-family: monospace; - font-size: 30px; - font-weight: 800; -} - -.js-score-hidden { - display: none; -} \ No newline at end of file diff --git a/sass/modules/_reset.scss b/sass/modules/_reset.scss deleted file mode 100644 index 21bc1d4..0000000 --- a/sass/modules/_reset.scss +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Reset styles on DOM elements so we can properly - * style them - **/ - -body, h1, h2 { - margin: 0; -} - -ul { - padding: 0; -} - -li { - list-style-type: none; -} - -a, a:link, a:visited { - color: inherit; - text-decoration: none; - border-bottom: 1px solid transparent; -} \ No newline at end of file diff --git a/sass/style.scss b/sass/style.scss deleted file mode 100644 index 949a252..0000000 --- a/sass/style.scss +++ /dev/null @@ -1,14 +0,0 @@ -/** - * Main Stylesheet file for augbog.github.io - */ - -// Mixins -@import "mixins/breakpoint"; - -// Modular styles -@import "modules/header"; -@import "modules/hero"; - -// Other styles -@import "modules/reset"; -@import "modules/extras"; \ No newline at end of file diff --git a/site.webmanifest b/site.webmanifest deleted file mode 100644 index 45dc8a2..0000000 --- a/site.webmanifest +++ /dev/null @@ -1 +0,0 @@ -{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} \ No newline at end of file diff --git a/src/App.jsx b/src/App.jsx new file mode 100644 index 0000000..55936d7 --- /dev/null +++ b/src/App.jsx @@ -0,0 +1,101 @@ +import { useEffect, useRef } from 'react'; + +const socialLinks = [ + { label: 'Twitter', href: 'https://mobile.twitter.com/augburto' }, + { label: 'GitHub', href: 'https://github.com/augbog' }, + { label: 'LinkedIn', href: 'https://www.linkedin.com/in/augustusyuan' }, + { label: 'Stack Overflow', href: 'https://stackoverflow.com/users/1168661/aug' }, +]; + +function AnimatedPatternCanvas() { + const canvasRef = useRef(null); + + useEffect(() => { + const canvas = canvasRef.current; + const context = canvas?.getContext('2d'); + + if (!canvas || !context) { + return undefined; + } + + let animationFrameId; + let width = window.innerWidth; + let height = window.innerHeight; + const pixelRatio = Math.min(window.devicePixelRatio || 1, 2); + + const setCanvasSize = () => { + width = window.innerWidth; + height = window.innerHeight; + canvas.width = Math.floor(width * pixelRatio); + canvas.height = Math.floor(height * pixelRatio); + canvas.style.width = `${width}px`; + canvas.style.height = `${height}px`; + context.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0); + }; + + const drawPattern = (time) => { + const t = time * 0.001; + const spacing = 48; + + context.clearRect(0, 0, width, height); + + for (let x = -spacing; x < width + spacing; x += spacing) { + for (let y = -spacing; y < height + spacing; y += spacing) { + const waveX = Math.sin((x * 0.012) + t * 1.2); + const waveY = Math.cos((y * 0.012) - t * 0.9); + const offset = (waveX + waveY) * 8; + const radius = 1.5 + ((waveX + 1) * 2.2); + + const alpha = 0.14 + ((waveY + 1) / 2) * 0.18; + context.beginPath(); + context.fillStyle = `rgba(34, 211, 238, ${alpha.toFixed(3)})`; + context.arc(x + offset, y - offset, radius, 0, Math.PI * 2); + context.fill(); + } + } + + animationFrameId = window.requestAnimationFrame(drawPattern); + }; + + setCanvasSize(); + animationFrameId = window.requestAnimationFrame(drawPattern); + window.addEventListener('resize', setCanvasSize); + + return () => { + window.cancelAnimationFrame(animationFrameId); + window.removeEventListener('resize', setCanvasSize); + }; + }, []); + + return