@ray-js/lamp-circle-picker 1.0.15-beta.1 → 1.0.16-beta.1
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/lib/component/rjs/index.js +23 -4
- package/lib/component/rjs/index.rjs +43 -43
- package/lib/component/rjs/index.tyml +3 -3
- package/lib/index.js +10 -1
- package/lib/index.less +0 -1
- package/lib/utils/index.d.ts +4 -0
- package/lib/utils/index.js +8 -0
- package/package.json +1 -1
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import Render from './index.rjs';
|
|
2
|
+
function getArcTopPadding(radius, innerRingRadius) {
|
|
3
|
+
let touchCircleLineWidth = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
|
|
4
|
+
return Math.ceil(4 + (innerRingRadius + (radius - innerRingRadius) / 2) + (radius - innerRingRadius - 4) / 2 + (touchCircleLineWidth || 24) / 2 + 4 - radius);
|
|
5
|
+
}
|
|
2
6
|
const ETipRectPosition = {
|
|
3
7
|
LEFT: 'LEFT',
|
|
4
8
|
RIGHT: 'RIGHT'
|
|
@@ -68,7 +72,9 @@ Component({
|
|
|
68
72
|
colorText: '',
|
|
69
73
|
tipRectPosition: ETipRectPosition.LEFT,
|
|
70
74
|
prePowerOff: false,
|
|
71
|
-
preShowMask: false
|
|
75
|
+
preShowMask: false,
|
|
76
|
+
topPadding: 0,
|
|
77
|
+
canvasHeight: 200
|
|
72
78
|
},
|
|
73
79
|
observers: {
|
|
74
80
|
'value.**'(v) {
|
|
@@ -108,9 +114,11 @@ Component({
|
|
|
108
114
|
this.render = new Render(this);
|
|
109
115
|
const {
|
|
110
116
|
radius,
|
|
111
|
-
innerRingRadius
|
|
117
|
+
innerRingRadius,
|
|
118
|
+
touchCircleLineWidth = 0
|
|
112
119
|
} = this.data;
|
|
113
120
|
this.render._setCircles(radius, innerRingRadius);
|
|
121
|
+
this._updateLayoutMetrics(radius, innerRingRadius, touchCircleLineWidth);
|
|
114
122
|
},
|
|
115
123
|
ready() {
|
|
116
124
|
const {
|
|
@@ -152,6 +160,7 @@ Component({
|
|
|
152
160
|
} = this.data;
|
|
153
161
|
this.prePowerOff = inactive;
|
|
154
162
|
this.preShowMask = maskVisible;
|
|
163
|
+
this._updateLayoutMetrics(radius, innerRingRadius, touchCircleLineWidth);
|
|
155
164
|
// 防止重复渲染
|
|
156
165
|
if (this.lastValue === value) {
|
|
157
166
|
return;
|
|
@@ -204,11 +213,21 @@ Component({
|
|
|
204
213
|
rgb
|
|
205
214
|
});
|
|
206
215
|
},
|
|
216
|
+
_updateLayoutMetrics(radius, innerRingRadius) {
|
|
217
|
+
let touchCircleLineWidth = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
|
|
218
|
+
const topPadding = getArcTopPadding(radius, innerRingRadius, touchCircleLineWidth);
|
|
219
|
+
this.setData({
|
|
220
|
+
topPadding,
|
|
221
|
+
canvasHeight: radius * 2 + topPadding,
|
|
222
|
+
centerY: radius + topPadding
|
|
223
|
+
});
|
|
224
|
+
},
|
|
207
225
|
_getLengthByAnglePosition(x, y) {
|
|
208
226
|
const {
|
|
209
|
-
radius
|
|
227
|
+
radius,
|
|
228
|
+
centerY
|
|
210
229
|
} = this.data;
|
|
211
|
-
var radian = Math.atan2(y -
|
|
230
|
+
var radian = Math.atan2(y - centerY, x - radius); // 弧度
|
|
212
231
|
var angle = radian * (180 / Math.PI); // 角度
|
|
213
232
|
let angleData = 0;
|
|
214
233
|
if (+angle > 135 && +angle <= 180) {
|
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
// commonColor.rjs
|
|
2
2
|
const scale = 2;
|
|
3
3
|
|
|
4
|
+
function getArcTopPadding(radius, innerRingRadius, touchCircleLineWidth = 0) {
|
|
5
|
+
const midRadius = innerRingRadius + (radius - innerRingRadius) / 2;
|
|
6
|
+
const thumbDisplayRadius = (radius - innerRingRadius - 4) / 2;
|
|
7
|
+
const shadowDisplay = (touchCircleLineWidth || 24) / 2;
|
|
8
|
+
const strokeHalf = 4;
|
|
9
|
+
const margin = 4;
|
|
10
|
+
return Math.ceil(
|
|
11
|
+
margin + midRadius + thumbDisplayRadius + shadowDisplay + strokeHalf - radius
|
|
12
|
+
);
|
|
13
|
+
}
|
|
14
|
+
|
|
4
15
|
function reverseColorStops(colorStops) {
|
|
5
16
|
if (!Array.isArray(colorStops)) {
|
|
6
17
|
console.error('【ray-circle-picker=> Input parameter must be an array.');
|
|
@@ -398,13 +409,19 @@ export default Render({
|
|
|
398
409
|
this.radius = radius;
|
|
399
410
|
this.innerRingRadius = innerRingRadius;
|
|
400
411
|
|
|
412
|
+
const { touchCircleLineWidth = 0 } = options;
|
|
413
|
+
this.topPadding = getArcTopPadding(radius, innerRingRadius, touchCircleLineWidth);
|
|
414
|
+
this.centerY = radius + this.topPadding;
|
|
415
|
+
this.centerX = radius;
|
|
416
|
+
|
|
401
417
|
const diameter = radius * 2;
|
|
418
|
+
const canvasHeight = diameter + this.topPadding;
|
|
402
419
|
canvas.width = diameter * scale;
|
|
403
|
-
canvas.height =
|
|
420
|
+
canvas.height = canvasHeight * scale;
|
|
404
421
|
const ctx = canvas.getContext('2d');
|
|
405
422
|
|
|
406
|
-
const poxCenterX =
|
|
407
|
-
const poxCenterY =
|
|
423
|
+
const poxCenterX = this.centerX * scale;
|
|
424
|
+
const poxCenterY = this.centerY * scale;
|
|
408
425
|
|
|
409
426
|
const colorList = options.colorList.map(item => {
|
|
410
427
|
return {
|
|
@@ -454,7 +471,7 @@ export default Render({
|
|
|
454
471
|
|
|
455
472
|
ctx.scale(scale, scale);
|
|
456
473
|
canvas.style.width = `${diameter}px`;
|
|
457
|
-
canvas.style.height = `${
|
|
474
|
+
canvas.style.height = `${canvasHeight}px`;
|
|
458
475
|
this.annulusContext = ctx;
|
|
459
476
|
},
|
|
460
477
|
|
|
@@ -515,6 +532,7 @@ export default Render({
|
|
|
515
532
|
_setCircles(radius, innerRingRadius) {
|
|
516
533
|
this.radius = radius;
|
|
517
534
|
this.innerRingRadius = innerRingRadius;
|
|
535
|
+
this.centerX = radius;
|
|
518
536
|
},
|
|
519
537
|
_getAnglePositionByValue(value) {
|
|
520
538
|
const ctx = this.annulusContext;
|
|
@@ -524,14 +542,9 @@ export default Render({
|
|
|
524
542
|
}
|
|
525
543
|
|
|
526
544
|
const angle = 135 + (value / 1000) * 270;
|
|
527
|
-
const
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
Math.cos((angle * Math.PI) / 180);
|
|
531
|
-
const y =
|
|
532
|
-
this.radius +
|
|
533
|
-
(this.innerRingRadius + (this.radius - this.innerRingRadius) / 2) *
|
|
534
|
-
Math.sin((angle * Math.PI) / 180);
|
|
545
|
+
const midRadius = this.innerRingRadius + (this.radius - this.innerRingRadius) / 2;
|
|
546
|
+
const x = this.centerX + midRadius * Math.cos((angle * Math.PI) / 180);
|
|
547
|
+
const y = this.centerY + midRadius * Math.sin((angle * Math.PI) / 180);
|
|
535
548
|
const { data } = ctx.getImageData(Math.round(x * 2), Math.round(y * 2), 1, 1);
|
|
536
549
|
const rgb = { r: data[0], g: data[1], b: data[2] };
|
|
537
550
|
this.updateThumbPosition(x, y, rgb);
|
|
@@ -560,8 +573,9 @@ export default Render({
|
|
|
560
573
|
this.preRgb = rgb;
|
|
561
574
|
}
|
|
562
575
|
let ctx = this.canvasThumbCtx;
|
|
576
|
+
const canvasHeight = this.radius * 2 + (this.topPadding || 0);
|
|
563
577
|
this.canvasThumb.width = this.radius * 4;
|
|
564
|
-
this.canvasThumb.height =
|
|
578
|
+
this.canvasThumb.height = canvasHeight * 2;
|
|
565
579
|
ctx.clearRect(0, 0, this.canvasThumb.width, this.canvasThumb.height);
|
|
566
580
|
ctx.beginPath();
|
|
567
581
|
const radius = this.radius - this.innerRingRadius - 4; // 圆弧半径
|
|
@@ -585,7 +599,7 @@ export default Render({
|
|
|
585
599
|
ctx.stroke();
|
|
586
600
|
ctx.scale(2, 2);
|
|
587
601
|
this.canvasThumb.style.width = `${this.radius * 2}px`;
|
|
588
|
-
this.canvasThumb.style.height = `${
|
|
602
|
+
this.canvasThumb.style.height = `${canvasHeight}px`;
|
|
589
603
|
},
|
|
590
604
|
getAnnulusImageData(x, y) {
|
|
591
605
|
const ctx = this.annulusContext;
|
|
@@ -621,10 +635,12 @@ export default Render({
|
|
|
621
635
|
},
|
|
622
636
|
_getValidMaxMinRes(x, y) {
|
|
623
637
|
const { radius, innerRingRadius } = this;
|
|
624
|
-
const
|
|
625
|
-
const
|
|
638
|
+
const centerX = this.centerX ?? radius;
|
|
639
|
+
const centerY = this.centerY ?? radius;
|
|
640
|
+
const xDistance = Math.abs(x - centerX);
|
|
641
|
+
const yDistance = Math.abs(y - centerY);
|
|
626
642
|
const distance = Math.sqrt(xDistance * xDistance + yDistance * yDistance);
|
|
627
|
-
const radian = Math.atan2(y -
|
|
643
|
+
const radian = Math.atan2(y - centerY, x - centerX);
|
|
628
644
|
let angle = radian * (180 / Math.PI);
|
|
629
645
|
|
|
630
646
|
const mid = 90
|
|
@@ -635,39 +651,23 @@ export default Render({
|
|
|
635
651
|
angle = 135;
|
|
636
652
|
}
|
|
637
653
|
|
|
654
|
+
const midRadius = innerRingRadius + (radius - innerRingRadius) / 2;
|
|
655
|
+
|
|
638
656
|
if (angle < 45 || angle > 135) {
|
|
639
|
-
const thumbPositionY =
|
|
640
|
-
|
|
641
|
-
(innerRingRadius + (radius - innerRingRadius) / 2) *
|
|
642
|
-
Math.sin(Math.atan2(y - radius, x - radius));
|
|
643
|
-
const thumbPositionX =
|
|
644
|
-
radius +
|
|
645
|
-
(innerRingRadius + (radius - innerRingRadius) / 2) *
|
|
646
|
-
Math.cos(Math.atan2(y - radius, x - radius));
|
|
657
|
+
const thumbPositionY = centerY + midRadius * Math.sin(Math.atan2(y - centerY, x - centerX));
|
|
658
|
+
const thumbPositionX = centerX + midRadius * Math.cos(Math.atan2(y - centerY, x - centerX));
|
|
647
659
|
return { x: thumbPositionX, y: thumbPositionY };
|
|
648
660
|
}
|
|
649
661
|
if (angle >= 45 && angle < 80) {
|
|
650
|
-
const
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
Math.sin(Math.atan2(210 - radius, 210 - radius));
|
|
654
|
-
const thumbPositionX =
|
|
655
|
-
radius +
|
|
656
|
-
(innerRingRadius + (radius - innerRingRadius) / 2) *
|
|
657
|
-
Math.cos(Math.atan2(210 - radius, 210 - radius));
|
|
662
|
+
const endpointRadian = (45 * Math.PI) / 180;
|
|
663
|
+
const thumbPositionY = centerY + midRadius * Math.sin(endpointRadian);
|
|
664
|
+
const thumbPositionX = centerX + midRadius * Math.cos(endpointRadian);
|
|
658
665
|
return { x: thumbPositionX, y: thumbPositionY };
|
|
659
666
|
}
|
|
660
667
|
if (angle > 115 && angle <= 135) {
|
|
661
|
-
|
|
662
|
-
const
|
|
663
|
-
const
|
|
664
|
-
|
|
665
|
-
const thumbPositionY =
|
|
666
|
-
radius + (innerRingRadius + (radius - innerRingRadius) / 2) * Math.sin(realAngle);
|
|
667
|
-
|
|
668
|
-
const thumbPositionX =
|
|
669
|
-
radius - (innerRingRadius + (radius - innerRingRadius) / 2) * Math.cos(realAngle);
|
|
670
|
-
|
|
668
|
+
const endpointRadian = (135 * Math.PI) / 180;
|
|
669
|
+
const thumbPositionY = centerY + midRadius * Math.sin(endpointRadian);
|
|
670
|
+
const thumbPositionX = centerX + midRadius * Math.cos(endpointRadian);
|
|
671
671
|
return { x: thumbPositionX, y: thumbPositionY };
|
|
672
672
|
}
|
|
673
673
|
},
|
|
@@ -4,14 +4,14 @@
|
|
|
4
4
|
type="2d"
|
|
5
5
|
canvas-id="{{ canvasId }}"
|
|
6
6
|
disable-scroll="true"
|
|
7
|
-
style="width: {{ radius * 2 }}px; height:
|
|
7
|
+
style="width: {{ radius * 2 }}px; height: {{ canvasHeight }}px;"
|
|
8
8
|
/>
|
|
9
|
-
<view class="lamp-temp-circle-picker-canvasPowerOffMask" style="position: absolute; top: 0; left: 0; width: {{ radius * 2 }}px; height:
|
|
9
|
+
<view class="lamp-temp-circle-picker-canvasPowerOffMask" style="position: absolute; top: 0; left: 0; width: {{ radius * 2 }}px; height: {{ canvasHeight }}px;" ty:if="{{ maskVisible }}" />
|
|
10
10
|
<canvas
|
|
11
11
|
class="lamp-temp-circle-picker-canvasThumbWrapper"
|
|
12
12
|
type="2d"
|
|
13
13
|
canvas-id="{{ canvasId }}_thumb"
|
|
14
14
|
disable-scroll="true"
|
|
15
|
-
style="position: absolute; top: 0; left: 0; width: {{ radius * 2 }}px; height:
|
|
15
|
+
style="position: absolute; top: 0; left: 0; width: {{ radius * 2 }}px; height: {{ canvasHeight }}px;"
|
|
16
16
|
/>
|
|
17
17
|
</view>
|
package/lib/index.js
CHANGED
|
@@ -5,6 +5,8 @@ import { View, Text } from '@ray-js/components';
|
|
|
5
5
|
import clsx from 'clsx';
|
|
6
6
|
import Strings from './i18n';
|
|
7
7
|
import AnnulusPickerColor from './component';
|
|
8
|
+
import { useStdPx2Adapt } from './hooks';
|
|
9
|
+
import { getArcTopPadding } from './utils';
|
|
8
10
|
import './index.less';
|
|
9
11
|
const LampCirclePicker = props => {
|
|
10
12
|
const {
|
|
@@ -38,6 +40,10 @@ const LampCirclePicker = props => {
|
|
|
38
40
|
const [innerCircleColor, setInnerCircleColor] = useState('');
|
|
39
41
|
const innerImgRadius = innerRingRadius * 4 * 0.8;
|
|
40
42
|
const _value = value !== null && value !== void 0 ? value : temperature;
|
|
43
|
+
const adaptedRadius = useStdPx2Adapt(radius);
|
|
44
|
+
const adaptedInnerRingRadius = useStdPx2Adapt(innerRingRadius);
|
|
45
|
+
const adaptedTouchCircleLineWidth = useStdPx2Adapt(touchCircleLineWidth);
|
|
46
|
+
const topPadding = useMemo(() => getArcTopPadding(adaptedRadius, adaptedInnerRingRadius, adaptedTouchCircleLineWidth), [adaptedRadius, adaptedInnerRingRadius, adaptedTouchCircleLineWidth]);
|
|
41
47
|
const canvasId = useMemo(() => {
|
|
42
48
|
return `canvasId_${String(+new Date()).slice(-3)}_${String(Math.random()).slice(-3)}`;
|
|
43
49
|
}, []);
|
|
@@ -54,7 +60,10 @@ const LampCirclePicker = props => {
|
|
|
54
60
|
className: clsx('lamp-temp-circle-picker-container', 'lamp-temp-circle-picker-flexCenter'),
|
|
55
61
|
style: style
|
|
56
62
|
}, showInnerCircle && /*#__PURE__*/React.createElement(View, {
|
|
57
|
-
className: clsx('lamp-temp-circle-picker-innerBox', 'lamp-temp-circle-picker-flexCenter')
|
|
63
|
+
className: clsx('lamp-temp-circle-picker-innerBox', 'lamp-temp-circle-picker-flexCenter'),
|
|
64
|
+
style: {
|
|
65
|
+
transform: `translateY(${topPadding / 2}px)`
|
|
66
|
+
}
|
|
58
67
|
}, /*#__PURE__*/React.createElement(View, {
|
|
59
68
|
className: "lamp-temp-circle-picker-ringIcon",
|
|
60
69
|
style: _objectSpread({
|
package/lib/index.less
CHANGED
package/lib/utils/index.d.ts
CHANGED
|
@@ -9,4 +9,8 @@ export declare const getSystemCacheInfo: () => {
|
|
|
9
9
|
windowWidth: number;
|
|
10
10
|
windowHeight: number;
|
|
11
11
|
};
|
|
12
|
+
/**
|
|
13
|
+
* @brief Compute top padding so thumb shadow is not clipped at 270°
|
|
14
|
+
*/
|
|
15
|
+
export declare function getArcTopPadding(radius: number, innerRingRadius: number, touchCircleLineWidth?: number): number;
|
|
12
16
|
export { rgbToHsl, rgb2hsv, hsv2rgb };
|
package/lib/utils/index.js
CHANGED
|
@@ -48,4 +48,12 @@ export const getSystemCacheInfo = () => {
|
|
|
48
48
|
}
|
|
49
49
|
return __systemCacheInfo;
|
|
50
50
|
};
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* @brief Compute top padding so thumb shadow is not clipped at 270°
|
|
54
|
+
*/
|
|
55
|
+
export function getArcTopPadding(radius, innerRingRadius) {
|
|
56
|
+
let touchCircleLineWidth = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
|
|
57
|
+
return Math.ceil(4 + (innerRingRadius + (radius - innerRingRadius) / 2) + (radius - innerRingRadius - 4) / 2 + (touchCircleLineWidth || 24) / 2 + 4 - radius);
|
|
58
|
+
}
|
|
51
59
|
export { rgbToHsl, rgb2hsv, hsv2rgb };
|