2015-09-22 21 views
5

Mam element canvas canvas i zaimplementowałem pędzel przechwytujący zdarzenia elementu canvas. To wszystko działa dobrze, rysując na płótnie. Jednak nie sądzę, że podoba mi się, jak nie można kontynuować rysowania, jeśli mysz opuści płótno w połowie suwu. To po prostu to odcina. Jest to dla mnie bardzo nieczytelne, a moim zdaniem mało przyjazne dla użytkownika.Jak rysować poza elementem canvas HTML?

Jeśli otworzysz program Microsoft Paint i zaczniesz rysować pędzlem lub elipsą lub czymś innym, tak długo, jak zaczniesz w obszarze roboczym, możesz przeciągnąć myszą w dowolne miejsce ekranu i ponownie przejść do obszaru roboczego. Ułatwia to również na przykład rysowanie ćwiartek w rogach, ponieważ możesz przeciągnąć narzędzie elipsy poza ekran. Mam nadzieję, że to ma sens.

W każdym razie, zastanawiałem się, czy istnieje sposób na wdrożenie tego z płótnem HTML5 lub jak chciałbym wdrożyć tego typu rzeczy. Użytkownik nigdy nie musiałby widzieć niczego tam narysowanego; będzie to głównie funkcja użyteczności.

Edycja: problemem z wieloma z tych rozwiązań jest obsługa współrzędnych. Obecnie moje płótno znajduje się pośrodku ekranu, a górna lewa strona płótna to (0, 0), a dolna prawa to (500, 500). Należy również wziąć pod uwagę tłumaczenie współrzędnych.

Edycja2: Dowiedziałem się, że najwyraźniej można zrównać granice płótna. Na przykład można podać ujemne szerokości, wysokości i współrzędne, a element canvas będzie go obsługiwał dobrze. Zasadniczo rozwiązanie prawdopodobnie obejmuje przechwycenie dokumentu mousemove i mouseup i po prostu przetłumaczenie x i y, aby rozpocząć od lewego górnego rogu obszaru roboczego.

+3

można uchwycić myszy wydarzenia w samym oknie, a następnie przenieść się na płótno? – zero298

+0

Być może spróbuj podać przykład tego, co masz obecnie. Łatwiej nam pomóc, jeśli nie musimy najpierw odtwarzać naszego własnego "zepsutego" przykładu. – duncanhall

+0

Być może mógłbyś również uczynić element canvas w pełnej szerokości i wysokości okna i obszaru rysunku nieco mniejszego w obszarze roboczym? –

Odpowiedz

1

Oto niezwykle szorstki pierwszy projekt jaki sposób można nasłuchiwać zdarzeń myszy w oknie zamiast płótna, aby móc zwrócić się w sposób ciągły:

var logger = document.getElementById("logger"), 
 
    mState = document.getElementById("mState"), 
 
    mX = document.getElementById("mX"), 
 
    mY = document.getElementById("mY"), 
 
    cX = document.getElementById("cX"), 
 
    cY = document.getElementById("cY"), 
 
    c = document.getElementById("canvas"), 
 
    ctx = c.getContext("2d"); 
 

 
var mouse = { 
 
    x: 0, 
 
    y: 0, 
 
    state: "" 
 
}; 
 

 
function printCanvasLocation() { 
 
    var b = c.getBoundingClientRect(); 
 
    cX.innerHTML = b.top; 
 
    cY.innerHTML = b.left; 
 
} 
 

 
function setState(mouseE, state) { 
 
    mouse.x = mouseE.clientX; 
 
    mouse.y = mouseE.clientY; 
 

 
    mX.innerHTML = mouseE.clientX; 
 
    mY.innerHTML = mouseE.clientY; 
 
    if (state) { 
 
    mState.innerHTML = state; 
 
    mouse.state = state; 
 
    } 
 
} 
 

 
window.addEventListener("mousedown", function(mouseE) { 
 
    setState(mouseE, "down"); 
 
}); 
 

 
window.addEventListener("mouseup", function(mouseE) { 
 
    setState(mouseE, "up"); 
 
}); 
 

 
window.addEventListener("mousemove", function(mouseE) { 
 
    var offset = c.getBoundingClientRect(); 
 

 
    var fix = { 
 
    x1: (mouse.x - offset.left), 
 
    y1: (mouse.y - offset.top), 
 
    x2: (mouseE.clientX - offset.left), 
 
    y2: (mouseE.clientY - offset.top) 
 
    }; 
 

 
    if (mouse.state === "down") { 
 
    ctx.moveTo(fix.x1, fix.y1); 
 
    ctx.lineTo(fix.x2, fix.y2); 
 
    ctx.strokeStyle = "#000"; 
 
    ctx.stroke(); 
 
    } 
 
    setState(mouseE); 
 
}); 
 

 
window.addEventListener("resize", function() { 
 
    printCanvasLocation(); 
 
}); 
 

 
printCanvasLocation();
  .center { 
 

 
       text-align: center; 
 

 
      } 
 

 
      canvas { 
 

 
       background-color: lightblue; 
 

 
      }
<main> 
 
    <div class="center"> 
 
    <canvas id="canvas" width="128" height="128">If you can see me, you should update your browser</canvas> 
 
    </div> 
 
    <div id="logger" role="log"> 
 
    <span>State: </span><span id="mState">Unknown</span> 
 
    <span>X: </span><span id="mX">Unknown</span> 
 
    <span>Y: </span><span id="mY">Unknown</span> 
 
    <span>Canvas X: </span><span id="cX">Unknown</span> 
 
    <span>Canvas Y: </span><span id="cY">Unknown</span> 
 
    </div> 
 
</main>

+0

Twoje "Canvas X" i "Canvas Y" są cofnięte, ale poza tym wspaniała odpowiedź! Myślę, że to zrobi. –

2

Oto jeden sposób można zachować rysunek kiedy ponownie wprowadzić płótnie:

  • Utwórz zmienną globalną i ustawić, że jeden na true na mousedown
  • Dodaj globalne wydarzenie dla mouseUp więc można złapać jeśli ktoś zrobić poza płótno, a jeśli tak, należy ustawić zmienną globalną false i mouseUp zapotrzebowanie elementu canvas jest oczywiście również ustawić tak samo zmienna
  • na mouseMove, sprawdź zmienną globalną, aby mogło być prawdziwe przed narysować

Aby narysować "na zewnątrz" płótna, np. Ćwierćokręgi w rogu, przesuwałbym wszystkie zdarzenia do poziomu dokumentu jako globalnego programu obsługi i przechwytywałbym element canvas podczas klikania i przekazywał jego współrzędne klienta, które mają być obliczane za pomocą współrzędnych dokumentu .

Powiązane problemy