function switch_tool(state, item) { const tool = item.getAttribute('data-tool'); if (tool === 'undo') { queue_event(state, undo_event(state)); return; } if (state.tools.active_element) { state.tools.active_element.classList.remove('active'); } const old_class = 'tool-' + state.tools.active; const new_class = 'tool-' + tool; document.querySelector('canvas').classList.remove(old_class); state.tools.active = tool; state.tools.active_element = item; state.tools.active_element.classList.add('active'); document.querySelector('canvas').classList.add(new_class); if (tool === 'pencil' || tool === 'eraser' || tool === 'ruler') { update_cursor(state); document.querySelector('.brush-dom').classList.remove('dhide'); } else { document.querySelector('.brush-dom').classList.add('dhide'); } } function select_color(state, item, color_u32) { if (state.colors.active_element) { state.colors.active_element.classList.remove('active'); } if (state.colors.extended_element) { state.colors.extended_element.classList.remove('extended'); state.colors.extended_element = null; } const last_minor = item.lastElementChild; const color_css = color_from_u32(color_u32); last_minor.setAttribute('data-color', color_css.substring(1)); last_minor.querySelector('.color-pane').style.background = color_css; state.colors.active_element = item; item.classList.add('active'); } function extend_major_color(state, item) { if (state.colors.active_element) { state.colors.active_element.classList.remove('active'); } if (state.colors.extended_element) { state.colors.extended_element.classList.remove('extended'); } const last_minor = item.lastElementChild; // Restore last pane color in case it was overwritten by active color last_minor.querySelector('.color-pane').style.background = '#' + item.getAttribute('data-last-color'); last_minor.setAttribute('data-color', item.getAttribute('data-last-color')); state.colors.extended_element = item; item.classList.add('extended'); } function set_color_u32(state, color_u32) { if (color_u32 === state.players[state.me].color) { return; } const color_css = color_from_u32(color_u32).substring(1); const color_minor = document.querySelector(`.color-minor[data-color="${color_css}"]`); if (!color_minor) { set_color_u32(state, 0); return; } const major_color = color_minor.parentElement; select_color(state, major_color, color_u32); state.players[state.me].color = color_u32 update_cursor(state); fire_event(state, color_event(color_u32)); } function switch_stroke_width(e, state) { if (!state.online) return; const value = parseInt(e.target.value); state.players[state.me].width = value; update_cursor(state); } function broadcast_stroke_width(e, state) { const value = e.target.value; fire_event(state, width_event(value)); } function init_tools(state) { const tools = document.querySelectorAll('.tools .tool'); const color_groups = document.querySelectorAll('.pallete .color-major'); tools.forEach((item) => { item.addEventListener('click', () => switch_tool(state, item)); }); color_groups.forEach((item) => { item.setAttribute('data-last-color', item.lastElementChild.getAttribute('data-color')); let longtouch_timer = null; item.addEventListener('touchstart', (e) => { longtouch_timer = setTimeout(() => { extend_major_color(state, item); }, 500); }); item.addEventListener('touchmove', (e) => { if (longtouch_timer) { clearTimeout(longtouch_timer); } longtouch_timer = null; }); item.addEventListener('touchend', (e) => { if (longtouch_timer) { clearTimeout(longtouch_timer); } longtouch_timer = null; }); item.addEventListener('click', (e) => { if (e.ctrlKey) { extend_major_color(state, item); return; } let color_element = e.target; let target = e.target; while (!target.classList.contains('color-minor')) { target = target.parentElement; } const color_str = target.getAttribute('data-color'); const color_u32 = color_to_u32(color_str); set_color_u32(state, color_u32); }) }); switch_tool(state, document.querySelector('.tool[data-tool="pencil"]')); const slider = document.querySelector('#stroke-width'); // slider.value = state.players[state.me].width; slider.addEventListener('input', (e) => switch_stroke_width(e, state)); slider.addEventListener('change', (e) => broadcast_stroke_width(e, state)); document.querySelector('.phone-extra-controls').addEventListener('click', zenmode); }