canvas-color-disc 1.1.2 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2018 Vasco Asturiano
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2018 Vasco Asturiano
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,87 +1,81 @@
1
- <!--
2
- * @Descripttion:
3
- * @version:
4
- * @Author: chengzan
5
- * @Date: 2021-10-16 15:40:48
6
- * @LastEditors: Please set LastEditors
7
- * @LastEditTime: 2021-10-16 17:04:00
8
- -->
9
- # production
10
-
11
- > 一个Vue的canvas色盘选择组件,支持移动端和PC端
12
-
13
-
14
- ![avatar](https://udfs.unisiot.com/group1/M00/03/85/rBEBA2FqlXOAfw1hAAECEWBl9Kc837.png)
15
-
16
- <img src="https://udfs.unisiot.com/group1/M00/03/85/rBEBA2FqlXOAfw1hAAECEWBl9Kc837.png" width="50%">
17
-
18
- ## Build Setup
19
-
20
- ``` bash
21
- # install dependencies
22
- npm i canvas-color-disc --save
23
- ```
24
- yarn
25
- ``` bash
26
- # install dependencies
27
- yarn add canvas-color-disc
28
- ```
29
- main.js添加组件
30
- ```
31
- import CanvasColorDisc from 'canvas-color-disc'
32
- Vue.use(CanvasColorDisc)
33
-
34
- ```
35
-
36
- ```vue
37
- <template>
38
- <div id="app">
39
- <p>RGB: {{RGB}}</p>
40
- <p>Hex: {{Hex}}</p>
41
- <CanvasColorDisc
42
- id="0"
43
- :color="RGB"
44
- :width="300"
45
- :height="240"
46
- @change="changeColor"></CanvasColorDisc>
47
- </div>
48
- </template>
49
-
50
- <script>
51
- export default {
52
- name: 'App',
53
- data() {
54
- return {
55
- // RGB: { r: 255, g:255, b:255 },
56
- RGB: '#ff0000',
57
- Hex: '',
58
- }
59
- },
60
- methods: {
61
- changeColor(newRgb, utils) {
62
- this.RGB = newRgb
63
- this.Hex = `#${utils.RGBToHex(`(${newRgb.r}, ${newRgb.g}, ${newRgb.b})`)}`.toUpperCase()
64
- },
65
- },
66
- }
67
- </script>
68
-
69
- <style>
70
- html {
71
- font-family: "Microsoft Sans Serif", Arial, Helvetica, sans-serif
72
- }
73
- </style>
74
- ```
75
-
76
- | 参数 | 说明 | 类型 | 默认值 |
77
- | ------------- | ----------- | ----------------------------------------------- | ------ |
78
- | id | canvas id拼接 | String | "0" |
79
- | color | 默认颜色 | Object | String(如:"#FF0000") | {"r": 255, "g": 255, "b": 255} |
80
- | width | canvas画板宽度 | Number | window.innerWidth * 0.7 |
81
- | height | canvas画板高度 | Number | window.innerWidth * 0.78 |
82
-
83
-
84
-
85
- | 事件 | 说明 | 回调参数 |
86
- | ------------- | ----------- | ----------------------------------------------- |
87
- | change | 选择结束回调 | rgb: 颜色, Util: 内置util,可以转换颜色(Util.hvsToRGB、Util.RGBToHvs、Util.RGBToHex、Util.hexToRGB、Util.RGBToHsv、Util.hsvToRgb) |
1
+ # canvas-color-disc
2
+
3
+ > 一个基于 Vue + Canvas 的圆形色盘选择组件,支持移动端和 PC 端
4
+
5
+
6
+ ![avatar](https://udfs.unisiot.com/group1/M00/03/85/rBEBA2FqlXOAfw1hAAECEWBl9Kc837.png)
7
+
8
+ <img src="https://udfs.unisiot.com/group1/M00/03/85/rBEBA2FqlXOAfw1hAAECEWBl9Kc837.png" width="50%">
9
+
10
+ ## Build Setup
11
+
12
+ ``` bash
13
+ # install dependencies
14
+ npm install
15
+ ```
16
+
17
+ ``` bash
18
+ # serve examples at localhost:5173
19
+ npm run dev
20
+ ```
21
+
22
+ ``` bash
23
+ # library build (ES + UMD) to dist/
24
+ npm run build
25
+ ```
26
+
27
+ ## 使用
28
+
29
+ ```vue
30
+ <template>
31
+ <div id="app">
32
+ <p>RGB: {{ rgb }}</p>
33
+ <canvas-color-disc
34
+ v-model="rgb"
35
+ :width="300"
36
+ :height="300"
37
+ @change="onChange"
38
+ />
39
+ </div>
40
+ </template>
41
+
42
+ <script>
43
+ export default {
44
+ data () {
45
+ return {
46
+ rgb: { r: 255, g: 255, b: 255 }
47
+ }
48
+ },
49
+ methods: {
50
+ onChange (rgb) {
51
+ console.log('change:', rgb)
52
+ }
53
+ }
54
+ }
55
+ </script>
56
+ ```
57
+
58
+ ## API
59
+
60
+ ### Props
61
+
62
+ | 参数 | 说明 | 类型 | 默认值 |
63
+ | --- | --- | --- | --- |
64
+ | value | 当前颜色,支持 `v-model` | Object `{ r, g, b }` | `{ r: 255, g: 255, b: 255 }` |
65
+ | width | 画布宽度(CSS 像素) | Number | 300 |
66
+ | height | 画布高度(CSS 像素) | Number | 300 |
67
+
68
+ ### Events
69
+
70
+ | 事件名 | 说明 | 回调参数 |
71
+ | --- | --- | --- |
72
+ | input | 颜色变化时实时触发(配合 `v-model` 使用) | `{ r, g, b }` |
73
+ | change | 一次选择(拖动/点击)结束时触发 | `{ r, g, b }` |
74
+
75
+ ### 说明
76
+
77
+ - 色盘为 HSV 模型:色相取角度、饱和度取离圆心的半径比例,明度固定为最高,圆心为白色
78
+ - `width`/`height` 为画布逻辑尺寸(CSS 像素),色盘半径自动按 `min(width, height) / 2 - 18` 适配,圆心居中
79
+ - 取色坐标会自动换算回画布逻辑坐标:即使画布被外部 CSS 缩放(如全局 `canvas { max-width: 100% }`、父容器压缩、transform 缩放),取色位置仍与视觉位置一致
80
+ - 点击或拖动超出色盘范围时,选择器会钉在圆周上(取圆周对应位置的颜色)
81
+ - 基于 Pointer Events,鼠标与触摸的操作方式一致
@@ -0,0 +1,228 @@
1
+ var T = Object.defineProperty;
2
+ var _ = Object.getOwnPropertySymbols;
3
+ var U = Object.prototype.hasOwnProperty, k = Object.prototype.propertyIsEnumerable;
4
+ var P = (t, e, s) => e in t ? T(t, e, { enumerable: !0, configurable: !0, writable: !0, value: s }) : t[e] = s, C = (t, e) => {
5
+ for (var s in e || (e = {}))
6
+ U.call(e, s) && P(t, s, e[s]);
7
+ if (_)
8
+ for (var s of _(e))
9
+ k.call(e, s) && P(t, s, e[s]);
10
+ return t;
11
+ };
12
+ function D(t, e, s) {
13
+ const o = (t % 360 + 360) % 360, n = e / 100, i = s / 100, a = Math.floor(o / 60), c = o / 60 - a, r = i * (1 - n), h = i * (1 - n * c), g = i * (1 - n * (1 - c));
14
+ let u = 0, d = 0, l = 0;
15
+ switch (a) {
16
+ case 0:
17
+ u = i, d = g, l = r;
18
+ break;
19
+ case 1:
20
+ u = h, d = i, l = r;
21
+ break;
22
+ case 2:
23
+ u = r, d = i, l = g;
24
+ break;
25
+ case 3:
26
+ u = r, d = h, l = i;
27
+ break;
28
+ case 4:
29
+ u = g, d = r, l = i;
30
+ break;
31
+ default:
32
+ u = i, d = r, l = h;
33
+ }
34
+ return {
35
+ r: Math.round(u * 255),
36
+ g: Math.round(d * 255),
37
+ b: Math.round(l * 255)
38
+ };
39
+ }
40
+ function z(t, e, s) {
41
+ const o = t / 255, n = e / 255, i = s / 255, a = Math.max(o, n, i), c = Math.min(o, n, i), r = a - c;
42
+ let h = 0;
43
+ return r !== 0 && (a === o ? h = 60 * ((n - i) / r % 6) : a === n ? h = 60 * ((i - o) / r + 2) : h = 60 * ((o - n) / r + 4), h < 0 && (h += 360)), {
44
+ h,
45
+ s: a === 0 ? 0 : r / a * 100,
46
+ v: a * 100
47
+ };
48
+ }
49
+ function $(t, e, s, o, n) {
50
+ const i = t - s, a = e - o, c = Math.sqrt(i * i + a * a);
51
+ let r = -Math.atan2(a, i) * 180 / Math.PI;
52
+ return r < 0 && (r += 360), {
53
+ h: r,
54
+ s: n === 0 ? 0 : Math.min(c / n, 1) * 100,
55
+ dist: c
56
+ };
57
+ }
58
+ function A(t, e, s, o, n) {
59
+ const i = -t * Math.PI / 180, a = e / 100 * n;
60
+ return {
61
+ x: s + Math.cos(i) * a,
62
+ y: o + Math.sin(i) * a
63
+ };
64
+ }
65
+ function X(t, e, s, o, n) {
66
+ const i = t.canvas, a = i.width, c = i.height, r = e * n, h = s * n, g = o * n, u = g * g, d = new Array(360);
67
+ for (let f = 0; f < 360; f++)
68
+ d[f] = D(f, 100, 100);
69
+ const l = t.createImageData(a, c), v = l.data;
70
+ for (let f = 0; f < c; f++) {
71
+ const m = f - h, O = m * m;
72
+ for (let b = 0; b < a; b++) {
73
+ const w = b - r, x = w * w + O;
74
+ if (x > u)
75
+ continue;
76
+ const p = (f * a + b) * 4, R = Math.sqrt(x) / g;
77
+ let I = -Math.atan2(m, w) * 180 / Math.PI;
78
+ I < 0 && (I += 360);
79
+ const M = d[Math.round(I) % 360];
80
+ v[p] = 255 + (M.r - 255) * R, v[p + 1] = 255 + (M.g - 255) * R, v[p + 2] = 255 + (M.b - 255) * R, v[p + 3] = 255;
81
+ }
82
+ }
83
+ t.putImageData(l, 0, 0);
84
+ }
85
+ function Y(t, e, s, o, n, i, a, c) {
86
+ var r = typeof t == "function" ? t.options : t;
87
+ return e && (r.render = e, r.staticRenderFns = s, r._compiled = !0), r._scopeId = "data-v-" + i, {
88
+ exports: t,
89
+ options: r
90
+ };
91
+ }
92
+ const q = 15, E = 12, N = 18, F = 8;
93
+ function S(t) {
94
+ const e = t || {};
95
+ return {
96
+ r: typeof e.r == "number" ? e.r : 255,
97
+ g: typeof e.g == "number" ? e.g : 255,
98
+ b: typeof e.b == "number" ? e.b : 255
99
+ };
100
+ }
101
+ function B(t, e) {
102
+ return !!t && !!e && t.r === e.r && t.g === e.g && t.b === e.b;
103
+ }
104
+ const j = {
105
+ name: "CanvasColorDisc",
106
+ props: {
107
+ // 当前颜色 {r, g, b},支持 v-model
108
+ value: {
109
+ type: Object,
110
+ default: () => ({ r: 255, g: 255, b: 255 })
111
+ },
112
+ // 画布宽高(CSS 像素)
113
+ width: {
114
+ type: Number,
115
+ default: 300
116
+ },
117
+ height: {
118
+ type: Number,
119
+ default: 300
120
+ }
121
+ },
122
+ data() {
123
+ return {
124
+ rgb: S(this.value),
125
+ centerX: 0,
126
+ centerY: 0,
127
+ radius: 0,
128
+ dragging: !1
129
+ };
130
+ },
131
+ watch: {
132
+ value: {
133
+ deep: !0,
134
+ handler(t) {
135
+ B(t, this.rgb) || (this.rgb = S(t), this.drawSelector());
136
+ }
137
+ },
138
+ width() {
139
+ this.rebuildCanvas();
140
+ },
141
+ height() {
142
+ this.rebuildCanvas();
143
+ }
144
+ },
145
+ mounted() {
146
+ this.canvasRect = null, this.rafId = 0, typeof ResizeObserver != "undefined" && (this.canvasResizeObserver = new ResizeObserver(() => {
147
+ this.canvasRect = null;
148
+ }), this.canvasResizeObserver.observe(this.$refs.selectorCanvas)), this.rebuildCanvas();
149
+ },
150
+ beforeDestroy() {
151
+ this.rafId && (cancelAnimationFrame(this.rafId), this.rafId = 0), this.canvasResizeObserver && (this.canvasResizeObserver.disconnect(), this.canvasResizeObserver = null);
152
+ },
153
+ methods: {
154
+ // 初始化画布尺寸并重绘色盘与选择器
155
+ rebuildCanvas() {
156
+ this.$nextTick(() => {
157
+ this.setupCanvas(), this.drawSelector();
158
+ });
159
+ },
160
+ setupCanvas() {
161
+ const t = window.devicePixelRatio || 1, e = this.$refs.discCanvas, s = this.$refs.selectorCanvas;
162
+ [e, s].forEach((n) => {
163
+ n.style.width = this.width + "px", n.style.height = this.height + "px", n.width = Math.round(this.width * t), n.height = Math.round(this.height * t);
164
+ }), this.centerX = this.width / 2, this.centerY = this.height / 2, this.radius = Math.max(Math.min(this.width, this.height) / 2 - N, 1), this.discCtx = e.getContext("2d"), this.selectorCtx = s.getContext("2d"), this.discCtx.setTransform(t, 0, 0, t, 0, 0), this.selectorCtx.setTransform(t, 0, 0, t, 0, 0), X(this.discCtx, this.centerX, this.centerY, this.radius, t), this.canvasRect = null;
165
+ },
166
+ // 绘制选择器圆环
167
+ drawSelector() {
168
+ const t = this.selectorCtx;
169
+ if (!t)
170
+ return;
171
+ const e = z(this.rgb.r, this.rgb.g, this.rgb.b), s = A(e.h, e.s, this.centerX, this.centerY, this.radius);
172
+ t.clearRect(0, 0, this.width, this.height), t.save(), t.shadowOffsetX = 1, t.shadowOffsetY = 3, t.shadowColor = "rgba(100, 100, 100, 0.5)", t.shadowBlur = 5, t.beginPath(), t.arc(s.x, s.y, q, 0, Math.PI * 2), t.fillStyle = "#eee", t.fill(), t.restore(), t.save(), t.beginPath(), t.arc(s.x, s.y, E, 0, Math.PI * 2), t.fillStyle = "rgb(" + this.rgb.r + ", " + this.rgb.g + ", " + this.rgb.b + ")", t.fill(), t.restore();
173
+ },
174
+ onPointerDown(t) {
175
+ t.preventDefault();
176
+ const e = this.$refs.selectorCanvas;
177
+ this.canvasRect = e.getBoundingClientRect(), this.dragging = !0;
178
+ try {
179
+ e.setPointerCapture(t.pointerId);
180
+ } catch (s) {
181
+ }
182
+ this.pickColor(t.clientX, t.clientY);
183
+ },
184
+ onPointerMove(t) {
185
+ this.dragging && this.pickColor(t.clientX, t.clientY);
186
+ },
187
+ onPointerUp() {
188
+ this.dragging && (this.dragging = !1, this.flushUpdate(), this.$emit("change", C({}, this.rgb)));
189
+ },
190
+ // 根据触点坐标更新当前颜色
191
+ pickColor(t, e) {
192
+ this.canvasRect || (this.canvasRect = this.$refs.selectorCanvas.getBoundingClientRect());
193
+ const s = this.canvasRect;
194
+ if (!s || s.width === 0 || s.height === 0)
195
+ return;
196
+ const o = (t - s.left) * this.width / s.width, n = (e - s.top) * this.height / s.height, i = $(o, n, this.centerX, this.centerY, this.radius);
197
+ this.rgb = i.dist < F ? { r: 255, g: 255, b: 255 } : D(i.h, i.s, 100), this.scheduleUpdate();
198
+ },
199
+ // 用 requestAnimationFrame 合并高频的 pointermove 更新
200
+ scheduleUpdate() {
201
+ this.rafId || (this.rafId = requestAnimationFrame(() => {
202
+ this.rafId = 0, this.drawSelector(), this.$emit("input", C({}, this.rgb));
203
+ }));
204
+ },
205
+ // 立即提交尚未执行的更新(交互结束时调用)
206
+ flushUpdate() {
207
+ this.rafId && (cancelAnimationFrame(this.rafId), this.rafId = 0, this.drawSelector(), this.$emit("input", C({}, this.rgb)));
208
+ }
209
+ }
210
+ };
211
+ var H = function() {
212
+ var e = this, s = e._self._c;
213
+ return s("div", { staticClass: "canvas-color-disc" }, [s("canvas", { ref: "discCanvas", staticClass: "disc-canvas", attrs: { width: e.width, height: e.height } }), s("canvas", { ref: "selectorCanvas", staticClass: "disc-canvas disc-selector", attrs: { width: e.width, height: e.height }, on: { pointerdown: e.onPointerDown, pointermove: e.onPointerMove, pointerup: e.onPointerUp, pointercancel: e.onPointerUp } })]);
214
+ }, L = [], G = /* @__PURE__ */ Y(
215
+ j,
216
+ H,
217
+ L,
218
+ !1,
219
+ null,
220
+ "e9569c49"
221
+ );
222
+ const y = G.exports;
223
+ y.install = (t) => {
224
+ t.component(y.name, y);
225
+ };
226
+ export {
227
+ y as default
228
+ };
@@ -0,0 +1 @@
1
+ (function(c,h){typeof exports=="object"&&typeof module!="undefined"?module.exports=h():typeof define=="function"&&define.amd?define(h):(c=typeof globalThis!="undefined"?globalThis:c||self,c.CanvasColorDisc=h())})(this,function(){"use strict";var H=Object.defineProperty;var T=Object.getOwnPropertySymbols;var L=Object.prototype.hasOwnProperty,G=Object.prototype.propertyIsEnumerable;var O=(c,h,d)=>h in c?H(c,h,{enumerable:!0,configurable:!0,writable:!0,value:d}):c[h]=d,y=(c,h)=>{for(var d in h||(h={}))L.call(h,d)&&O(c,d,h[d]);if(T)for(var d of T(h))G.call(h,d)&&O(c,d,h[d]);return c};function c(t,e,s){const o=(t%360+360)%360,n=e/100,i=s/100,a=Math.floor(o/60),u=o/60-a,r=i*(1-n),l=i*(1-n*u),p=i*(1-n*(1-u));let v=0,f=0,g=0;switch(a){case 0:v=i,f=p,g=r;break;case 1:v=l,f=i,g=r;break;case 2:v=r,f=i,g=p;break;case 3:v=r,f=l,g=i;break;case 4:v=p,f=r,g=i;break;default:v=i,f=r,g=l}return{r:Math.round(v*255),g:Math.round(f*255),b:Math.round(g*255)}}function h(t,e,s){const o=t/255,n=e/255,i=s/255,a=Math.max(o,n,i),u=Math.min(o,n,i),r=a-u;let l=0;return r!==0&&(a===o?l=60*((n-i)/r%6):a===n?l=60*((i-o)/r+2):l=60*((o-n)/r+4),l<0&&(l+=360)),{h:l,s:a===0?0:r/a*100,v:a*100}}function d(t,e,s,o,n){const i=t-s,a=e-o,u=Math.sqrt(i*i+a*a);let r=-Math.atan2(a,i)*180/Math.PI;return r<0&&(r+=360),{h:r,s:n===0?0:Math.min(u/n,1)*100,dist:u}}function U(t,e,s,o,n){const i=-t*Math.PI/180,a=e/100*n;return{x:s+Math.cos(i)*a,y:o+Math.sin(i)*a}}function k(t,e,s,o,n){const i=t.canvas,a=i.width,u=i.height,r=e*n,l=s*n,p=o*n,v=p*p,f=new Array(360);for(let b=0;b<360;b++)f[b]=c(b,100,100);const g=t.createImageData(a,u),m=g.data;for(let b=0;b<u;b++){const I=b-l,B=I*I;for(let w=0;w<a;w++){const M=w-r,D=M*M+B;if(D>v)continue;const R=(b*a+w)*4,x=Math.sqrt(D)/p;let _=-Math.atan2(I,M)*180/Math.PI;_<0&&(_+=360);const P=f[Math.round(_)%360];m[R]=255+(P.r-255)*x,m[R+1]=255+(P.g-255)*x,m[R+2]=255+(P.b-255)*x,m[R+3]=255}}t.putImageData(g,0,0)}function z(t,e,s,o,n,i,a,u){var r=typeof t=="function"?t.options:t;return e&&(r.render=e,r.staticRenderFns=s,r._compiled=!0),r._scopeId="data-v-"+i,{exports:t,options:r}}const $=15,A=12,X=18,Y=8;function S(t){const e=t||{};return{r:typeof e.r=="number"?e.r:255,g:typeof e.g=="number"?e.g:255,b:typeof e.b=="number"?e.b:255}}function q(t,e){return!!t&&!!e&&t.r===e.r&&t.g===e.g&&t.b===e.b}const E={name:"CanvasColorDisc",props:{value:{type:Object,default:()=>({r:255,g:255,b:255})},width:{type:Number,default:300},height:{type:Number,default:300}},data(){return{rgb:S(this.value),centerX:0,centerY:0,radius:0,dragging:!1}},watch:{value:{deep:!0,handler(t){q(t,this.rgb)||(this.rgb=S(t),this.drawSelector())}},width(){this.rebuildCanvas()},height(){this.rebuildCanvas()}},mounted(){this.canvasRect=null,this.rafId=0,typeof ResizeObserver!="undefined"&&(this.canvasResizeObserver=new ResizeObserver(()=>{this.canvasRect=null}),this.canvasResizeObserver.observe(this.$refs.selectorCanvas)),this.rebuildCanvas()},beforeDestroy(){this.rafId&&(cancelAnimationFrame(this.rafId),this.rafId=0),this.canvasResizeObserver&&(this.canvasResizeObserver.disconnect(),this.canvasResizeObserver=null)},methods:{rebuildCanvas(){this.$nextTick(()=>{this.setupCanvas(),this.drawSelector()})},setupCanvas(){const t=window.devicePixelRatio||1,e=this.$refs.discCanvas,s=this.$refs.selectorCanvas;[e,s].forEach(n=>{n.style.width=this.width+"px",n.style.height=this.height+"px",n.width=Math.round(this.width*t),n.height=Math.round(this.height*t)}),this.centerX=this.width/2,this.centerY=this.height/2,this.radius=Math.max(Math.min(this.width,this.height)/2-X,1),this.discCtx=e.getContext("2d"),this.selectorCtx=s.getContext("2d"),this.discCtx.setTransform(t,0,0,t,0,0),this.selectorCtx.setTransform(t,0,0,t,0,0),k(this.discCtx,this.centerX,this.centerY,this.radius,t),this.canvasRect=null},drawSelector(){const t=this.selectorCtx;if(!t)return;const e=h(this.rgb.r,this.rgb.g,this.rgb.b),s=U(e.h,e.s,this.centerX,this.centerY,this.radius);t.clearRect(0,0,this.width,this.height),t.save(),t.shadowOffsetX=1,t.shadowOffsetY=3,t.shadowColor="rgba(100, 100, 100, 0.5)",t.shadowBlur=5,t.beginPath(),t.arc(s.x,s.y,$,0,Math.PI*2),t.fillStyle="#eee",t.fill(),t.restore(),t.save(),t.beginPath(),t.arc(s.x,s.y,A,0,Math.PI*2),t.fillStyle="rgb("+this.rgb.r+", "+this.rgb.g+", "+this.rgb.b+")",t.fill(),t.restore()},onPointerDown(t){t.preventDefault();const e=this.$refs.selectorCanvas;this.canvasRect=e.getBoundingClientRect(),this.dragging=!0;try{e.setPointerCapture(t.pointerId)}catch(s){}this.pickColor(t.clientX,t.clientY)},onPointerMove(t){this.dragging&&this.pickColor(t.clientX,t.clientY)},onPointerUp(){this.dragging&&(this.dragging=!1,this.flushUpdate(),this.$emit("change",y({},this.rgb)))},pickColor(t,e){this.canvasRect||(this.canvasRect=this.$refs.selectorCanvas.getBoundingClientRect());const s=this.canvasRect;if(!s||s.width===0||s.height===0)return;const o=(t-s.left)*this.width/s.width,n=(e-s.top)*this.height/s.height,i=d(o,n,this.centerX,this.centerY,this.radius);this.rgb=i.dist<Y?{r:255,g:255,b:255}:c(i.h,i.s,100),this.scheduleUpdate()},scheduleUpdate(){this.rafId||(this.rafId=requestAnimationFrame(()=>{this.rafId=0,this.drawSelector(),this.$emit("input",y({},this.rgb))}))},flushUpdate(){this.rafId&&(cancelAnimationFrame(this.rafId),this.rafId=0,this.drawSelector(),this.$emit("input",y({},this.rgb)))}}};var N=function(){var e=this,s=e._self._c;return s("div",{staticClass:"canvas-color-disc"},[s("canvas",{ref:"discCanvas",staticClass:"disc-canvas",attrs:{width:e.width,height:e.height}}),s("canvas",{ref:"selectorCanvas",staticClass:"disc-canvas disc-selector",attrs:{width:e.width,height:e.height},on:{pointerdown:e.onPointerDown,pointermove:e.onPointerMove,pointerup:e.onPointerUp,pointercancel:e.onPointerUp}})])},F=[],j=z(E,N,F,!1,null,"e9569c49");const C=j.exports;return C.install=t=>{t.component(C.name,C)},C});
package/dist/style.css ADDED
@@ -0,0 +1 @@
1
+ .canvas-color-disc[data-v-e9569c49]{position:relative;display:inline-block}.disc-canvas[data-v-e9569c49]{display:block}.disc-selector[data-v-e9569c49]{position:absolute;top:0;left:0;cursor:crosshair;touch-action:none;-webkit-user-select:none;user-select:none}
package/package.json CHANGED
@@ -1,103 +1,63 @@
1
- {
2
- "name": "canvas-color-disc",
3
- "version": "1.1.2",
4
- "description": "Color disc realized by canvas",
5
- "private": false,
6
- "main": "src/index.js",
7
- "scripts": {
8
- "test": "echo \"Error: no test specified\" && exit 1",
9
- "start": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
10
- "lint": "eslint --ext .js,.vue src test/unit test/e2e/specs",
11
- "lintfix": "eslint --fix --ext .js,.vue src test/unit test/e2e/specs",
12
- "build": "node build/build.js"
13
- },
14
- "repository": {
15
- "type": "git",
16
- "url": "git+https://github.com/zancheng/canvas-color-disc.git"
17
- },
18
- "keywords": [
19
- "canvas",
20
- "color",
21
- "disc",
22
- "canvas disc",
23
- "canvas color disc",
24
- "canvas color",
25
- "H5 disc",
26
- "H5 color",
27
- "H5 canvas color",
28
- "H5 canvas color disc"
29
- ],
30
- "author": "chengzan",
31
- "license": "MIT",
32
- "dependencies": {
33
- "vue": "^2.5.2"
34
- },
35
- "devDependencies": {
36
- "autoprefixer": "^7.1.2",
37
- "babel-core": "^6.22.1",
38
- "babel-eslint": "^8.2.1",
39
- "babel-helper-vue-jsx-merge-props": "^2.0.3",
40
- "babel-jest": "^21.0.2",
41
- "babel-loader": "^7.1.1",
42
- "babel-plugin-dynamic-import-node": "^1.2.0",
43
- "babel-plugin-transform-es2015-modules-commonjs": "^6.26.0",
44
- "babel-plugin-transform-runtime": "^6.22.0",
45
- "babel-preset-env": "^1.3.2",
46
- "babel-preset-stage-2": "^6.22.0",
47
- "babel-register": "^6.22.0",
48
- "copy-webpack-plugin": "^4.0.1",
49
- "cross-spawn": "^5.0.1",
50
- "css-loader": "^0.28.0",
51
- "eslint": "^5.0.0",
52
- "eslint-config-standard": "^10.2.1",
53
- "eslint-friendly-formatter": "^3.0.0",
54
- "eslint-loader": "^1.7.1",
55
- "eslint-plugin-import": "^2.7.0",
56
- "eslint-plugin-node": "^5.2.0",
57
- "eslint-plugin-promise": "^3.4.0",
58
- "eslint-plugin-standard": "^3.0.1",
59
- "eslint-plugin-vue": "^5.2.3",
60
- "extract-text-webpack-plugin": "^3.0.0",
61
- "friendly-errors-webpack-plugin": "^1.6.1",
62
- "glob-all": "^3.1.0",
63
- "html-webpack-plugin": "^2.30.1",
64
- "jest": "^22.0.4",
65
- "jest-serializer-vue": "^0.3.0",
66
- "node-notifier": "^5.1.2",
67
- "node-sass": "^4.12.0",
68
- "optimize-css-assets-webpack-plugin": "^3.2.0",
69
- "postcss-import": "^11.0.0",
70
- "postcss-loader": "^2.0.8",
71
- "postcss-url": "^7.2.1",
72
- "purify-css": "^1.2.5",
73
- "purifycss-webpack": "^0.7.0",
74
- "rimraf": "^2.6.0",
75
- "sass-loader": "^7.3.1",
76
- "selenium-server": "^3.0.1",
77
- "semver": "^5.3.0",
78
- "shelljs": "^0.7.6",
79
- "uglifyjs-webpack-plugin": "^1.1.1",
80
- "url-loader": "^0.5.8",
81
- "vue-jest": "^1.0.2",
82
- "vue-loader": "^13.3.0",
83
- "vue-style-loader": "^3.0.1",
84
- "vue-template-compiler": "^2.5.2",
85
- "webpack": "^3.6.0",
86
- "webpack-bundle-analyzer": "^2.9.0",
87
- "webpack-dev-server": "^2.9.1",
88
- "webpack-merge": "^4.1.0"
89
- },
90
- "engines": {
91
- "node": ">= 6.0.0",
92
- "npm": ">= 3.0.0"
93
- },
94
- "browserslist": [
95
- "> 1%",
96
- "last 2 versions",
97
- "not ie <= 8"
98
- ],
99
- "bugs": {
100
- "url": "https://github.com/zancheng/canvas-color-disc/issues"
101
- },
102
- "homepage": "https://github.com/zancheng/canvas-color-disc#readme"
103
- }
1
+ {
2
+ "name": "canvas-color-disc",
3
+ "version": "1.2.0",
4
+ "description": "Color disc realized by canvas",
5
+ "private": false,
6
+ "main": "dist/canvas-color-disc.umd.js",
7
+ "module": "dist/canvas-color-disc.es.js",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/canvas-color-disc.es.js",
11
+ "require": "./dist/canvas-color-disc.umd.js"
12
+ },
13
+ "./dist/style.css": "./dist/style.css"
14
+ },
15
+ "style": "dist/style.css",
16
+ "files": [
17
+ "dist",
18
+ "src"
19
+ ],
20
+ "sideEffects": [
21
+ "*.css"
22
+ ],
23
+ "scripts": {
24
+ "dev": "vite",
25
+ "start": "vite",
26
+ "build": "vite build",
27
+ "preview": "vite preview",
28
+ "lint": "eslint --ext .js,.vue src demo",
29
+ "lintfix": "eslint --fix --ext .js,.vue src demo"
30
+ },
31
+ "repository": {
32
+ "type": "git",
33
+ "url": "git+https://github.com/zancheng/canvas-color-disc.git"
34
+ },
35
+ "keywords": [
36
+ "canvas",
37
+ "color",
38
+ "disc"
39
+ ],
40
+ "author": "chengzan",
41
+ "license": "MIT",
42
+ "peerDependencies": {
43
+ "vue": "^2.5.0"
44
+ },
45
+ "devDependencies": {
46
+ "@vitejs/plugin-vue2": "^2.3.1",
47
+ "babel-eslint": "^8.2.1",
48
+ "eslint": "^5.16.0",
49
+ "eslint-plugin-vue": "^5.2.3",
50
+ "vite": "^5.4.0",
51
+ "vue": "2.7.16"
52
+ },
53
+ "engines": {
54
+ "node": ">= 18"
55
+ },
56
+ "bugs": {
57
+ "url": "https://github.com/zancheng/canvas-color-disc/issues"
58
+ },
59
+ "homepage": "https://github.com/zancheng/canvas-color-disc#readme",
60
+ "allowScripts": {
61
+ "esbuild@0.21.5": true
62
+ }
63
+ }