@lhs7/wheel-selector
Version:
193 lines (192 loc) • 7.43 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.drawLineFromCenter = exports.drawDragging = exports.drawCancelButton = exports.drawItems = exports.drawItem = exports.clearCanvas = exports.removeCanvas = exports.makeCanvas = void 0;
const whiteColor = "rgba(255, 255, 255, 1)";
const blackColor = "rgba(0, 0, 0, 1)";
const transparentColor = "rgba(0, 0, 0, 0)";
function makeCanvas(pos, size) {
const canvas = document.createElement("canvas");
canvas.style.position = "fixed";
canvas.style.left = `${pos.x - size / 2}px`;
canvas.style.top = `${pos.y - size / 2}px`;
canvas.style.pointerEvents = "none"; // Make sure it doesn't block mouse events
canvas.style.zIndex = "10000";
canvas.width = size;
canvas.height = size;
document.body.appendChild(canvas);
return canvas;
}
exports.makeCanvas = makeCanvas;
function removeCanvas(canvas) {
if (!canvas)
return;
clearCanvas(canvas);
canvas.remove();
}
exports.removeCanvas = removeCanvas;
function clearCanvas(canvas) {
if (!canvas)
return;
const ctx = canvas.getContext("2d");
if (!ctx)
return;
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
exports.clearCanvas = clearCanvas;
function drawItem(selector, itemNo) {
var _a;
const { items, outerDistance, innerDistance, selectedItemNo, cursorCanvas, } = selector;
const { selectedColor, defaultColor } = selector.theme;
if (cursorCanvas === null)
return;
const ctx = cursorCanvas.getContext("2d");
if (!ctx)
return;
if (itemNo === null)
return;
const item = items[itemNo];
const itemCount = items.length;
const angleStep = (2 * Math.PI) / itemCount; // Divide 360 degrees into equal parts
const startAngle = angleStep * itemNo;
const endAngle = startAngle + angleStep;
//Erase outer slice
ctx.globalCompositeOperation = "destination-out";
ctx.beginPath();
ctx.moveTo(outerDistance, outerDistance);
ctx.arc(outerDistance, outerDistance, outerDistance, startAngle, endAngle);
ctx.closePath();
ctx.fillStyle = whiteColor;
ctx.fill();
// Draw the outer slice
ctx.globalCompositeOperation = "source-over";
ctx.beginPath();
ctx.moveTo(outerDistance, outerDistance);
ctx.arc(outerDistance, outerDistance, outerDistance, startAngle, endAngle);
ctx.closePath();
ctx.fillStyle =
selectedItemNo === itemNo ? selectedColor : defaultColor; // Assign item color or default
ctx.fill();
if (selector.items.length > 1) {
ctx.globalCompositeOperation = "source-over";
drawLineFromCenter(cursorCanvas, startAngle, outerDistance, whiteColor);
drawLineFromCenter(cursorCanvas, endAngle, outerDistance, whiteColor);
}
// Add the label
const midAngle = startAngle + angleStep / 2; // Find the midpoint of the slice
const textRadius = (innerDistance + outerDistance) / 2; // Position text between inner and outer radii
const textX = outerDistance + textRadius * Math.cos(midAngle); // X-coordinate for text
const textY = outerDistance + textRadius * Math.sin(midAngle); // Y-coordinate for text
drawText(cursorCanvas, (_a = item.name) !== null && _a !== void 0 ? _a : "", selectedItemNo === itemNo ? blackColor : whiteColor, {
x: textX,
y: textY,
});
//Erase inner slice
ctx.globalCompositeOperation = "destination-out";
ctx.beginPath();
ctx.moveTo(outerDistance, outerDistance);
ctx.arc(outerDistance, outerDistance, innerDistance, 0, Math.PI * 2);
ctx.closePath();
ctx.fillStyle = whiteColor;
ctx.fill();
ctx.globalCompositeOperation = "source-over";
}
exports.drawItem = drawItem;
function drawItems(selector) {
const { cursorCanvas, outerDistance, innerDistance } = selector;
if (cursorCanvas === null)
return;
clearCanvas(cursorCanvas);
selector.items.forEach((_, idx) => drawItem(selector, idx));
drawCircleLine(cursorCanvas, outerDistance, 3, whiteColor);
drawCircleLine(cursorCanvas, innerDistance, 3, whiteColor);
drawCancelButton(selector);
const { lineInfo } = selector;
if (lineInfo) {
drawLineFromCenter(selector.cursorCanvas, lineInfo.angle, Math.min(lineInfo.length, selector.outerDistance), "rgba(255, 255, 255, 1)", 5);
}
}
exports.drawItems = drawItems;
function drawCancelButton(selector) {
const { cursorCanvas } = selector;
if (cursorCanvas === null)
return;
const ctx = cursorCanvas.getContext("2d");
if (!ctx)
return;
const { outerDistance, innerDistance, selectedItemNo } = selector;
const { selectedColor, defaultColor } = selector.theme;
ctx.globalCompositeOperation = "source-over";
ctx.beginPath();
ctx.moveTo(outerDistance, outerDistance);
ctx.arc(outerDistance, outerDistance, innerDistance - 5, 0, Math.PI * 2);
ctx.closePath();
ctx.fillStyle =
selectedItemNo === "CANCEL" ? selectedColor : defaultColor;
ctx.fill();
}
exports.drawCancelButton = drawCancelButton;
function drawDragging(selector) {
var _a;
const { draggingItem, mouseCanvas, dragginIconSize } = selector;
if (mouseCanvas === null || draggingItem === null)
return;
if (mouseCanvas !== null)
clearCanvas(mouseCanvas);
const ctx = mouseCanvas.getContext("2d");
if (!ctx)
return;
const radius = dragginIconSize / 2;
ctx.beginPath();
ctx.arc(radius, radius, radius, 0, Math.PI * 2);
ctx.closePath();
ctx.fillStyle = selector.theme.defaultColor;
ctx.fill();
drawCircleLine(mouseCanvas, radius, 3, whiteColor);
drawText(mouseCanvas, (_a = draggingItem.name) !== null && _a !== void 0 ? _a : "", whiteColor, {
x: radius,
y: radius,
});
}
exports.drawDragging = drawDragging;
function drawCircleLine(canvas, radius, width, color) {
const ctx = canvas.getContext("2d");
if (!ctx)
return;
ctx.beginPath();
ctx.arc(canvas.width / 2, canvas.height / 2, radius - width / 2, 0, Math.PI * 2);
ctx.closePath();
ctx.strokeStyle = color; // Outline color
ctx.lineWidth = width; // Outline thickness
ctx.stroke();
}
function drawText(canvas, text, color, pos) {
const ctx = canvas.getContext("2d");
if (!ctx)
return;
ctx.fillStyle = color; // Text color
ctx.font = "16px Arial"; // Text font
ctx.textAlign = "center"; // Center-align text
ctx.textBaseline = "middle"; // Middle-align text
ctx.fillText(text, pos.x, pos.y);
}
function drawLineFromCenter(canvas, angle, length, color, width = 3) {
const ctx = canvas.getContext("2d");
if (!ctx)
return;
// Get the center of the canvas
const centerX = canvas.width / 2;
const centerY = canvas.height / 2;
// Calculate the endpoint of the line using trigonometry
const endX = centerX + length * Math.cos(angle);
const endY = centerY + length * Math.sin(angle);
// Draw the line
ctx.globalCompositeOperation = "source-over";
ctx.beginPath();
ctx.moveTo(centerX, centerY); // Start at the center of the canvas
ctx.lineTo(endX, endY); // Draw to the calculated endpoint
ctx.closePath();
ctx.strokeStyle = color; // Set the line color
ctx.lineWidth = width; // Set the line width
ctx.stroke(); // Render the line
}
exports.drawLineFromCenter = drawLineFromCenter;