Line Drawing using Mouse

Tujuan

Membuat aplikasi web untuk menggambar garis menggunakan mouse.

Alat dan Bahan

D3.js

Dasar Teori

Logika Interaksi

secara sederhana, untuk membuat garis, dapat dilakukan dengan merespon kegiatan drag and drop. Pada drag and drop, ada 3 mouse event yang perlu diperhatikan

  1. mousedown
  2. mousemove
  3. mouseup

mousedown adalah saat tombol mouse ditekan, mousemove adalah saat mouse digerakkan, dan mouseup adalah saat tombol dilepas. seperti ditunjukkan pada gambar berikut.

Drag and Drop

idenya, ketika mousedown, kita buat line pada posisi mouse tersebut. kemudian saat mousemove, selama mouse masih ditekan, kita update ujung line sesuai posisi mouse. kemudian saat mouseup, berhenti mengupdate.

Aspek Teknis

secara teknis, banyak cara untuk menerapkan logika interaksi tersebut. jika dibatasi pada HTML5 dan D3, maka teknis yang paling dekat adalah penggunaan SVG.

ada banyak elemen yang disediakan oleh SVG, meliputi garis, segi empat, lingkaran, dan sebagainya.

dalam hal ini, yang mendekati yang kita butuhkan adalah line

line memiliki beberapa atribut, yaitu x1, y1, x2, y2. atribut ini mewakili titik awal (x1, y1) dan titik akhir (x2, y2)

kemudian, selain elemen, kita juga butuh mekanisme untuk merespon mouse events (mousedown, mousemove, mouseup).
Alhamdulillah, fasilitas tersebut sudah tersedia di d3.
kita bisa menggunakan .on untuk mendaftarkan callback. Callback adalah nama khusus untuk sebuah fungsi yang akan dieksekusi pada event tertentu.

Implementasi

untuk mengimplementasi ide tersebut, kita bisa mulai dari membuat garis menggunakan SVG line dan D3.

Experiment 1: Membuat line menggunakan d3.

kita mulai dengan membuat div dengan id d3-drawing-area sebagai tempat d3 untuk menggenerate SVG.

<div id="d3-drawing-area"></div>
view raw index.html hosted with ❤ by GitHub

kemudian dengan menggunakan d3, kita select id tersebut kemudian kita tambahkan svg dengan lebar 300 dan tinggi 300. kemudian supaya bisa dilihat dengan mudah, kita atur background-nya dengan warna lightblue.

var svg = d3.select('#d3-drawing-area').append('svg')
.attr('width', 300)
.attr('height', 300)
.style('background', 'lightblue');
view raw index.html hosted with ❤ by GitHub

kemudian pada svg tersebut, kita tambahkan line dengan koordinat (100,100) dan (200, 200). kemudian kita beri warna stroke blue dan stroke-width 2.

var line = svg.append('line')
.attr('x1', 100)
.attr('y1', 100)
.attr('x2', 200)
.attr('y2', 200)
.style('stroke', 'blue');
view raw index.html hosted with ❤ by GitHub

berikut adalah hasil yang diperoleh

view full code

dari situ, kita bisa lanjut dengan menambahkan callback untuk mousemove. kita bisa menggunakan mousemove untuk mengupdate endpoint.

Experiment 2: Mengupdate endpoint pada saat mousemove.

kita bisa memodifikasi garis yang ada melalui variable line. Pada saat ada event mousemove diatas svg, maka kita lakukan update pada atribut x2 dan y2 dari line. Untuk mendapatkan posisi koordinat mouse relatif terhadap svg, kita bisa menggunakan d3.mouse.

svg.on('mousemove', function() {
// get mouse position relative to "this" svg
var mousePosition = d3.mouse(this);
// use it to update endpoint (x2, y2)
line
.attr('x2', mousePosition[0])
.attr('y2', mousePosition[1]);
});
view raw index.html hosted with ❤ by GitHub

hasil yang diperoleh sebagai berikut

view code

dari kode tersebut masih terasa kurang pas, karena tidak ada pengecekan apakah tombol mouse sedang di tekan atau tidak.

Experiment 3: Mengupdate endpoint hanya saat tombol mouse sedang ditekan.

sejauh yang saya ketahui, belum ada fasilitas untuk mengetahui status tombol di d3. sehingga kita perlu membuat sendiri dengan teknik flag variable.

flag variable ini kita sebut dengan drag. Jika bernilai true, maka tombol mouse sedang ditekan. Variable ini kita beri nilai awal false.

var drag = false;
view raw index.html hosted with ❤ by GitHub

kemudian flag ini kita set true saat mousedown

svg.on('mousedown', function() {
drag = true;
});
view raw index.html hosted with ❤ by GitHub

dan di-set false saat mouseup

svg.on('mouseup', function() {
drag = false;
});
view raw index.html hosted with ❤ by GitHub

dari flag tersebut, kita lakukan update line saat mousemove hanya jika drag bernilai true. Jika tidak, maka langsung return tanpa melakukan apapun.

if(!drag) {
return;
}
view raw index.html hosted with ❤ by GitHub

berikut adalah hasil yang diperoleh

view full code

kita bisa melanjutkan program tersebut dengan mengupdate titik awal (startingpoint) dari line setiap kali mousedown.

Experiment 4: Mengubah starting point saat tombol mouse ditekan.

Selain mengubah titik awal, kode ini juga mengubah titik akhir sesuai posisi mouse. Sehingga saat user mousedown kemudian langsung mouseup, maka tidak ada garis yang muncul.

svg.on('mousedown', function() {
drag = true;
var mousePosition = d3.mouse(this);
line
.attr('x1', mousePosition[0])
.attr('y1', mousePosition[1])
.attr('x2', mousePosition[0])
.attr('y2', mousePosition[1]);
});
view raw index.html hosted with ❤ by GitHub

berikut adalah hasil yang diperoleh

view full code

Kesimpulan

membuat aplikasi menggambar garis menggunakan mouse, dapat dilakukan menggunakan d3.js dikombinasi dengan mouse event beserta teknik flag variable

Saran

aplikasi yang dibuat dapat dikembangkan lebih lanjut, misalnya dengan menambahkan kemampuan (fitur) untuk menggambar lebih dari satu garis. seperti kode berikut

view full code

Daftar Pustaka

Draw a straight line using mouse
Simulate Drag and Drop
SVG Tutorial
SVG Line – <line\>
D3.js First Steps

Leave a Reply

Your email address will not be published. Required fields are marked *