npm package: @joostlubach/circles
Description: Daag.
Latest version: 1.4.3

# Circles

Daag.

## Installatie

Om dit programma te installeren moet je eerst NodeJS installeren. Dat kan hier: https://nodejs.org/en/download/.

Als het geïnstalleerd is, open je je Terminal en typ je het volgende commando:

```bash
sudo npm install -g @joostlubach/circles
```

Je wordt dan om je wachtwoord gevraagd. Vanaf dat moment kun je het programma gebruiken zoals hieronder beschreven.

### Upgrades

Als ik een update heb gedaan gebruik je het volgende commando om te upgraden:

```bash
sudo npm upgrade -g @joostlubach/circles
```

## Hoe werkt het

Om het proces te starten typ je `$ circles <in_dir> <out_dir>`. Het proces begint dan te lopen en herstart telkens bij een wijziging in de `in_dir` directory. Deze directory moet tenminste de volgende dingen bevatten:

- Een configuratiebestand `config.yml` (zie hieronder)
- Voor elk invoerkanaal een PNG-bestand

Als het configuratiebestand mist, zal daarvoor een melding worden gegeven, tot het bestand er wel is. Als de configuratie ongeldig is, of er mist tijdens het proces een ander bestand, zal daarvoor ook een reden worden aangegeven. Als de configuratie geldig is en alle bestanden zijn aanwezig, zal de uitvoerdirectory automatisch een SVG voor elk kanaal bevatten, en een composite SVG als dat gewenst is.

> Let op: de bestanden in de uitvoermap worden zomaar overschreven. Zorg dus dat als je tevreden bent met het uitvoerbestand, je deze even kopieert.

## Configuratie

De configuratie is een YAML bestand met de volgende structuur:

```yml
channels:
  # Voor elk kanaal moet hier een entry worden toegevoegd. Er is geen minimum of maxmimum.
  
  # Dit is de naam van het kanaal.
  red:                        
    # Optioneel. Dit is het invoerbestand, relatief aan <in_dir>. Als deze niet wordt opgegeven, wordt <naam>.png aangenomen.
    input: joost.png          
    # Optioneel. Dit is het uitvoerbestand, relatief aan <out_dir>. Als deze niet wordt opgegeven, wordt <naam>.svg aangenomen.
    output: red.svg           
    # De meetwaarde. Zie hieronder voor toegestande waarden.
    measurement: red          
    # Het middelpunt van de cirkels. Geef op als [x, y], waarbij x en y percentages mogen zijn, of absolute pixel aantallen.
    center: [48%, 48%]        
    # De afstand in pixels tussen de middellijnen van de cirkels.
    radius_interval: 20       
    # De afstand bij benadering tussen de meetpunten op een cirkel.
    sample_interval: 20       
    # De minimale meetwaarde. Zie onder voor meer informatie.
    min_value: 0              
    # De maximale meetwaarde. Zie onder voor meer informatie.
    max_value: 1              
    # De minimale cirkeldikte. Zie onder voor meer informatie.
    min_thickness: 0          
    # De maximale cirkeldikte. Zie onder voor meer informatie.
    max_thickness: 0.7        
    # Hier kun je de style opgeven voor de cirkel. Er zijn nogal wat opties (zie https://css-tricks.com/svg-properties-and-css/).
    style:                    
      # De belangrijkste zijn `fill` en eventueel `stroke` en `stroke-width`. Het attribuut `fill` moet geldige een CSS-kleur zijn.
      fill: 'red'             
  green:
    input: joost.png
    measurement: green
    # Kijk hier zijn het gewoon pixels.
    center: [800, 600]        
    # ... Etc.
    style:
      fill: 'green'
  blue:
    input: joost.png
    measurement: green
    # ... Etc.
    style:
      # Kijk, het mag bijvoorbeeld ook een hex-code zijn.
      fill: '#0000FF'

# Dit objectje is optioneel, en zorgt ervoor dat je een composite SVG kan genereren.
composite:
  # Elk item in het lijstje is ofwel zo'n dingetje waarin je ook de blend mode kan opgeeven.
  - {channel: red, mode: multiply}
  # Ofwel gewoon de naam van een kanaal, in welk geval 'multiply' wordt aangenomen voor blend mode.
  - green
  # Kijk, deze gebruikt een andere blend mode. Zie onder voor blend modes.
  - {channel: blue, mode: normal}
```

## Meetwaarden (`measurement`)

Elke meetwaarde wordt genormaliseerd tot een waarde tussen 0 en 1. De mogelijke metingen zijn:

- `red`: De waarde van het RGB-kanaal rood. 
- `green`: De waarde van het RGB-kanaal groen.
- `blue`: De waarde van het RGB-kanaal blauw.
- `alpha`: De waarde van het alfakanaal.
- `rgb`: De totale waarde van de kleur (zwart: 0, wit = 1)
- `luminosity`: De luminosity waarde (https://www.w3.org/TR/WCAG20/#relativeluminancedef).

> Let op dat de meetwaarden (behalve `alpha`) worden geïnverteerd. Dus een `luminosity` van 1 komt overeen met een zo dun mogelijke lijn, waardoor het resultaat wit lijkt.

## Berekening

De berekening gaat als volgt:

1. De meetwaarde wordt bepaald (altijd een getal tussen 0 en 1)
2. De meetwaarde wordt genormaliseerd adhv `min_value` en `max_value`. Bijvoorbeeld, met `min_value: 0.4` en `max_value: 0.6` krijg je bij een waarde van 0.4 en alles eronder de genormaliseerde waarde 0. De waarde 0.45 wordt genormaliseerd tot 0.25, etc. 0.6 en hoger worden genormaliseerd naar 1.
3. Deze genormaliseerde waarde wordt vervolgens omgezet naar een cirkeldikte adhv `min_thickness` en `max_thickness`. Dit zijn ook waardes tussen 0 en 1, en zijn daarmee relatief aan de maximaal mogelijke lijndikte, die weer afhankelijk is van `radius_interval`. Een thickness van 1 betekent dat de volledige tussenruimte wordt opgevuld.
4. Nou tekenen maar

## Blend modes

De volgende blend modes zijn toegestaan. Je weet zelf hoe ze werken.

- `normal`
- `multiply`
- `screen`
- `overlay`
- `darken`
- `lighten`
- `color-dodge`
- `color-burn`
- `hard-light`
- `soft-light`
- `difference`
- `exclusion`
- `hue`
- `saturation`
- `color`
- `luminosity`