@ray-js/lamp-circle-picker 1.0.12-beta-3 → 1.0.13-beta-2
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 +126 -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 +1 -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,105 @@ export default Render({
|
|
|
258
259
|
ctx.fill();
|
|
259
260
|
ctx.closePath();
|
|
260
261
|
}
|
|
261
|
-
|
|
262
|
+
|
|
263
|
+
// 返回渐变颜色数组,供后续绘制端点使用
|
|
264
|
+
return gradientColors;
|
|
265
|
+
},
|
|
266
|
+
|
|
267
|
+
// 绘制圆形端点以模拟 lineCap: 'round' 效果
|
|
268
|
+
drawRoundEndpoints(params) {
|
|
269
|
+
const {
|
|
270
|
+
ctx,
|
|
271
|
+
centerX,
|
|
272
|
+
centerY,
|
|
273
|
+
innerRadius,
|
|
274
|
+
outerRadius,
|
|
275
|
+
startAngle,
|
|
276
|
+
endAngle,
|
|
277
|
+
gradientColors,
|
|
278
|
+
scale,
|
|
279
|
+
} = params;
|
|
280
|
+
|
|
281
|
+
// 计算端点半径(色环宽度的一半)
|
|
282
|
+
const endpointRadius = ((outerRadius - innerRadius) / 2) * scale;
|
|
283
|
+
// 计算色环中线半径
|
|
284
|
+
const midRadius = (innerRadius + (outerRadius - innerRadius) / 2) * scale;
|
|
285
|
+
|
|
286
|
+
// 起始端点(135度位置)
|
|
287
|
+
const startAngleRad = (startAngle * Math.PI) / 180;
|
|
288
|
+
const startX = centerX + midRadius * Math.cos(startAngleRad);
|
|
289
|
+
const startY = centerY + midRadius * Math.sin(startAngleRad);
|
|
290
|
+
const startColor = gradientColors[1] || gradientColors[0]; // 使用第一个颜色
|
|
291
|
+
|
|
292
|
+
// 结束端点(405度位置)
|
|
293
|
+
const endAngleRad = (endAngle * Math.PI) / 180;
|
|
294
|
+
const endX = centerX + midRadius * Math.cos(endAngleRad);
|
|
295
|
+
const endY = centerY + midRadius * Math.sin(endAngleRad);
|
|
296
|
+
const endColor =
|
|
297
|
+
gradientColors[gradientColors.length - 2] || gradientColors[gradientColors.length - 1]; // 使用最后一个颜色
|
|
298
|
+
|
|
299
|
+
// 重置合成操作以正常绘制端点
|
|
300
|
+
ctx.globalCompositeOperation = 'source-over';
|
|
301
|
+
|
|
302
|
+
// 起始端点 - 使用半圆,封闭色环起点
|
|
303
|
+
// 半圆应该朝向色环外侧(逆时针方向),角度范围是从色环切线的外侧到内侧
|
|
304
|
+
const startHalfCircleStart = startAngleRad - Math.PI; // 色环外侧
|
|
305
|
+
const startHalfCircleEnd = startAngleRad; // 色环内侧
|
|
306
|
+
|
|
307
|
+
ctx.beginPath();
|
|
308
|
+
ctx.arc(startX, startY, endpointRadius, startHalfCircleStart, startHalfCircleEnd, false);
|
|
309
|
+
|
|
310
|
+
// 使用与色环相同的径向渐变
|
|
311
|
+
const startGradient = ctx.createRadialGradient(
|
|
312
|
+
centerX,
|
|
313
|
+
centerY,
|
|
314
|
+
innerRadius * scale,
|
|
315
|
+
centerX,
|
|
316
|
+
centerY,
|
|
317
|
+
outerRadius * scale
|
|
318
|
+
);
|
|
319
|
+
startGradient.addColorStop(0, startColor);
|
|
320
|
+
startGradient.addColorStop(1, startColor);
|
|
321
|
+
|
|
322
|
+
ctx.fillStyle = startGradient;
|
|
323
|
+
ctx.fill();
|
|
324
|
+
ctx.closePath();
|
|
325
|
+
|
|
326
|
+
// 结束端点 - 使用半圆,封闭色环终点
|
|
327
|
+
// 半圆应该朝向色环外侧(顺时针方向),角度范围是从色环切线的内侧到外侧
|
|
328
|
+
const endHalfCircleStart = endAngleRad; // 色环内侧
|
|
329
|
+
const endHalfCircleEnd = endAngleRad + Math.PI; // 色环外侧
|
|
330
|
+
|
|
331
|
+
ctx.beginPath();
|
|
332
|
+
ctx.arc(endX, endY, endpointRadius, endHalfCircleStart, endHalfCircleEnd, false);
|
|
333
|
+
|
|
334
|
+
// 使用与色环相同的径向渐变
|
|
335
|
+
const endGradient = ctx.createRadialGradient(
|
|
336
|
+
centerX,
|
|
337
|
+
centerY,
|
|
338
|
+
innerRadius * scale,
|
|
339
|
+
centerX,
|
|
340
|
+
centerY,
|
|
341
|
+
outerRadius * scale
|
|
342
|
+
);
|
|
343
|
+
endGradient.addColorStop(0, endColor);
|
|
344
|
+
endGradient.addColorStop(1, endColor);
|
|
345
|
+
|
|
346
|
+
ctx.fillStyle = endGradient;
|
|
347
|
+
ctx.fill();
|
|
348
|
+
ctx.closePath();
|
|
262
349
|
},
|
|
263
350
|
|
|
264
351
|
// 环形色盘 降级绘制
|
|
265
352
|
async renderAnnulusColorLowRank(id, radius, innerRingRadius, options = {}) {
|
|
266
353
|
let canvas = null;
|
|
267
|
-
const {
|
|
354
|
+
const {
|
|
355
|
+
touchCircleStrokeStyle,
|
|
356
|
+
ringBorderColor,
|
|
357
|
+
inactive,
|
|
358
|
+
maskVisible,
|
|
359
|
+
lineCap = 'round',
|
|
360
|
+
} = options;
|
|
268
361
|
this.touchCircleStrokeStyle = touchCircleStrokeStyle;
|
|
269
362
|
this.inactive = inactive;
|
|
270
363
|
this.maskVisible = maskVisible;
|
|
@@ -300,7 +393,10 @@ export default Render({
|
|
|
300
393
|
const offsetDegree = 270;
|
|
301
394
|
const endDegree = startDegree + offsetDegree;
|
|
302
395
|
|
|
303
|
-
|
|
396
|
+
// 保存 canvas 状态(在绘制主色环之前)
|
|
397
|
+
ctx.save();
|
|
398
|
+
|
|
399
|
+
const gradientColors = this.drawRingWithGradientSegments({
|
|
304
400
|
startAngle: startDegree,
|
|
305
401
|
endAngle: endDegree,
|
|
306
402
|
offsetDegree,
|
|
@@ -312,17 +408,35 @@ export default Render({
|
|
|
312
408
|
centerX: poxCenterX,
|
|
313
409
|
centerY: poxCenterY,
|
|
314
410
|
ringBorderColor,
|
|
411
|
+
lineCap,
|
|
315
412
|
});
|
|
316
413
|
|
|
414
|
+
// 恢复 canvas 状态(移除裁剪区域)
|
|
415
|
+
ctx.restore();
|
|
416
|
+
|
|
417
|
+
// 绘制圆形端点(在没有裁剪区域限制的情况下)
|
|
418
|
+
if (lineCap === 'round' && gradientColors && gradientColors.length > 0) {
|
|
419
|
+
this.drawRoundEndpoints({
|
|
420
|
+
ctx,
|
|
421
|
+
centerX: poxCenterX,
|
|
422
|
+
centerY: poxCenterY,
|
|
423
|
+
innerRadius: innerRingRadius,
|
|
424
|
+
outerRadius: radius,
|
|
425
|
+
startAngle: startDegree,
|
|
426
|
+
endAngle: endDegree,
|
|
427
|
+
gradientColors,
|
|
428
|
+
scale: scale, // 使用原始 scale
|
|
429
|
+
});
|
|
430
|
+
}
|
|
431
|
+
|
|
317
432
|
ctx.scale(scale, scale);
|
|
318
433
|
canvas.style.width = `${diameter}px`;
|
|
319
434
|
canvas.style.height = `${diameter}px`;
|
|
320
435
|
this.annulusContext = ctx;
|
|
321
436
|
},
|
|
322
437
|
|
|
323
|
-
// 环形色盘
|
|
438
|
+
// 环形色盘 - 统一使用降级渲染
|
|
324
439
|
async renderAnnulusColor(id, radius, innerRingRadius, temp = 0, options = {}) {
|
|
325
|
-
let canvas = null;
|
|
326
440
|
const {
|
|
327
441
|
touchCircleStrokeStyle = '',
|
|
328
442
|
touchCircleLineWidth = 0,
|
|
@@ -331,70 +445,19 @@ export default Render({
|
|
|
331
445
|
inactive = false,
|
|
332
446
|
maskVisible = false,
|
|
333
447
|
} = options || {};
|
|
448
|
+
|
|
449
|
+
// 设置实例属性
|
|
334
450
|
this.touchCircleStrokeStyle = touchCircleStrokeStyle;
|
|
335
451
|
this.touchCircleLineWidth = touchCircleLineWidth;
|
|
336
452
|
this.hideThumb = hideThumb;
|
|
337
453
|
this.inactive = inactive;
|
|
338
454
|
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
|
-
}
|
|
455
|
+
|
|
349
456
|
const { useEventChannel, eventChannelName } = options || {};
|
|
350
457
|
this.useEventChannel = useEventChannel;
|
|
351
458
|
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
459
|
|
|
397
|
-
//
|
|
460
|
+
// 统一使用降级渲染,确保所有机型的一致性
|
|
398
461
|
this.renderAnnulusColorLowRank(id, radius, innerRingRadius, options);
|
|
399
462
|
|
|
400
463
|
!this.hideThumb && this.renderAnnulusColorThumb(id, temp);
|
|
@@ -446,7 +509,7 @@ export default Render({
|
|
|
446
509
|
this.radius +
|
|
447
510
|
(this.innerRingRadius + (this.radius - this.innerRingRadius) / 2) *
|
|
448
511
|
Math.sin((angle * Math.PI) / 180);
|
|
449
|
-
const { data } = ctx.getImageData(x * 2, y * 2, 1, 1);
|
|
512
|
+
const { data } = ctx.getImageData(Math.round(x * 2), Math.round(y * 2), 1, 1);
|
|
450
513
|
const rgb = { r: data[0], g: data[1], b: data[2] };
|
|
451
514
|
this.updateThumbPosition(x, y, rgb);
|
|
452
515
|
const emitRes = {
|
|
@@ -507,7 +570,7 @@ export default Render({
|
|
|
507
570
|
console.error('ctx not found');
|
|
508
571
|
return;
|
|
509
572
|
}
|
|
510
|
-
const { data } = ctx.getImageData(x * 2, y * 2, 1, 1);
|
|
573
|
+
const { data } = ctx.getImageData(Math.round(x * 2), Math.round(y * 2), 1, 1);
|
|
511
574
|
const r = data[0];
|
|
512
575
|
const g = data[1];
|
|
513
576
|
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 };
|