Skip to content

Commit

Permalink
Merge pull request #2 from EricRovell/harmonies
Browse files Browse the repository at this point in the history
Harmonies plugin implementation
  • Loading branch information
EricRovell authored Jul 23, 2021
2 parents 1f386a9 + eaf9255 commit 1405768
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 3 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Blossom Changelog

## 1.2.0 (2021-07-23)

- *Harmonies* plugin implementation;

## 1.1.0 (2021-07-22)

- **Plugin API** implementation;
Expand Down
41 changes: 41 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,47 @@ export const pluginHarmonyColors: Plugin = (BaseClass): void => {
}
```
### Included plugins
<details>
<summary>
<code>
Harmonies
</code>
</summary>
Provides functionatity to generate [harmony colors](https://en.wikipedia.org/wiki/Harmony_(color)).
```js
import { blossom, extends } from "blossom";
import { harmonies } from "blossom/plugins/harmonies";

const color = blossom("FF0000");

color.harmonies("analogous")
.map(color => color.hex); // -> [ "#FF0080", "#FF0000", "#FF8000"]
color.harmonies("complimentary")
.map(color => color.hex); // -> [ "#FF0000", "#00FFFF" ]
color.harmonies("rectangle")
.map(color => color.hex); // -> [ "#FF0000", "#FFFF00", "#00FFFF", "#0000FF" ]
color.harmonies("tetradic")
.map(color => color.hex); // -> [ "#FF0000", "#80FF00", "#00FFFF", "#8000FF" ]
color.harmonies("triadic" )
.map(color => color.hex); // -> [ "#FF0000", "#00FF00", "#0000FF" ]
color.harmonies("splitcomplimentary")
.map(color => color.hex); // -> [ "#FF0000", "#00FF80", "#0080FF" ]
```
Harmony color schemes is available as type:
```ts
import type { Harmony } from "blossom/plugins/harmonies";

const harmony: Harmony = "analogous";
const notHarmony: Harmony = "round"; // TypeError
```
</details>
## Types
Blossom is written in strict TypeScript and ships with types in the library itself.
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@ericrovell/blossom",
"version": "1.1.0",
"version": "1.2.0",
"description": "Blossom is a JS library tool for colour manipulations and transformations.",
"main": "./index.js",
"module": "./index.js",
Expand Down Expand Up @@ -48,7 +48,8 @@
"^@util/(.*)": "<rootDir>/src/util/$1",
"^@models/(.*)": "<rootDir>/src/models/$1",
"^@manipulation": "<rootDir>/src/manipulation/index.ts",
"^@properties": "<rootDir>/src/properties/index.ts"
"^@properties": "<rootDir>/src/properties/index.ts",
"^@plugins/(.*)": "<rootDir>/src/plugins/$1"
},
"testEnvironment": "node"
},
Expand Down
20 changes: 19 additions & 1 deletion rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,34 @@ function getPluginsConfig(compilerOptions) {
];
}

const plugins = [
"harmonies"
];

/**
* Bundle everything into ESM module.
*/
export default [
/**
* Core bundle build in ESM
*/
{
input: "src/index.ts",
output: {
file: "dist/index.js",
format: "es"
},
plugins: getPluginsConfig({ declaration: true })
}
},
/**
* Plugins bundles build in ESM
*/
...plugins.map(name => ({
input: `src/plugins/${name}.ts`,
output: {
file: `dist/plugins/${name}.js`,
format: "es"
},
plugins: getPluginsConfig({ declaration: false })
}))
];
36 changes: 36 additions & 0 deletions src/plugins/harmonies.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import type { Plugin } from "@types";

export type Harmony =
| "analogous"
| "complimentary"
| "rectangle"
| "tetradic"
| "triadic"
| "splitcomplimentary";

declare module "blossom" {
interface Blossom {
/**
* Returns an array of harmony colors as `blossom` instances.
*/
harmonies(type: Harmony): Blossom[];
}
}

export const pluginHarmonies: Plugin = (BaseClass): void => {
/**
* All harmony colors are just hue-shifted colors of particular angles.
*/
const hueShifts: Record<Harmony, number[]> = {
analogous: [ -30, 0, 30 ],
complimentary: [ 0, 180 ],
rectangle: [ 0, 60, 180, 240 ],
tetradic: [ 0, 90, 180, 270 ],
triadic: [ 0, 120, 240 ],
splitcomplimentary: [ 0, 150, 210 ]
};

BaseClass.prototype.harmonies = function(type = "complimentary") {
return hueShifts[type].map(shift => this.rotate(shift))
}
}
40 changes: 40 additions & 0 deletions tests/plugins.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { blossom } from "@/blossom";
import { extend } from "@/extend";
import { pluginHarmonies } from "@plugins/harmonies";

describe("Harmony colors plugin", () => {
extend([ pluginHarmonies ]);

const color = blossom("#FF0000");

it("Generates analogous colors", () => {
expect(color.harmonies("analogous").map(value => value.hex)).toEqual([
"#FF0080", "#FF0000", "#FF8000"
]);
});
it("Generates complimentary colors", () => {
expect(color.harmonies("complimentary").map(value => value.hex)).toEqual([
"#FF0000", "#00FFFF"
]);
});
it("Generates rectangle colors", () => {
expect(color.harmonies("rectangle").map(value => value.hex)).toEqual([
"#FF0000", "#FFFF00", "#00FFFF", "#0000FF"
]);
});
it("Generates tetradic colors", () => {
expect(color.harmonies("tetradic").map(value => value.hex)).toEqual([
"#FF0000", "#80FF00", "#00FFFF", "#8000FF"
]);
});
it("Generates triadic colors", () => {
expect(color.harmonies("triadic").map(value => value.hex)).toEqual([
"#FF0000", "#00FF00", "#0000FF"
]);
});
it("Generates splitcomplimentary colors", () => {
expect(color.harmonies("splitcomplimentary").map(value => value.hex)).toEqual([
"#FF0000", "#00FF80", "#0080FF"
]);
});
});

0 comments on commit 1405768

Please sign in to comment.