Tworzę sobie pewną "apkę" w czystym HTML5/JS/CSS3, uruchamianą w przeglądarce. Najważniejszy element tej aplikacji to powierzchnia Canvas, która jest obsługiwana myszką. Dla uproszczenia, powiedzmy, że ta aplikacja, to taki ala Paint z Windows. Co oczywiste, aby taki Paint działał, należy obsłużyć 3 zdarzenia na powierzchni rysowania:
- Naciśnięcie przycisku myszki
- Przeciągnięcie myszki na naciśniętym przycisku
- Puszczenie przycisku myszki
Nie będę opisywać, jak działa Paint i każdy inny program tego typu obsługiwany myszką, bo każdy to wie.
Utworzyłem 3 metody, do których wchodzą współrzędne XY położenia kursora. Do tych celów obsłużyłem "mousedown", "mousemove" i "mouseup". Na komputerze z Windows lub Linux działa to bardzo dobrze, natomiast na smartfonie z Androidem działa tak sobie, bo telefon reaguje na naciśnięcie z pewnym opóźnieniem, a przeciąganie powoduje przewijanie strony. Dla przejrzystości kodu, napisałem funkcje MouseDown, MouseUp, MouseMove, przy czym ta ostatnia jest uruchamiana tylko na naciśniętym przycisku. Przejeżdżanie myszką nad canvas bez naciśniętego przycisku nie uruchamia żadnej funkcji, jest to celowo zrobione, w palcu nie ma odpowiednika tej czynności. Dalej poszukałem w www.google.com, jak zrealizować zdarzenia na wyświetlaczu dotykowym i podpiąłem funkcje pod zdarzenia z "touch" w nazwie, przy czym one również uruchamiają wyżej wymienione funkcje.
Działa to dobrze, ale jest pewien problem:
Jak się uruchomi wszystkie funkcje, to na smartfonie naciśnięcie przycisku i zwolnienie uruchamia się dwa razy, co nie jest pożądane. Na komputerze działa prawidłowo. Połowicznie rozwiązałem problem poprzez wprowadzenie zmiennej ConfTouch (true/false), która decyduje, czy używać funkcji dotykowych. Jak się ustawia tą zmienną na true lub na false odpowiednio do rodzaju urządzenia, to aplikacja działa w pełni prawidłowo na wszystkim, ale konieczne jest udostępnienie możliwości zmiany tego ustawienia, a więc też jest takie sobie.
W jaki sposób można automatycznie i wiarygodnie wyczuć, czy w danym przypadku bardziej odpowiednie są funkcje "dotykowe", czy "myszkowe"? Na komputerze działają tylko funkcje "myszkowe", a na smartfonie działają jedne i drugie, przy czym przy użyciu tych "dotykowych" aplikacja lepiej reaguje na dotykanie. Chodzi o to, żeby aplikacja działała i na komputerze i na smartfonie bez potrzeby ustawiania czegokolwiek, ani podwójnego wywoływania zdarzeń.
// Na komputerze - false
// Na smartfonie - true
var ConfTouch = false;
// Obiekt Canvas
var ScreenMouse = document.getElementById('ScreenMouse');
function MouseDown(X, Y)
{
// Kod zdarzenia na naciśniecie przycisku lub palca
}
function MouseMove(X, Y)
{
// Kod zdarzenia w czasie ruchu myszki na naciśniętym przycisku lub przyłożonego palca
}
function MouseUp(X, Y)
{
// Kod zdarzenia na puszczenie przycisku lub palca
}
var MouseBtn = false;
function MouseDown_(Evt)
{
if (!ConfTouch)
{
var _ = ScreenMouse.getBoundingClientRect();
MouseBtn = true;
MouseDown(Evt.clientX + window.scrollX - _.left, Evt.clientY + window.scrollX - _.top);
}
}
function MouseMove_(Evt)
{
if (!ConfTouch)
{
if (MouseBtn)
{
var _ = ScreenMouse.getBoundingClientRect();
MouseMove(Evt.clientX + window.scrollX - _.left, Evt.clientY + window.scrollX - _.top);
}
}
}
function MouseUp_(Evt)
{
if (!ConfTouch)
{
var _ = ScreenMouse.getBoundingClientRect();
MouseUp(Evt.clientX + window.scrollX - _.left, Evt.clientY + window.scrollX - _.top);
MouseBtn = false;
}
}
function MouseDown_0(Evt)
{
if ((ConfTouch) && (Evt.touches.length > 0))
{
document.getElementsByTagName("BODY")[0].className = "lock-screen";
var _ = ScreenMouse.getBoundingClientRect();
MouseBtn = true;
MouseDown(Evt.touches[0].clientX + window.scrollX - _.left, Evt.touches[0].clientY + window.scrollX - _.top);
}
}
function MouseMove_0(Evt)
{
if ((ConfTouch) && (Evt.touches.length > 0))
{
if (MouseBtn)
{
var _ = ScreenMouse.getBoundingClientRect();
MouseMove(Evt.touches[0].clientX + window.scrollX - _.left, Evt.touches[0].clientY + window.scrollX - _.top);
}
}
}
function MouseUp_0(Evt)
{
if ((ConfTouch))
{
document.getElementsByTagName("BODY")[0].className = "";
var _ = ScreenMouse.getBoundingClientRect();
MouseUp(0, 0);
MouseBtn = false;
}
}
function MouseReset(Evt)
{
if ((ConfTouch == 1))
{
document.getElementsByTagName("BODY")[0].className = "";
}
}
ScreenMouse.addEventListener("mousedown", MouseDown_);
ScreenMouse.addEventListener("mousemove", MouseMove_);
ScreenMouse.addEventListener("mouseup", MouseUp_);
ScreenMouse.addEventListener("touchstart", MouseDown_0);
ScreenMouse.addEventListener("touchmove", MouseMove_0);
ScreenMouse.addEventListener("touchend", MouseUp_0);
ScreenMouse.addEventListener("touchcancel", MouseReset);
Klasa lock-screen w CSS ma taką definicję:
.lock-screen {
height: 100%;
overflow: hidden;
width: 100%;
//position: fixed;
}