The goal of this task is to implement the following flow in a Next.js application.
- A user selects a local image file.
- The app loads that image, divides the image into tiles, computes the average colour of each tile, fetches a tile from the server for that colour, and composites the results into a photomosaic of the original image.
- The composited photomosaic should be displayed according to the following
constraints:
- tiles should be rendered a complete row at a time (a user should never see a row with some completed tiles and some incomplete)
- the mosaic should be rendered from the top row to the bottom row.
- The client app should make effective use of parallelism and asynchrony.
- Yarn
- Node.js 14.x (Or LTS)
# ensure you have the prerequisites
# install
brew install node && brew install yarn
# OR update
brew update && brew upgrade && brew install yarn
# install dependencies
yarn install
# dev
yarn devClone the repository to your local machine using the command git clone https://github.com/willdunlop/next-mosaic.git
Once you have cloned the repo, move into the project directory with cd ./next-mosaic.
Simply run npm install to begin installing the dependencies defined within the package.json file.
To build the project, simply run npm run build and Nextjs will begin it's build process. This will provide you with a production ready build which can be launched in the next step.
In order for environemnet variables to be exposed to the app, a copy of the file .env.example must be made. This file can be found in the root of the project and it's copy needs to be renamed to .env.local. env.local must also reside in the root of the project.
Running the command npm start will serve a production build of the app which can then be visited by going to http://localhost:3000 in your web browser.
Run npm run dev if you wish to use the project in develop mode. This can also be visited by going to http://localhost:3000 in your web browser.
The project skeleton contains the following:
- A quick Next.js boilerplate with Tailwind
- A fastify server for serving the client app and the tile images.
- An api route (
/api/colour/hex) serving an SVG mosaic tile for the desired colour. e.g,/api/colour/F00F00
Note: The tile size should be configurable via the environment variables in .env.local, feel free to move it to a shared constant file if you prefer.
The project is already set up to include those in both the client and the server. The default size is 16x16.
You should:
- pretend you're submitting this as production-quality code for review; i.e.,
- write effective comments;
- make the code modular;
- make the code testable;
- Browser APIs are sufficient for the exercise.
- use HTML5 features where appropriate;
- Allocate about ~3 hours to do the task.
You may:
- Use a caching strategy where appropriate;
- use any HTML5 feature supported by current Chrome (e.g., Promise, Worker);
- Be as creative as you like with the submission UI (file input, drag & drop, etc); however, it is not the focus of the task, a minimal UI is fine.
Have fun!