Files
2026-08-01 07:42:04 +03:00

232 lines
6.2 KiB
JavaScript

const input = document.getElementById('textInput');
const btn = document.getElementById('applyBtn');
const resetBtn = document.getElementById('resetBtn');
const container = document.getElementById('container');
const selectionBox = document.getElementById('selectionBox');
let letters = [];
let isDragging = false;
let isSelecting = false;
let hasMoved = false;
let startX = 0;
let startY = 0;
let dragOffsets = [];
let clickedLetter = null;
function init() {
if (window.localStorage) {
const saved = localStorage.getItem('savedWord');
if (saved) {
input.value = saved;
createLetters(saved);
}
}
}
function createLetters(text) {
container.innerHTML = '';
letters = [];
let totalWidth = 0;
const tempElements = [];
for (let i = 0; i < text.length; i++) {
const el = document.createElement('span');
el.textContent = text[i];
el.className = 'letter';
container.appendChild(el);
const rect = el.getBoundingClientRect();
totalWidth += rect.width + 2;
tempElements.push({ el, rect });
}
let startLeft = (window.innerWidth - totalWidth) / 2;
let top = window.innerHeight / 2;
for (let i = 0; i < text.length; i++) {
const item = tempElements[i];
let x = startLeft;
let y = top;
item.el.style.left = x + 'px';
item.el.style.top = y + 'px';
letters.push({
char: text[i],
el: item.el,
x: x,
y: y,
initialX: x,
initialY: y,
selected: false,
width: item.rect.width,
height: item.rect.height
});
startLeft += item.rect.width + 2;
}
}
btn.addEventListener('click', () => {
const val = input.value;
if (val) {
localStorage.setItem('savedWord', val);
createLetters(val);
}
});
resetBtn.addEventListener('click', () => {
letters.forEach(l => {
l.x = l.initialX;
l.y = l.initialY;
l.el.style.left = l.x + 'px';
l.el.style.top = l.y + 'px';
l.selected = false;
});
updateSelection();
});
input.addEventListener('input', () => {
localStorage.setItem('savedWord', input.value);
});
document.addEventListener('mousedown', (e) => {
if (e.target.tagName === 'INPUT' || e.target.tagName === 'BUTTON') return;
hasMoved = false;
if (e.target.classList.contains('letter')) {
const index = letters.findIndex(l => l.el === e.target);
if (index === -1) return;
clickedLetter = letters[index];
if (e.ctrlKey) {
clickedLetter.selected = !clickedLetter.selected;
updateSelection();
}
else if (!clickedLetter.selected) {
letters.forEach(l => l.selected = false);
clickedLetter.selected = true;
updateSelection();
}
isDragging = true;
startX = e.clientX;
startY = e.clientY;
dragOffsets = letters.filter(l => l.selected).map(l => ({
l,
originalX: l.x,
originalY: l.y,
offsetX: l.x - e.clientX,
offsetY: l.y - e.clientY
}));
e.preventDefault();
}
else {
isSelecting = true;
startX = e.clientX;
startY = e.clientY;
selectionBox.hidden = false;
selectionBox.style.left = startX + 'px';
selectionBox.style.top = startY + 'px';
selectionBox.style.width = '0px';
selectionBox.style.height = '0px';
if (!e.ctrlKey) {
letters.forEach(l => l.selected = false);
updateSelection();
}
e.preventDefault();
}
});
document.addEventListener('mousemove', (e) => {
if (isDragging || isSelecting) {
hasMoved = true;
}
if (isDragging) {
dragOffsets.forEach(item => {
item.l.x = e.clientX + item.offsetX;
item.l.y = e.clientY + item.offsetY;
item.l.el.style.left = item.l.x + 'px';
item.l.el.style.top = item.l.y + 'px';
});
}
else if (isSelecting) {
const currentX = e.clientX;
const currentY = e.clientY;
const left = Math.min(startX, currentX);
const top = Math.min(startY, currentY);
const width = Math.abs(currentX - startX);
const height = Math.abs(currentY - startY);
selectionBox.style.left = left + 'px';
selectionBox.style.top = top + 'px';
selectionBox.style.width = width + 'px';
selectionBox.style.height = height + 'px';
letters.forEach(l => {
const lRight = l.x + l.width;
const lBottom = l.y + l.height;
if (l.x < left + width && lRight > left && l.y < top + height && lBottom > top) {
l.selected = true;
}
});
updateSelection();
}
});
document.addEventListener('mouseup', (e) => {
if (isDragging) {
if (!hasMoved && clickedLetter && !e.ctrlKey) {
clickedLetter.selected = !clickedLetter.selected;
updateSelection();
}
else if (dragOffsets.length === 1 && hasMoved) {
const draggedItem = dragOffsets[0];
const targetX = e.clientX;
const targetY = e.clientY;
const dropTarget = letters.find(l => {
if (l === draggedItem.l) return false;
return targetX >= l.x && targetX <= l.x + l.width &&
targetY >= l.y && targetY <= l.y + l.height;
});
if (dropTarget) {
dropTarget.x = draggedItem.originalX;
dropTarget.y = draggedItem.originalY;
dropTarget.el.style.left = dropTarget.x + 'px';
dropTarget.el.style.top = dropTarget.y + 'px';
}
}
isDragging = false;
dragOffsets = [];
clickedLetter = null;
}
if (isSelecting) {
isSelecting = false;
selectionBox.hidden = true;
}
});
function updateSelection() {
letters.forEach(l => {
if (l.selected) {
l.el.classList.add('selected');
}
else {
l.el.classList.remove('selected');
}
});
}
init();