Skip to content

ianpurvis/purvisresearch.com

Repository files navigation

Build Status codecov

Purvis Research

Welcome to the source for my freelance site, built with Nuxt.

Everything gets hosted using a serverless back-end built with AWS Route53, S3, CloudFront, and Lambda.

Please take a look around and get in touch if you have any questions!

Points Of Interest

  • src/pages/index.vue maximizes semantic value by eliminating decoration at the HTML level. To see this in action, visit the live site and disable CSS in your browser. It also uses vue-tight to help preserve readability while controlling whitespace at render.

  • src/components/stretch.vue is a Vue component that watches the DOM to automatically scale its children to fit its own width.

  • src/mixins/pixi-demo.js imports PixiJS dynamically upon component mount, when the necessary browser context has been ensured.

  • src/shims/pixi.js is a module shim that bundles a subset of PixiJS and patches it with @pixi/unsafe-eval for compatibility with strict Content Security Policy.

  • src/models/gltf-loader.js and src/models/texture-loader.js extend their callback-based three.js counterparts with a simple promise API.

  • src/models/draco-loader.js overrides the default three.js DRACOLoader so that it can use a custom decoder module from the webpack build. The javascript interface for the decoder is loaded as a normal webpack chunk while the webassembly binary is loaded as a file asset with hashed url.

  • lib/draco is a custom WebAssembly build of Google's DRACO decoder that uses a fixed 16MB memory space to avoid dynamic allocation costs. It also discards emscripten's legacy browser polyfilling in favor of webpack-managed babel transpilation. Uncompressed, it's about 52K smaller than the copy of DRACO included with three.js. With gzip it's about 20K smaller.

  • bin/fetch-libre-barcode-128-text fetches the font's optimized .woff file from the Google Font API so that it can be included as a webpack build asset. Only glyphs used in page content are included.

  • src/mixins/debug.js provides a layout debug mode that can be enabled by hitting the 'd' key on any page.

  • spec/src/mixins/animatable.spec.js is the behavior spec for src/mixins/animatable.js, a vue mixin that provides a simple render loop interface with interpolated animations. The spec is nothing special, just an example of BDD, unit testing, and mocking with Jest.

  • src/assets/stylesheets/src.scss imports a subset of Bulma for simple style reset and basic design structure.

  • src/assets/shaders/halftone_filter.frag.glsl is a GLSL shader that creates a simple CYMK halftone effect. Based on Stefan Gustavson's WebGL Halftone Shader Tutorial with some modifications for use with three.js.

  • src/assets/models/basket.draco.glb is a 3D model of a small mayan basket that I scanned with Qlone. I simplified the original ~30mb model with Blender and encoded it as a 128k binary GLTF with DRACO compression.

  • lambda/middleware/index.js handles CloudFront Lambda@Edge events to provide redirection and HTTP header management.

  • infra/ contains the terraform configuration that manages the AWS infrastructure for this site. It orchestrates a number of AWS resources including Route53, Certificate Manager, S3, Cloudfront, and Lambda@Edge. Everything is organized and tagged with a human-friendly in the style of heroku.

  • .github/workflows/ci.yml checks the codebase with ESLint and StyleLint, generates the static site with Nuxt, and then executes the Jest test suites and sends code coverage to CodeCov. All build checks are required to pass before a PR is merged.

  • src/workers/dollar-physics-worker.js is a Web Worker interface for managing the ammo.js physics simulation found in src/workers/dollar-physics-worker.worker.js. Messages between the worker thread and main thread use Transferable buffers to maximize performance.

WebGL Experiments

  • src/pages/2020/jul.js is the runtime for 2020 Jul: A Banknote In Simplex Wind

    This banknote is animated with natural physics! I used Emscripten to create a micro version of the ammo.js physics library for this project. The simulation runs in a web worker that shares geometry data with the main thread via fast transferable buffers. For the wind, I mixed three channels of simplex noise to create a constantly changing force across each of the primary axes. Harriet Tubman will be a great face for the $20 bill.

  • src/pages/2019/apr.js is the runtime for 2019 Apr: Surreal WebRTC Television.

    When I’m in Tokyo, I love working out of the space at STUDIA. Check out this cool collaboration with illustrator Hankiti Maeda. Open it in your native browser so that you can use the webcam. You can be on TV day and night!

  • src/pages/2018/oct.js is the runtime for 2018 Oct: Screen Printing A 3D Scan.

    After a long break, I've made some new graphics! Recently I've been obsessed with a small Mayan basket that I bought while traveling in Belize. This project takes a 3D scan of the basket and processes it into a random CMYK print. You can watch it change or get something new each time you load the page.

  • src/pages/2017/nov.js is the runtime for 2017 Nov: A 3D Character Exploder.

    This month was busy, but I was finally able to get a new project done! Better late than never, I guess... Check out these slow motion hypercolor text explosions: each time you load the page you can get a new one.

  • src/pages/2017/oct.js is the runtime for 2017 Oct: A Bézier Moiré Generator.

    This month I built a Bézier curve generator that creates random moiré patterns. You can get something new each time you load the page. This project was inspired by the paintings of Anoka Faruqee, check her out!

  • src/pages/2017/sept.js is the runtime for 2017 Sep: An Emoji Particle Flow.

    Finally have some free time for fun projects! Stay tuned, I am going to try to put something small up each month.