Deteksi Mouse dan Touch di HTML5 Canvas


Setelah membuat animasi lingkaran futuristik pada posting sebelumnya, penulis penasaran menggunakan lingkaran tersebut untuk deteksi mouse dan touch HTML5 Canvas pada versi mobile.

Hasil testing dengan menjalankan di browser Chrome di salah satu device Android Samsung sebagaimana terlihat pada gambar di atas.

Tiap lingkaran menunjukkan posisi jari yang berbeda, sesuai jumlah sentuhan yang mampu di deteksi oleh device smartphone masing-masing.

Caranya adalah dengan menambahkan event listener mouse dan touch pada element Canvas, dengan metode penggambaran memanfaatkan fungsi translate dan rotate untuk transformasi tiap lingkarannya.

Kelemahannya, penomoran sentuhan direset tiap kali jumlah sentuhan berubah, yang mengakibatkan perubahan pengurutan penomoran sentuhan.

Kode HTML5 Canvasnya adalah seperti ditunjukkan pada kode di bawah ini:

<html> 
<head> 
<title>Mouse and Touch Event</title> 
<meta name="viewport" content="width=device-width, initial-scale=1.0"> 
</head> 
<body> 
<canvas id="myCanvas" width="1024" height="768"> 
</canvas> 
<div id="catatan"></div> 
<script> 
 
var canvas = document.getElementById("myCanvas"); 
var ctx = canvas.getContext("2d"); 
 
var mousePosition=[],lastPosition=[]; 
 
canvas.addEventListener("mousedown", function (e) { 
 getMousePos(0,canvas, e); 
}, false); 
 
canvas.addEventListener("mouseup", function (e) { 
 mousePosition=[]; 
}, false); 
 
canvas.addEventListener("mousemove", function (e) { 
 if(mousePosition.length>0)getMousePos(0,canvas, e); 
}, false); 
 
function getMousePos(id,canvasDom, mouseEvent) 
{ 
 var rect = canvasDom.getBoundingClientRect(); 
 mousePosition[2*id+0]=mouseEvent.clientX - rect.left; 
 mousePosition[2*id+1]=mouseEvent.clientY - rect.top; 
} 
 
canvas.addEventListener("touchstart", function (e) { 
 mousePosition=[]; 
 for(i=0;i<e.touches.length;i++)getMousePos(i,canvas,e.touches[i]); 
}, false); 
 
canvas.addEventListener("touchend", function (e) { 
 mousePosition=[]; 
 if(e.touches.length>0){ 
  for(i=0;i<e.touches.length;i++)getMousePos(i,canvas,e.touches[i]); 
 } 
}, false); 
 
canvas.addEventListener("touchmove", function (e) { 
 mousePosition=[]; 
 if(e.touches.length>0){ 
  for(i=0;i<e.touches.length;i++)getMousePos(i,canvas,e.touches[i]); 
 } 
}, false); 
 
var warna=["red","green","blue","white"]; 
var properti=[],mactive=[];//putaran,targetputaran 
 
function Menggambar() 
{ 
    ctx.globalAlpha=1.0; 
 ctx.fillStyle = "black"; 
 ctx.fillRect(0,0,canvas.width,canvas.height); 

 ctx.globalAlpha=0.8; 
 var num=Math.floor(mousePosition.length/2); 
 var b=4,numlingkaran=3; 
 var selangdata=b*numlingkaran; 
 for(i=0;i<num;i++){ 
  mactive[i]=3; 
  lastPosition[2*i+0]=mousePosition[2*i+0]; 
  lastPosition[2*i+1]=mousePosition[2*i+1]; 
 } 
 num=Math.floor(lastPosition.length/2); 

 for(i=0;i<num;i++){ 
  var a=i%warna.length; 

  var del=2; 

  var n=Math.floor(properti.length/selangdata); 
  var index=selangdata*i; 
  if(i<n){ 
   var j=0; 
   while(j<selangdata/2){ 
    if(properti[index+2*j+0]<properti[index+2*j+1]){ 
     properti[index+2*j+0]+=del; 
     if(properti[index+2*j+0]>properti[index+2*j+1])properti[index+2*j+0]=properti[index+2*j+1]; 
    }else if(properti[index+2*j+0]>properti[index+2*j+1]){ 
     properti[index+2*j+0]-=del; 
     if(properti[index+2*j+0]<properti[index+2*j+1])properti[index+2*j+0]=properti[index+2*j+1]; 
    } 

    if(properti[index+2*j+0]==properti[index+2*j+1])properti[index+2*j+1]=(mactive[i]>0)?Math.floor(properti[index+2*j+0]-90+180*Math.random()):0; 

    if(properti[index+2*j+1]<0)properti[index+2*j+1]=0; 
    if(properti[index+2*j+1]>360)properti[index+2*j+1]=360; 

    j++; 
   } 
  }else{ 
   var j=0; 
   while(j<selangdata/2){ 
    properti[index+2*j+0]=0; 
    properti[index+2*j+1]=Math.floor(properti[index+2*j+0]-90+270*Math.random()); 

    if(properti[index+2*j+1]<0)properti[index+2*j+1]=0; 
    if(properti[index+2*j+1]>360)properti[index+2*j+1]=360; 

    j++; 
   } 
  } 

  ctx.strokeStyle = warna[a]; 

  var index=selangdata*i; 
  for(m=0;m<numlingkaran;m++){ 
   ctx.save(); 
   ctx.translate(lastPosition[2*i+0],lastPosition[2*i+1]); 
   ctx.rotate(properti[index+b*m+0]*Math.PI/180); 

   ctx.beginPath(); 
   if(m%numlingkaran==0){ 
    ctx.lineWidth=300; 
    ctx.arc(0,0,150,0,properti[index+b*m+2]*Math.PI/180); 
   }else if(m%numlingkaran==1){ 
    ctx.lineWidth=150; 
    ctx.arc(0,0,200,0,properti[index+b*m+2]*Math.PI/180); 
   }else{ 
    ctx.lineWidth=100; 
    ctx.arc(0,0,150,0,properti[index+b*m+2]*Math.PI/180); 
   } 
   ctx.stroke(); 
   ctx.closePath(); 
   ctx.restore(); 
  } 
  if(mactive[i]>0)mactive[i]--; 
 } 

 window.requestAnimationFrame(Menggambar); 
} 
 
Menggambar(); 
</script> 
</body> 
</html> 

Komentar



Postingan populer dari blog ini

Jasa Penjadwalan Semester, UTS dan UAS Perguruan Tinggi menggunakan Google Sheet

Menyikapi Ucapan AI Pejabat

Peringatan: Aksi Penipuan Skimming Melalui Aplikasi Android M-Pajak

Kebodohan Karyawan Menyalahkan Sistem

Ketika Pengelola Basis Data Terabaikan

Checking Data yang Belum Dimasukkan dalam Daftar Menggunakan Query Google Sheet

Apps Script untuk Cetak Sertifikat

Kumpulan Source Code Greenfoot

Menyembunyikan Failed Load Images di Blogger

Game TicTacToe dengan Greenfoot