├── .formatter.exs ├── .gitignore ├── README.md ├── assets ├── .babelrc ├── css │ ├── app.scss │ ├── my_app.css │ └── phoenix.css ├── js │ └── app.js ├── package-lock.json ├── package.json ├── static │ ├── favicon.ico │ ├── images │ │ └── phoenix.png │ └── robots.txt └── webpack.config.js ├── circles1.jpg ├── circles2.jpg ├── config ├── config.exs ├── dev.exs ├── prod.exs ├── prod.secret.exs └── test.exs ├── lib ├── poisson_colors.ex ├── poisson_colors │ ├── application.ex │ └── style.ex ├── poisson_colors_web.ex └── poisson_colors_web │ ├── channels │ └── user_socket.ex │ ├── endpoint.ex │ ├── gettext.ex │ ├── live │ ├── circles_live.ex │ ├── circles_live.html.leex │ ├── page_live.ex │ └── page_live.html.leex │ ├── router.ex │ ├── telemetry.ex │ ├── templates │ ├── layout │ │ ├── app.html.eex │ │ ├── live.html.leex │ │ ├── live_fullscreen.html.leex │ │ └── root.html.leex │ └── svg_template.eex │ └── views │ ├── error_helpers.ex │ ├── error_view.ex │ └── layout_view.ex ├── mix.exs ├── mix.lock ├── priv ├── gettext │ ├── en │ │ └── LC_MESSAGES │ │ │ └── errors.po │ └── errors.pot └── output │ └── .output_dir └── test ├── poisson_colors_web └── views │ ├── error_view_test.exs │ └── layout_view_test.exs ├── support ├── channel_case.ex └── conn_case.ex └── test_helper.exs /.formatter.exs: -------------------------------------------------------------------------------- 1 | [ 2 | import_deps: [:phoenix], 3 | inputs: ["*.{ex,exs}", "{config,lib,test}/**/*.{ex,exs}"] 4 | ] 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # The directory Mix will write compiled artifacts to. 2 | /_build/ 3 | 4 | # If you run "mix test --cover", coverage assets end up here. 5 | /cover/ 6 | 7 | # The directory Mix downloads your dependencies sources to. 8 | /deps/ 9 | 10 | # Where 3rd-party dependencies like ExDoc output generated docs. 11 | /doc/ 12 | 13 | # Ignore .fetch files in case you like to edit your project deps locally. 14 | /.fetch 15 | 16 | # If the VM crashes, it generates a dump, let's ignore it too. 17 | erl_crash.dump 18 | 19 | # Also ignore archive artifacts (built via "mix archive.build"). 20 | *.ez 21 | 22 | # Ignore package tarball (built via "mix hex.build"). 23 | poisson_colors-*.tar 24 | 25 | # If NPM crashes, it generates a log, let's ignore it too. 26 | npm-debug.log 27 | 28 | # The directory NPM downloads your dependencies sources to. 29 | /assets/node_modules/ 30 | 31 | # Since we are building assets from assets/, 32 | # we ignore priv/static. You may want to comment 33 | # this depending on your deployment strategy. 34 | /priv/static/ 35 | 36 | # Output 37 | /priv/output/*.jpg 38 | /priv/output/*.svg 39 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Generating graphics using Elixir, Phoenix LiveView and SVG 2 | 3 | To start your Phoenix server: 4 | 5 | * Install dependencies with `mix deps.get` 6 | * Install Node.js dependencies with `npm install` inside the `assets` directory 7 | * Start Phoenix endpoint with `mix phx.server` 8 | 9 | Now you can visit [`localhost:4000`](http://localhost:4000) from your browser. 10 | 11 | ## The App 12 | 13 | The app **renders circles** according to settings (minimum distance of circles, color, opacity, size). You can even **save the final image as JPG** (and maybe use it 14 | as a wallpaper ;-)). 15 | 16 |  17 | 18 | ## About building this app 19 | 20 | ### It's a Phoenix LiveView project 21 | 22 | New project is created using [Mix](https://hexdocs.pm/phoenix/Mix.Tasks.Phx.New.html): 23 | 24 | `mix phx.new poisson_colors --no-ecto --live` 25 | 26 | ### Poisson disc sampling 27 | 28 | Circles' positions are calculated using 29 | [Poisson disc sampling algorithm](https://github.com/miladamilli/poisson_disc_sampling) 30 | (even random distribution). 31 | 32 | ### UI & updating settings 33 | 34 | Settings are updated using [LiveView](https://hexdocs.pm/phoenix_live_view/Phoenix.LiveView.html)'s 35 | _phx-change_ form event, for example: 36 | 37 | `