@ray-js/lamp-circle-picker 1.0.12-beta-2 → 1.0.13-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.rjs +127 -63
- package/lib/component/rjs/index.tyss +1 -1
- package/lib/hooks.js +2 -4
- package/lib/utils/index.d.ts +2 -2
- package/package.json +2 -1
|
@@ -129,7 +129,7 @@ export default Render({
|
|
|
129
129
|
return null;
|
|
130
130
|
},
|
|
131
131
|
|
|
132
|
-
|
|
132
|
+
drawRingWithGradientSegments(params) {
|
|
133
133
|
let {
|
|
134
134
|
startAngle,
|
|
135
135
|
endAngle,
|
|
@@ -142,6 +142,7 @@ export default Render({
|
|
|
142
142
|
centerX,
|
|
143
143
|
centerY,
|
|
144
144
|
ringBorderColor,
|
|
145
|
+
lineCap = 'round',
|
|
145
146
|
} = params;
|
|
146
147
|
|
|
147
148
|
// 检查 canvas 和 context
|
|
@@ -258,13 +259,106 @@ export default Render({
|
|
|
258
259
|
ctx.fill();
|
|
259
260
|
ctx.closePath();
|
|
260
261
|
}
|
|
261
|
-
|
|
262
|
+
|
|
263
|
+
// 注意:这里不设置 globalCompositeOperation,让调用方决定是否需要
|
|
264
|
+
// 返回渐变颜色数组,供后续绘制端点使用
|
|
265
|
+
return gradientColors;
|
|
266
|
+
},
|
|
267
|
+
|
|
268
|
+
// 绘制圆形端点以模拟 lineCap: 'round' 效果
|
|
269
|
+
drawRoundEndpoints(params) {
|
|
270
|
+
const {
|
|
271
|
+
ctx,
|
|
272
|
+
centerX,
|
|
273
|
+
centerY,
|
|
274
|
+
innerRadius,
|
|
275
|
+
outerRadius,
|
|
276
|
+
startAngle,
|
|
277
|
+
endAngle,
|
|
278
|
+
gradientColors,
|
|
279
|
+
scale,
|
|
280
|
+
} = params;
|
|
281
|
+
|
|
282
|
+
// 计算端点半径(色环宽度的一半)
|
|
283
|
+
const endpointRadius = ((outerRadius - innerRadius) / 2) * scale;
|
|
284
|
+
// 计算色环中线半径
|
|
285
|
+
const midRadius = (innerRadius + (outerRadius - innerRadius) / 2) * scale;
|
|
286
|
+
|
|
287
|
+
// 起始端点(135度位置)
|
|
288
|
+
const startAngleRad = (startAngle * Math.PI) / 180;
|
|
289
|
+
const startX = centerX + midRadius * Math.cos(startAngleRad);
|
|
290
|
+
const startY = centerY + midRadius * Math.sin(startAngleRad);
|
|
291
|
+
const startColor = gradientColors[1] || gradientColors[0]; // 使用第一个颜色
|
|
292
|
+
|
|
293
|
+
// 结束端点(405度位置)
|
|
294
|
+
const endAngleRad = (endAngle * Math.PI) / 180;
|
|
295
|
+
const endX = centerX + midRadius * Math.cos(endAngleRad);
|
|
296
|
+
const endY = centerY + midRadius * Math.sin(endAngleRad);
|
|
297
|
+
const endColor =
|
|
298
|
+
gradientColors[gradientColors.length - 2] || gradientColors[gradientColors.length - 1]; // 使用最后一个颜色
|
|
299
|
+
|
|
300
|
+
// 重置合成操作以正常绘制端点
|
|
301
|
+
ctx.globalCompositeOperation = 'source-over';
|
|
302
|
+
|
|
303
|
+
// 起始端点 - 使用半圆,封闭色环起点
|
|
304
|
+
// 半圆应该朝向色环外侧(逆时针方向),角度范围是从色环切线的外侧到内侧
|
|
305
|
+
const startHalfCircleStart = startAngleRad - Math.PI; // 色环外侧
|
|
306
|
+
const startHalfCircleEnd = startAngleRad; // 色环内侧
|
|
307
|
+
|
|
308
|
+
ctx.beginPath();
|
|
309
|
+
ctx.arc(startX, startY, endpointRadius, startHalfCircleStart, startHalfCircleEnd, false);
|
|
310
|
+
|
|
311
|
+
// 使用与色环相同的径向渐变
|
|
312
|
+
const startGradient = ctx.createRadialGradient(
|
|
313
|
+
centerX,
|
|
314
|
+
centerY,
|
|
315
|
+
innerRadius * scale,
|
|
316
|
+
centerX,
|
|
317
|
+
centerY,
|
|
318
|
+
outerRadius * scale
|
|
319
|
+
);
|
|
320
|
+
startGradient.addColorStop(0, startColor);
|
|
321
|
+
startGradient.addColorStop(1, startColor);
|
|
322
|
+
|
|
323
|
+
ctx.fillStyle = startGradient;
|
|
324
|
+
ctx.fill();
|
|
325
|
+
ctx.closePath();
|
|
326
|
+
|
|
327
|
+
// 结束端点 - 使用半圆,封闭色环终点
|
|
328
|
+
// 半圆应该朝向色环外侧(顺时针方向),角度范围是从色环切线的内侧到外侧
|
|
329
|
+
const endHalfCircleStart = endAngleRad; // 色环内侧
|
|
330
|
+
const endHalfCircleEnd = endAngleRad + Math.PI; // 色环外侧
|
|
331
|
+
|
|
332
|
+
ctx.beginPath();
|
|
333
|
+
ctx.arc(endX, endY, endpointRadius, endHalfCircleStart, endHalfCircleEnd, false);
|
|
334
|
+
|
|
335
|
+
// 使用与色环相同的径向渐变
|
|
336
|
+
const endGradient = ctx.createRadialGradient(
|
|
337
|
+
centerX,
|
|
338
|
+
centerY,
|
|
339
|
+
innerRadius * scale,
|
|
340
|
+
centerX,
|
|
341
|
+
centerY,
|
|
342
|
+
outerRadius * scale
|
|
343
|
+
);
|
|
344
|
+
endGradient.addColorStop(0, endColor);
|
|
345
|
+
endGradient.addColorStop(1, endColor);
|
|
346
|
+
|
|
347
|
+
ctx.fillStyle = endGradient;
|
|
348
|
+
ctx.fill();
|
|
349
|
+
ctx.closePath();
|
|
262
350
|
},
|
|
263
351
|
|
|
264
352
|
// 环形色盘 降级绘制
|
|
265
353
|
async renderAnnulusColorLowRank(id, radius, innerRingRadius, options = {}) {
|
|
266
354
|
let canvas = null;
|
|
267
|
-
const {
|
|
355
|
+
const {
|
|
356
|
+
touchCircleStrokeStyle,
|
|
357
|
+
ringBorderColor,
|
|
358
|
+
inactive,
|
|
359
|
+
maskVisible,
|
|
360
|
+
lineCap = 'round',
|
|
361
|
+
} = options;
|
|
268
362
|
this.touchCircleStrokeStyle = touchCircleStrokeStyle;
|
|
269
363
|
this.inactive = inactive;
|
|
270
364
|
this.maskVisible = maskVisible;
|
|
@@ -300,7 +394,10 @@ export default Render({
|
|
|
300
394
|
const offsetDegree = 270;
|
|
301
395
|
const endDegree = startDegree + offsetDegree;
|
|
302
396
|
|
|
303
|
-
|
|
397
|
+
// 保存 canvas 状态(在绘制主色环之前)
|
|
398
|
+
ctx.save();
|
|
399
|
+
|
|
400
|
+
const gradientColors = this.drawRingWithGradientSegments({
|
|
304
401
|
startAngle: startDegree,
|
|
305
402
|
endAngle: endDegree,
|
|
306
403
|
offsetDegree,
|
|
@@ -312,17 +409,35 @@ export default Render({
|
|
|
312
409
|
centerX: poxCenterX,
|
|
313
410
|
centerY: poxCenterY,
|
|
314
411
|
ringBorderColor,
|
|
412
|
+
lineCap,
|
|
315
413
|
});
|
|
316
414
|
|
|
415
|
+
// 恢复 canvas 状态(移除裁剪区域)
|
|
416
|
+
ctx.restore();
|
|
417
|
+
|
|
418
|
+
// 绘制圆形端点(在没有裁剪区域限制的情况下)
|
|
419
|
+
if (lineCap === 'round' && gradientColors && gradientColors.length > 0) {
|
|
420
|
+
this.drawRoundEndpoints({
|
|
421
|
+
ctx,
|
|
422
|
+
centerX: poxCenterX,
|
|
423
|
+
centerY: poxCenterY,
|
|
424
|
+
innerRadius: innerRingRadius,
|
|
425
|
+
outerRadius: radius,
|
|
426
|
+
startAngle: startDegree,
|
|
427
|
+
endAngle: endDegree,
|
|
428
|
+
gradientColors,
|
|
429
|
+
scale: scale, // 使用原始 scale
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
|
|
317
433
|
ctx.scale(scale, scale);
|
|
318
434
|
canvas.style.width = `${diameter}px`;
|
|
319
435
|
canvas.style.height = `${diameter}px`;
|
|
320
436
|
this.annulusContext = ctx;
|
|
321
437
|
},
|
|
322
438
|
|
|
323
|
-
// 环形色盘
|
|
439
|
+
// 环形色盘 - 统一使用降级渲染
|
|
324
440
|
async renderAnnulusColor(id, radius, innerRingRadius, temp = 0, options = {}) {
|
|
325
|
-
let canvas = null;
|
|
326
441
|
const {
|
|
327
442
|
touchCircleStrokeStyle = '',
|
|
328
443
|
touchCircleLineWidth = 0,
|
|
@@ -331,70 +446,19 @@ export default Render({
|
|
|
331
446
|
inactive = false,
|
|
332
447
|
maskVisible = false,
|
|
333
448
|
} = options || {};
|
|
449
|
+
|
|
450
|
+
// 设置实例属性
|
|
334
451
|
this.touchCircleStrokeStyle = touchCircleStrokeStyle;
|
|
335
452
|
this.touchCircleLineWidth = touchCircleLineWidth;
|
|
336
453
|
this.hideThumb = hideThumb;
|
|
337
454
|
this.inactive = inactive;
|
|
338
455
|
this.maskVisible = maskVisible;
|
|
339
|
-
|
|
340
|
-
canvas = await getCanvasById(id);
|
|
341
|
-
} catch (error) {
|
|
342
|
-
console.error(error);
|
|
343
|
-
return;
|
|
344
|
-
}
|
|
345
|
-
if (!canvas) {
|
|
346
|
-
console.error('canvas not found');
|
|
347
|
-
return;
|
|
348
|
-
}
|
|
456
|
+
|
|
349
457
|
const { useEventChannel, eventChannelName } = options || {};
|
|
350
458
|
this.useEventChannel = useEventChannel;
|
|
351
459
|
this.eventChannelName = eventChannelName;
|
|
352
|
-
canvas.width = radius * 4;
|
|
353
|
-
canvas.height = radius * 4;
|
|
354
|
-
const ctx = canvas.getContext('2d');
|
|
355
|
-
|
|
356
|
-
const startAngle = Math.PI * 0.75;
|
|
357
|
-
const endAngle = Math.PI * 0.25;
|
|
358
|
-
const counterclockwise = false;
|
|
359
|
-
ctx.beginPath();
|
|
360
|
-
ctx.arc(
|
|
361
|
-
radius * 2,
|
|
362
|
-
radius * 2,
|
|
363
|
-
innerRingRadius * 2 + (radius - innerRingRadius),
|
|
364
|
-
startAngle,
|
|
365
|
-
endAngle,
|
|
366
|
-
counterclockwise
|
|
367
|
-
);
|
|
368
|
-
|
|
369
|
-
let grd = null;
|
|
370
|
-
if (ctx.createConicGradient && lineCap === 'round') {
|
|
371
|
-
try {
|
|
372
|
-
grd = ctx.createConicGradient(startAngle - Math.PI * 0.1, radius * 2, radius * 2);
|
|
373
|
-
options.colorList?.forEach(item => {
|
|
374
|
-
grd.addColorStop(item.offset, item.color);
|
|
375
|
-
});
|
|
376
|
-
//设定曲线粗细度
|
|
377
|
-
ctx.lineWidth = (radius - innerRingRadius) * 2;
|
|
378
|
-
//给曲线着色
|
|
379
|
-
ctx.strokeStyle = grd;
|
|
380
|
-
//连接处样式
|
|
381
|
-
ctx.lineCap = lineCap || 'round';
|
|
382
|
-
//给环着色
|
|
383
|
-
ctx.stroke();
|
|
384
|
-
ctx.closePath();
|
|
385
|
-
ctx.scale(2, 2);
|
|
386
|
-
canvas.style.width = `${radius * 2}px`;
|
|
387
|
-
canvas.style.height = `${radius * 2}px`;
|
|
388
|
-
this.annulusContext = ctx;
|
|
389
|
-
} catch (err) {
|
|
390
|
-
console.error('createConicGradient:', err);
|
|
391
|
-
}
|
|
392
|
-
!this.hideThumb && this.renderAnnulusColorThumb(id, temp);
|
|
393
|
-
this.callMethod('initedCanvas', {});
|
|
394
|
-
return;
|
|
395
|
-
}
|
|
396
460
|
|
|
397
|
-
//
|
|
461
|
+
// 统一使用降级渲染,确保所有机型的一致性
|
|
398
462
|
this.renderAnnulusColorLowRank(id, radius, innerRingRadius, options);
|
|
399
463
|
|
|
400
464
|
!this.hideThumb && this.renderAnnulusColorThumb(id, temp);
|
|
@@ -446,7 +510,7 @@ export default Render({
|
|
|
446
510
|
this.radius +
|
|
447
511
|
(this.innerRingRadius + (this.radius - this.innerRingRadius) / 2) *
|
|
448
512
|
Math.sin((angle * Math.PI) / 180);
|
|
449
|
-
const { data } = ctx.getImageData(x * 2, y * 2, 1, 1);
|
|
513
|
+
const { data } = ctx.getImageData(Math.round(x * 2), Math.round(y * 2), 1, 1);
|
|
450
514
|
const rgb = { r: data[0], g: data[1], b: data[2] };
|
|
451
515
|
this.updateThumbPosition(x, y, rgb);
|
|
452
516
|
const emitRes = {
|
|
@@ -507,7 +571,7 @@ export default Render({
|
|
|
507
571
|
console.error('ctx not found');
|
|
508
572
|
return;
|
|
509
573
|
}
|
|
510
|
-
const { data } = ctx.getImageData(x * 2, y * 2, 1, 1);
|
|
574
|
+
const { data } = ctx.getImageData(Math.round(x * 2), Math.round(y * 2), 1, 1);
|
|
511
575
|
const r = data[0];
|
|
512
576
|
const g = data[1];
|
|
513
577
|
const b = data[2];
|
package/lib/hooks.js
CHANGED
|
@@ -8,8 +8,6 @@ import { getSystemCacheInfo } from './utils';
|
|
|
8
8
|
*/
|
|
9
9
|
export const useStdPx2Adapt = function (stdPx) {
|
|
10
10
|
let toFixed = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 2;
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
} = useMemo(() => getSystemCacheInfo(), [stdPx]);
|
|
14
|
-
return +(stdPx * (screenWidth / 375)).toFixed(toFixed) || stdPx;
|
|
11
|
+
const systemInfo = useMemo(() => getSystemCacheInfo(), [stdPx]);
|
|
12
|
+
return +(stdPx * (systemInfo.windowWidth / 375)).toFixed(toFixed) || stdPx;
|
|
15
13
|
};
|
package/lib/utils/index.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ type HSL = {
|
|
|
6
6
|
};
|
|
7
7
|
declare const rgbToHsl: (r: number, g: number, b: number) => HSL;
|
|
8
8
|
export declare const getSystemCacheInfo: () => {
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
windowWidth: number;
|
|
10
|
+
windowHeight: number;
|
|
11
11
|
};
|
|
12
12
|
export { rgbToHsl, rgb2hsv, hsv2rgb };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ray-js/lamp-circle-picker",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.13-beta-1",
|
|
4
4
|
"description": "照明缺角色环",
|
|
5
5
|
"main": "lib/index",
|
|
6
6
|
"files": [
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
"lint": "eslint src --ext .js,.jsx,.ts,.tsx --fix",
|
|
21
21
|
"dev": "yarn start:tuya",
|
|
22
22
|
"build": "ray build --type=component",
|
|
23
|
+
"build:tuya": "ray build ./example -t tuya",
|
|
23
24
|
"start:tuya": "ray start ./example",
|
|
24
25
|
"prepublishOnly": "yarn build",
|
|
25
26
|
"release-it": "standard-version"
|