diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
deleted file mode 100644
index 31822eeb..00000000
--- a/.github/workflows/lint.yml
+++ /dev/null
@@ -1,15 +0,0 @@
-name: Lint
-
-on: [push]
-
-jobs:
- vue-cli:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v1
- - name: Install
- run: |
- npm ci
- - name: Lint
- run: |
- npm run lint
\ No newline at end of file
diff --git a/.github/workflows/npm-deploy.yml b/.github/workflows/npm-deploy.yml
index 93e1e837..a006afab 100644
--- a/.github/workflows/npm-deploy.yml
+++ b/.github/workflows/npm-deploy.yml
@@ -9,16 +9,16 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v1
- - name: Install
- run: |
- npm ci
- - name: Build
- run: |
- npm run build
- - name: Publish
- run: |
- echo "//registry.npmjs.org/:_authToken=$NPM_AUTH_TOKEN" > .npmrc
- npm publish || true
- env:
- NPM_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }}
\ No newline at end of file
+ - uses: actions/checkout@v1
+ - name: Install
+ run: |
+ npm ci
+ - name: Build
+ run: |
+ npm run build
+ - name: Publish
+ run: |
+ echo "//registry.npmjs.org/:_authToken=$NPM_AUTH_TOKEN" > .npmrc
+ npm publish || true
+ env:
+ NPM_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }}
diff --git a/.github/workflows/push-process-todo-comments.yml b/.github/workflows/push-process-todo-comments.yml
index a5bb81e4..190b2575 100644
--- a/.github/workflows/push-process-todo-comments.yml
+++ b/.github/workflows/push-process-todo-comments.yml
@@ -13,4 +13,4 @@ jobs:
uses: dtinth/todo-actions@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- TODO_ACTIONS_MONGO_URL: ${{ secrets.TODO_ACTIONS_MONGO_URL }}
\ No newline at end of file
+ TODO_ACTIONS_MONGO_URL: ${{ secrets.TODO_ACTIONS_MONGO_URL }}
diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml
new file mode 100644
index 00000000..b3ed9b36
--- /dev/null
+++ b/.github/workflows/push.yml
@@ -0,0 +1,25 @@
+name: Push
+
+on: [push]
+
+jobs:
+ lint:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v1
+ - name: Install
+ run: |
+ npm ci
+ - name: Lint
+ run: |
+ npm run lint
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v1
+ - name: Install
+ run: |
+ npm ci
+ - name: Build
+ run: |
+ npm run build
diff --git a/.mergify.yml b/.mergify.yml
index 75f4a442..717506e0 100644
--- a/.mergify.yml
+++ b/.mergify.yml
@@ -3,7 +3,7 @@ pull_request_rules:
conditions:
- author=greenkeeper[bot]
- label~=greenkeeper
- - status-success~=Lint
+ - status-success~=Push
- status-success~=WIP
actions:
merge:
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 00000000..65300ef2
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,19 @@
+# 0.3.0
+
+**Additions**
+
+- add native WebComponents support including attribute type conversion.
+
+**Changes**
+
+- added `options` attribute where all options (`colorLeft`, `colorRight`, ...) now must be placed in. The old Attributes were removed.
+
+# 0.2.0
+
+**Fixes**
+
+- channel value `[1,1]` was not reachable. The top center value is therefore now `[1,1]`
+
+# 0.1.0
+
+- Initial Release, may be buggy, unstable and not ready for production until version 1.0.0 is reached.
diff --git a/README.md b/README.md
index 0097b1e2..da7089bd 100644
--- a/README.md
+++ b/README.md
@@ -2,11 +2,25 @@
> A simple two channel Color Picker
-![two channel picker screenshot](docs/img/screenshot.png)
+## About
+
+I needed an intuitive color picker to control my warm-white-cold-white (WWCW) LED Strips with the [SmartLight Project](https://github.com/adrianjost/SmartLight-Web-Client).
+
+
+
+
+
+The picker value is therefore indepent from the displayed color. The given value is a number between 0 and 1 for each of the two channels. The brightness can be determined by dragging the slider along the Y-axis. Dragging along the X-axis changes the relationship between the two channels.
+
+
+
+
## Usage
-### 1. Install
+### Vue
+
+Install the package:
```bash
npm i @adrianjost/two-channel-picker
@@ -18,29 +32,74 @@ or
yarn add @adrianjost/two-channel-picker
```
-### 2. Usage in Component (Vue)
+In your App:
```vue
-
+
+```
+
+### As a native Web Component
+
+```html
+
+
+
+
+
+
+
-```
\ No newline at end of file
+```
+
+> please note, that you may need to adjust the version number in the url.
+
+## API
+
+### Props
+
+You can customize the picker with the following props/attributes.
+
+> When using the lib as a web component you must provide all attributes `JSON.stringify()`-ed.
+
+| attribute | type | default value | description |
+| --- | --- | --- | --- |
+| `value` / `v-model` | Array, String | `[1,0]` | the current channel values, if provided as a String, this must be `JSON.parse()`-able |
+| `options` | Object | `{}` | all your config goes in here |
+
+#### Options
+
+Available Attributes in the `options` prop:
+
+| attribute | type | default value | description |
+| --- | --- | --- | --- |
+| `readOnly` | Boolean | `false` | should the user be able to move the marker? |
+| `colorLeft` | String | `#fd9` | the color in the top left corner. Must be in the HEX Format with 3 or 6 digits. |
+| `colorRight` | String | `#fd9` | the color in the top right corner. Must be in the HEX Format with 3 or 6 digits. |
+| `marker.borderWidth` | Number | `2` | The border width of the active marker in px. |
+| `marker.radius` | Number | `16` | The border radius including the borderWidth in px. |
+
+You need more options? Please open an issue and I will do my best to implement it. Pull Requests are also welcome!
diff --git a/docs/img/screenshot.png b/docs/img/screenshot.png
index 49a99d21..bc694728 100644
Binary files a/docs/img/screenshot.png and b/docs/img/screenshot.png differ
diff --git a/docs/img/values.png b/docs/img/values.png
new file mode 100644
index 00000000..aa5c0311
Binary files /dev/null and b/docs/img/values.png differ
diff --git a/package-lock.json b/package-lock.json
index 4e3a0ea2..679fd18f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "@adrianjost/two-channel-picker",
- "version": "0.1.0",
+ "version": "0.3.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -13888,7 +13888,8 @@
"vue": {
"version": "2.6.10",
"resolved": "https://registry.npmjs.org/vue/-/vue-2.6.10.tgz",
- "integrity": "sha512-ImThpeNU9HbdZL3utgMCq0oiMzAkt1mcgy3/E6zWC/G6AaQoeuFdsl9nDhTDU3X1R6FK7nsIUuRACVcjI+A2GQ=="
+ "integrity": "sha512-ImThpeNU9HbdZL3utgMCq0oiMzAkt1mcgy3/E6zWC/G6AaQoeuFdsl9nDhTDU3X1R6FK7nsIUuRACVcjI+A2GQ==",
+ "dev": true
},
"vue-eslint-parser": {
"version": "2.0.3",
diff --git a/package.json b/package.json
index c6fddb85..80ba3072 100644
--- a/package.json
+++ b/package.json
@@ -1,16 +1,19 @@
{
"name": "@adrianjost/two-channel-picker",
- "version": "0.2.0",
+ "version": "0.3.0",
"author": "Adrian Jost (https://adrianjost.dev)",
"scripts": {
"lint": "vue-cli-service lint",
- "build": "vue-cli-service build --target lib --name TwoChannelPicker ./src/TwoChannelPicker.vue --mode production --dest dist/lib",
+ "build:vue": "vue-cli-service build --target lib --name TwoChannelPicker ./src/TwoChannelPicker.vue --mode production --dest dist/lib",
+ "build:wc": "vue-cli-service build --target wc --inline-vue --name two-channel-picker ./src/TwoChannelPicker.vue --dest dist/wc",
+ "build": "run-p build:*",
"dev": "vue-cli-service serve"
},
- "dependencies": {
+ "peerDependencies": {
"vue": "^2.6.10"
},
"devDependencies": {
+ "vue": "^2.6.10",
"@vue/cli-plugin-babel": "^3.7.0",
"@vue/cli-plugin-eslint": "^3.8.0",
"@vue/cli-service": "^4.0.0",
@@ -39,7 +42,10 @@
"last 2 versions"
],
"files": [
- "dist/lib/*"
+ "dist/*",
+ "docs/*",
+ "LICENSE",
+ "README.md"
],
"gitHooks": {
"pre-commit": "lint-staged"
diff --git a/src/Dev.vue b/src/Dev.vue
index 9084269a..658ce719 100644
--- a/src/Dev.vue
+++ b/src/Dev.vue
@@ -1,7 +1,7 @@
diff --git a/src/TwoChannelPicker.vue b/src/TwoChannelPicker.vue
index 09e4020e..c6f965c8 100644
--- a/src/TwoChannelPicker.vue
+++ b/src/TwoChannelPicker.vue
@@ -22,6 +22,7 @@
:style="{
background: currentColor,
transform: translate,
+ ...getMarkerStyles(_options),
}"
/>
@@ -39,20 +40,13 @@ export default {
mixins: [colorConversion],
props: {
value: {
- type: Array,
+ type: [Array, String],
default: () => [1, 0],
validator: (v) => v[0] >= 0 && v[0] <= 1 && v[1] >= 0 && v[1] <= 1,
},
- colorLeft: {
- type: String,
- default: "#fd9",
- },
- colorRight: {
- type: String,
- default: "#9df",
- },
- readOnly: {
- type: Boolean,
+ options: {
+ type: Object,
+ default: () => ({}),
},
},
data() {
@@ -70,12 +64,22 @@ export default {
},
};
},
- animation: {
- animationFrame: undefined,
- changeTimeout: undefined,
- hasChangedLately: false,
- },
computed: {
+ _options() {
+ return {
+ colorLeft: "#fd9",
+ colorRight: "#9df",
+ readOnly: false,
+ marker: {
+ radius: 16,
+ borderWidth: 2,
+ },
+ ...this.getTypesafeAttr(this.options),
+ };
+ },
+ typeSafeValue() {
+ return this.getTypesafeAttr(this.value);
+ },
currentColor() {
return this.getColorForPosition({
x: this.marker.x,
@@ -86,8 +90,8 @@ export default {
return this.getTranslate(this.marker.x, this.marker.y);
},
colorMid() {
- const cA = this.hex2rgb(this.colorLeft);
- const cB = this.hex2rgb(this.colorRight);
+ const cA = this.hex2rgb(this._options.colorLeft);
+ const cB = this.hex2rgb(this._options.colorRight);
const maxColor = (v1, v2) => {
const s = v1 + v2;
return s > 255 ? 255 : s;
@@ -99,7 +103,7 @@ export default {
});
},
backgroundGradient() {
- return `linear-gradient(to right, ${this.colorLeft} 0%, ${this.colorMid} 50%, ${this.colorRight} 100%)`;
+ return `linear-gradient(to right, ${this._options.colorLeft} 0%, ${this.colorMid} 50%, ${this._options.colorRight} 100%)`;
},
},
watch: {
@@ -107,7 +111,7 @@ export default {
const channels = this.getChannelsForPosition(this.marker);
this.$emit("input", channels);
},
- value: {
+ typeSafeValue: {
immediate: true,
handler(values) {
if (this.$options.hasChangedLately) {
@@ -126,30 +130,49 @@ export default {
},
},
},
+ animation: {
+ animationFrame: undefined,
+ changeTimeout: undefined,
+ hasChangedLately: false,
+ },
mounted() {
window.addEventListener("resize", this.resize);
- this.resize();
+ setTimeout(this.resize, 0);
},
methods: {
+ getTypesafeAttr(value) {
+ try {
+ if (typeof value === "string") {
+ return JSON.parse(value);
+ } else {
+ return value;
+ }
+ } catch (error) {
+ console.error(error);
+ }
+ console.error("unable to type convert attribute");
+ return value;
+ },
/*
START MARKER POSITIONING
*/
start(event) {
- if (this.readOnly) {
+ if (this._options.readOnly) {
return;
}
+ this.resize();
this.dragActive = true;
this.move(event);
},
end(event) {
- if (this.readOnly) {
+ if (this._options.readOnly) {
return;
}
this.move(event);
this.dragActive = false;
},
move(event) {
- if (this.readOnly) {
+ if (this._options.readOnly) {
return;
}
// event.preventDefault();
@@ -174,6 +197,7 @@ export default {
this.frame.minY = boundingBox.top;
this.frame.maxX = boundingBox.right;
this.frame.maxY = boundingBox.bottom;
+ this.$forceUpdate();
},
_getEventPosition(event) {
// mouse
@@ -205,7 +229,7 @@ export default {
END MARKER POSITIONING
*/
/*
- START MARKER COLOR
+ START MARKER STYLES
*/
getColorBetweenColors(colorA, colorB, position) {
const cA = this.hex2rgb(colorA);
@@ -221,14 +245,14 @@ export default {
let newColor;
if (x < 0.5) {
newColor = this.getColorBetweenColors(
- this.colorLeft,
+ this._options.colorLeft,
this.colorMid,
x * 2
);
} else {
newColor = this.getColorBetweenColors(
this.colorMid,
- this.colorRight,
+ this._options.colorRight,
(x - 0.5) * 2
);
}
@@ -237,8 +261,17 @@ export default {
newColor.b = Math.round(newColor.b * y);
return this.rgb2hex(newColor);
},
+ getMarkerStyles(options) {
+ const { radius, borderWidth } = options.marker;
+ return {
+ padding: `${radius - borderWidth}px`,
+ "margin-bottom": `${-radius}px`,
+ "margin-left": `${-radius}px`,
+ "border-width": `${borderWidth}px`,
+ };
+ },
/*
- END MARKER COLOR
+ END MARKER STYLES
*/
/* START V-MODEL CALCULATIONS */
getChannelsForPosition({ x, y }) {
@@ -286,9 +319,6 @@ $borderWidth: 2px;
left: 0;
z-index: 2;
display: inline-block;
- padding: ($height / 2) - $borderWidth;
- margin-bottom: -($height / 2);
- margin-left: -($height / 2);
border: $borderWidth solid var(--color-border-i, #fff);
border-radius: 50%;