HTML5 kətan üçün Hit Region Tanılamasını vurun və kətan şekillerindəki hadisələrə necə tıklayacak

Kətan şəkliniz üçün sadə bir onClick ehtiyacınız varmı? Ancaq Canvas'ın bu cür dinləyicilər üçün bir API yoxdur. Hadisələri yalnız bir hissəsində deyil, bütün ekranda eşidə bilərsiniz. Bu problem ətrafında necə işləməyimə dair iki əsas yanaşmanı təsvir edəcəyəm.

DİQQƏT! AddHitRegion API-dən istifadə etməyəcəyəm, çünki hal hazırda qeyri-sabitdir (2017-ci ildə) və tam dəstəklənmir. Ancaq baxa bilərsiniz.

Sadə HTML5 kətan qrafikası ilə başlayaq. Təsəvvür edin ki, bir tərəfə bir neçə dairə çəkmək istəyirik.

Demo:

İndi yalnız bir ekranda olan klikləri dinləyə bilərik:

canvas.addEventListener ('klikləyin', () => {console.log ('kətan vurmaq');});

Ancaq bir dairənin tıklamasına qulaq asmaq istəyirik. Bunu necə edirsən? Bir dairəni tıkladığımızı necə bilirsiniz?

1 yanaşma - riyaziyyatın gücündən istifadə edin

Dairəmizin koordinatları və ölçüləri haqqında məlumatımız olduğu üçün mənasız hesablamaları olan bir dairədə bir tıklamanı tapmaq üçün riyaziyyatdan asanlıqla istifadə edə bilərik. Bizə lazım olan şey klik hadisəsindən siçan mövqeyini almaq və bütün dairələrin kəsişmələrini yoxlamaqdır:

Bu yanaşma geniş yayılmışdır və bir çox layihələrdə istifadə olunur. Daha mürəkkəb formalar üçün riyaziyyat funksiyalarını asanlıqla tapa bilərsiniz, məsələn, düzbucaqlar, ellipslər, çoxbucaqlar və s.

Bu yanaşma çox yaxşıdır və çox sayda forma olmadıqda olduqca sürətli ola bilər.

Ancaq bu yanaşmanı çox mürəkkəb formalar üçün istifadə etmək çox çətindir. Məsələn, kvadrat əyriləri olan xətləri istifadə edirsiniz.

2 yanaşma - hit bölgəni təqlid edin

Hit bölgələri fikri sadədir: sadəcə tıklanmış sahənin altına piksel gətirməliyik və eyni rəngə sahib bir forma tapırıq:

Ancaq bu yanaşma işləməyəcək, çünki eyni rəngli formalar ola bilər, elə deyilmi? Belə bir toqquşmanın qarşısını almaq üçün xüsusi "hit graph" kətan yaratmalıyıq. Demək olar ki, eyni formalara sahib olacaq, lakin hər bir forma özünəməxsus rəngə sahib olacaqdır. Beləliklə, hər bir dairə üçün təsadüfi rənglər yaratmalıyıq:

Bundan sonra hər bir şəkli TWICE çəkməliyik. Əvvəlcə görünən kətanlarda, sonra "vurulmuş" kətanlarda.

İndi kətan vurursan, vurulmuş kətan üzərində yalnız bir piksel götürməlisən və eyni rəngli bir forma tapmalısan. Bu hərəkətlər çox sürətli və BÜTÜN şekiller üzərində təkrarlamaq məcburiyyətində deyilsiniz. Formanızın nə qədər mürəkkəb olmasının da əhəmiyyəti yoxdur. İstədiyinizi çəkin və hər forma üçün fərqli rənglərdən istifadə edin.

Tam kodu ilə demo:

Hansı yanaşma daha yaxşıdır?

İkinci "vuruş" yanaşmasında ən böyük problem, iki dəfə şəkl çəkməyinizdir. Buna görə performans iki dəfə düşə bilər! Bununla birlikdə, kətan üzərində rəsm çəkmək daha asan ola bilər. Oradakı kölgələri və xətləri atlaya bilərsiniz, bəzi formaları sadələşdirə bilərsiniz, məsələn B. bir mətni sadəcə bir düzbucaqlı ilə əvəz edin. Lakin rəsm bitdikdən sonra bu yanaşma çox sürətli ola bilər. Çünki bir piksel götürmək və saxlanılan şekillerin bir hissəsinə daxil olmaq çox tezdir.

Bunları birlikdə istifadə etmək olarmı?

Əlbətdə. Bir neçə kətan kitabxanası belə qarışıq bir yanaşmadan istifadə edir.

İşin necə qurulduğunu təqdim edirik:

Hər bir forma üçün sadələşdirilmiş məhdudlaşdırıcı düzbucaqlıları (x, y, eni, boyu) hesablamaq lazımdır. Sonra siçan mövqeyi və ətraf düzbucaqlı ilə kəsişən şekilleri süzmək üçün ilk riyazi yanaşmadan istifadə edirsiniz. Daha sonra bir vuruş çəkə və daha dəqiq bir nəticə əldə etmək üçün ikinci yanaşma ilə kəsişməni sınaya bilərsiniz.

Niyə bu iş üçün yalnız SVG istifadə etməyək?

Çünki kətan bəzən daha güclü ola bilər və tələb olunan işinizə daha yaxşı uyğunlaşa bilər. Burada da bir vəzifə vacibdir. Beləliklə, Canvas vs SVG bu yazı kontekstində deyil. Kətan istifadə etsəniz və vurma təsbitini istəyirsinizsə, bir şey istifadə etməlisiniz, elə deyilmi?

Başqa hadisələr haqqında? Mousemove, Mouseenter və s. Kimi?

Təsvir edilən yanaşmalara yalnız əlavə kod əlavə etməlisiniz. 100% siçan altında bir forma tanıdığınız zaman bütün digər hadisələri təqlid edə bilərsiniz.

İstifadəyə hazır həllər varmı?

Əlbətdə. Yalnız "HTML5 Canvas Framework" keçidini sınayın. Ancaq şəxsi tövsiyəm http://konvajs.github.io/. Demək olar ki, unudulmuşam, bu kitabxananın qoruyucusuyam. Konva yalnız ikinci bir yanaşmadan istifadə edir və adətən DOM elementləri üçün (və daha çox, məsələn, sürükləmək kimi) bütün siçan və toxunma hadisələrini dəstəkləyir.