is there anyone who can make a custom caret cursor handle for ace editor js? (usually marked with a water drop icon). I have made it, but when the cursor handle is touched using the touch event, the default ace cursor moves to the tip of the finger, as a result the ace cursor cannot be seen when the handle is touched. please if anyone can help.
this my code
var editor = ace.edit("editor");
editor.setTheme("ace/theme/github_dark");
editor.session.setUseWorker(true);
editor.session.setMode("ace/mode/html");
editor.setOptions({
enableBasicAutocompletion: true,
enableLiveAutocompletion: true,
enableSnippets: true,
fontSize: "14px",
wrap: true,
animatedScroll: false,
scrollSpeed: 0,
});
editor.setValue(`<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
</body>
</html>`, -1);
const ln = document.createElement("div");
const bx = document.createElement("div");
bx.id = "box";
ln.className = "line";
bx.innerHTML = `
t<svg id="caretHandle" width="100%" height="100%" viewBox="0 0 24 29" xmlnsn="http://www.w3.org/2000/svg"><path fill="#558eff" d="m20.496197,8.485282c4.700846,4.700846 4.700846,12.269717 0,16.970563c-4.700846,4.700846 -12.269717,4.700846 -16.970563,0c-4.700846,-4.700846 -4.700846,-12.269717 0,-16.970563l8.485281,-8.485281l8.485281,8.485281z" /></svg>
`;
editor.container.append(bx);
editor.container.append(ln);
(function() {
const box = document.querySelector("#box");
const line = document.querySelector(".line");
const aceCursorEl = document.querySelector(".ace_cursor");
let editorRect;
let offsetX = 0;
let offsetY = 0;
let isDragging = false;
line.style.opacity = 0;
// Tambahkan flag untuk menandakan apakah sedang di-drag
function updateCursorPosition() {
if (!isDragging) { // Hanya update jika tidak sedang di-drag
const cursorPos = editor.getCursorPosition();
const screenPos = editor.renderer.textToScreenCoordinates(cursorPos.row, cursorPos.column);
editorRect = editor.container.getBoundingClientRect();
const relativeX = screenPos.pageX - editorRect.left;
const relativeY = screenPos.pageY - editorRect.top;
line.style.transform = `translate(${relativeX}px,${relativeY}px)`;
} else {
// Selama drag, posisikan line di atas box
const boxCurrentRect = box.getBoundingClientRect();
const lineOffsetUp = -line.offsetHeight - 5; // Offset ke atas agar tidak menempel
line.style.transform = `translate(${boxCurrentRect.left - editorRect.left}px,${boxCurrentRect.top - editorRect.top + lineOffsetUp}px)`;
}
}
function updateWaterDrop() {
const cursorPos = editor.getCursorPosition();
const screenPos = editor.renderer.textToScreenCoordinates(cursorPos.row, cursorPos.column);
editorRect = editor.container.getBoundingClientRect();
const relativeX = screenPos.pageX - editorRect.left;
const relativeY = screenPos.pageY - editorRect.top;
const handleOffsetDown = 25; // Sesuaikan offset ke bawah agar tidak tertutup jari saat touch start
box.style.transform = `translate(${relativeX}px,${relativeY + handleOffsetDown}px)`;
}
box.ontouchstart = function(eventStart) {
isDragging = true; // Set flag menjadi true saat mulai drag
line.style.opacity = 1;
let touchStart = eventStart.touches.item(0);
editorRect = editor.container.getBoundingClientRect();
offsetX = touchStart.clientX - this.getBoundingClientRect().left;
offsetY = touchStart.clientY - this.getBoundingClientRect().top;
// Posisikan line di atas box saat touch start
const boxCurrentRect = this.getBoundingClientRect();
const lineOffsetUp = -line.offsetHeight - 5; // Offset ke atas
line.style.transform = `translate(${boxCurrentRect.left - editorRect.left +16}px,${boxCurrentRect.top - editorRect.top + lineOffsetUp}px)`;
// Pastikan kursor Ace terlihat saat mulai drag
const aceCursorElement = document.querySelector(".ace_cursor");
if (aceCursorElement) {
aceCursorElement.style.visibility = 'visible';
aceCursorElement.style.zIndex = 100000001; // Pastikan di atas
}
};
box.ontouchmove = function(eventMove) {
if (!isDragging) return;
let touchMove = eventMove.touches.item(0);
let touchX = touchMove.clientX - editorRect.left;
let touchY = touchMove.clientY - editorRect.top;
const cursorPos = editor.getCursorPosition();
// Posisikan caret handle agar offset ke bawah dari posisi sentuhan
const handleOffsetDown = 25; // Sesuaikan offset ke bawah
box.style.transform = `translate(${touchX - offsetX}px,${touchY - offsetY + handleOffsetDown}px)`;
// Selama drag, posisikan line di atas box yang bergerak
const boxCurrentRect = box.getBoundingClientRect();
const lineOffsetUp = -line.offsetHeight - 5; // Offset ke atas
line.style.transform = `translate(${boxCurrentRect.left -editorRect.left +22}px,${boxCurrentRect.top - editorRect.top + lineOffsetUp}px)`;
// Update posisi kursor ACE yang sebenarnya berdasarkan sentuhan
//mendeteksi posisi kursor row sekarang
if (
touchMove.clientX >= editorRect.left &&
touchMove.clientX <= editorRect.right &&
touchMove.clientY >= editorRect.top &&
touchMove.clientY <= editorRect.bottom
) {
const screenToText = editor.renderer.screenToTextCoordinates(touchX, touchY);
console.log()
//editor.moveCursorTo(screenToText.row, screenToText.column);
editor.clearSelection();
}
};
box.ontouchend = function(eventEnd) {
isDragging = false; // Set flag menjadi false saat selesai drag
line.style.opacity = 0;
updateCursorPosition(); // Kembalikan posisi line ke posisi kursor Ace
updateWaterDrop(); // Pastikan posisi box tetap sinkron setelah drag selesai
// Kembalikan z-index kursor Ace
const aceCursorElement = document.querySelector(".ace_cursor");
if (aceCursorElement) {
aceCursorElement.style.zIndex = '';
}
};
editor.on("changeSelection", function() {
updateWaterDrop();
updateCursorPosition();
});
editor.renderer.on("afterRender", function() {
updateCursorPosition();
updateWaterDrop();
});
// Inisialisasi posisi awal caret handle agar berada di bawah kursor
function initializeCaretHandlePosition() {
const cursorPos = editor.getCursorPosition();
const screenPos = editor.renderer.textToScreenCoordinates(cursorPos.row, cursorPos.column);
editorRect = editor.container.getBoundingClientRect();
const relativeX = screenPos.pageX - editorRect.left;
const relativeY = screenPos.pageY - editorRect.top;
const handleOffsetDown = 25; // Sesuaikan offset ke bawah
line.style.transform = `translate(${relativeX}px,${relativeY}px)`;
box.style.transform = `translate(${relativeX}px,${relativeY + handleOffsetDown}px)`;
}
initializeCaretHandlePosition();
})();