Working with canvas

69 views
Skip to first unread message

Ranjit kumar Kundu

unread,
Sep 23, 2016, 7:20:27 AM9/23/16
to Selenium Users
How to work with objects inside or displayed inside the canvas using web driver or action class or any other solution is available if???

David

unread,
Sep 23, 2016, 6:14:23 PM9/23/16
to Selenium Users
Via the DOM, for whatever is exposed to the DOM? I don't think Selenium exposes specific methods to work with canvas. So you try to find the elements by XPath, CSS and manipulate it (click, drag & drop, etc.), or directly manipulate via javascript.

The last resort option for those who work with canvas's developed internally (not a 3rd party component you just add in), have your web developer add in automation support such that you can invoke special javascript that makes it do some stuff you need it to do, or to extract out certain data you want to validate. I had to do that once when I couldn't automate the canvas widget using normal means (Selenium API, javascript) to move an object inside around. Thankfully the developer obliged to my request.

Also, for canvas objects, for validating things inside the canvas, you can actually call javascript to extract out the canvas image as base64 and then save to file or compare the base64 content directly for things like an exact (or fuzzy logic) image comparison. Or you can do the simpler screenshot route. I did the javascript route to pull out the image for comparison. e.g. https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toDataURL

Kristjan Robam

unread,
Dec 22, 2019, 9:56:50 AM12/22/19
to Selenium Users
A sample to use canvas:

<canvas id="myCanvas" width="200" height="100" style="border:1px solid #000000;">
</canvas>

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.moveTo(00);
ctx.lineTo(200100);
ctx.stroke();

It gets more difficult, when you have more difficult problems.
Please check out my internet game to learn it a little deeply :

Index.html:

<html>
<head>
<meta name="viewport" content="width=345, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0">
<script src="jquery.min.js"></script>
<style type="text/css">
.a1 {
color: #F0F0F0;
}
body {
background-color: black;
}
.a15 {
color: #f1c12a;
font-size:15px;
}
.currtime {
color: #f1c12a;
}
.a2 {
color: #b2bc33;
width: 345px;
position:absolute;
top:500px;
}
.link1 {
  color: #b2bc33;
}
a:link {
color: #b2bc33;
}
.a3 {
position:relative;
top:-1vw;
}
.myCanvas {
position:relative;
left:0vw;
display: inline-block;
}
.score {
   font-size:15px;
   color: #f1c12a;
}
.currtime {
   font-size:15px;
}
.toplist {
   font-size:15px;
   color: #f1c12a;
}

.aaa1 {
    display:inline-block;
height: 520px;
}
@media (max-width: 345px) {
   .topplayers {
   display:block;
   position:relative;
   width:345px;
   vertical-align:top;
  left: 0px;  
      top: 0px;
   }
}
@media (min-width: 345px) {
.topplayers {
   display:block;
   position:relative;
   width:345px;
   vertical-align:top;
   left: 0px;
   top: -20px;
}
}

/*
* {
  outline: 5px dotted green;
}
*/
</style>
</head>
<body>
<h1 class="a1"> Click game </h1>
<p class="a3"></p>
<div class="aaa1">
<canvas class="myCanvas" width="345" height="430" style="border:1px solid #d3d3d3;">
Error</canvas>
<p class="a2">Author: Kristjan Robam . Email: <br> robamm...@aol.com . <a href="clickgame2.0.7z">Download</a></p>
</div>
<div class="topplayers">
<h1 class="a15">Click as many circles as you can in 35 seconds !</h1>
<button id="startgame1" name="Start!" onclick="startgameofclicks()">Start!</button>
<h1 class="a15">Score:</h1>
<div class="score">0</div>
<h1 class="a15">Time:</h1>
<div class="currtime">0</div>
<h1 class="a15">Top players:</h1>
<div class="toplist"></div>
</div>


<script>
var aaa=16;
var aaa12=3;

var cola=new Array();
const circles = new Array();

var circlenr=1;
var x = 10;
var y = 100;
var r = 15;
var nextX, nextY;
var WIDTH = 313;
var HEIGHT = 399;
var countt=0;
var circlesnumber=1;
var gamestatus="";
var currenttimea=0;
var lastimea=0;
var currenttimeb=0;
var lastimeb=0;
var currenttimec=0;
var lastimec=0;

var playerscore=0;


function getRandomInt(min, max) {
    min = Math.ceil(min);
    max = Math.floor(max);
    return Math.floor(Math.random() * (max - min + 1)) + min;
}


function randomdir(direction) {
   newdirection="";
   while(true) {
      var newd=getRandomInt(1,4);
  if(newd==1) newdirection="right";
  if(newd==2) newdirection="up";
  if(newd==3) newdirection="left";
  if(newd==4) newdirection="down";
  if(direction!=newdirection) break;
   }   
   return newdirection;
}
function randomdir() {
   newdirection="";
   var newd=getRandomInt(1,4);
   if(newd==1) newdirection="right";
   if(newd==2) newdirection="up";
   if(newd==3) newdirection="left";
   if(newd==4) newdirection="down";
   return newdirection;
}
function getnextdegree(degree) {
   var newdeg=degree+10;
   if(newdeg>359) newdeg=newdeg-360;
   return newdeg;
}


function rgbToHexaaa(ccccc) {
  var hex = ccccc.toString(16);
  return hex.length == 1 ? "0" + hex : hex;
}
function rgbToHex(r, g, b) {
  return "#" + rgbToHexaaa(r) + rgbToHexaaa(g) + rgbToHexaaa(b);
}


function getnextcolor() {
var aa1=getRandomInt(0,256);
var aa2=getRandomInt(0,256);
var aa3=getRandomInt(0,256);
return rgbToHex(aa1, aa2, aa3);
}



var c = document.getElementsByClassName("MyCanvas")[0];
var ctx = c.getContext("2d");
ctx.beginPath();
ctx.rect(0, 0, 347, 423);
ctx.closePath();

function isinCircle(evx, evy, circlex, circley, r) {
   return Math.sqrt((evx-circlex)*(evx-circlex) + (evy-circley)*(evy-circley)) < r;
}
c.addEventListener('click', function(event) {
     var rect = c.getBoundingClientRect();
 
//var ev_x=event.pageX-rect.left;
//var ev_y=event.pageY-rect.top;
 
 
var mouse_x=(event.clientX - rect.left) / (rect.right - rect.left) * c.width;
var mouse_y=(event.clientY - rect.top) / (rect.bottom - rect.top) * c.height;

    var canvasOffset=$(".myCanvas").offset();

     var offsetX=canvasOffset.left;
     var offsetY=canvasOffset.top;
 
var ev_x=event.pageX-offsetX;
var ev_y=event.pageY-offsetY;
for (var i = circles.length - 1; i >= 0; --i) {
if(isinCircle(ev_x, ev_y, circles[i].x+7.5, circles[i].y+7.5, 30)) {
if(gamestatus=="stop") break;
playerscore++;
document.getElementsByClassName("score")[0].innerHTML = playerscore;
circles.splice(i,1);
} else {
}
}
}); 

function getRandomColor() {
  var letters = '0123456789ABCDEF';
  var color = '#';
  for (var i = 0; i < 6; i++) {
    color += letters[Math.floor(Math.random() * 16)];
  }
  return color;
}

var imgObj;

function clear() {
  ctx.clearRect(0, 0, c.width, c.height);
}


function drawcircle(circlea) {

  //clear();
  ctx.save();
  ctx.beginPath();
  ctx.translate(circlea.x+16,circlea.y+16);
  circlea.degree=getnextdegree(circlea.degree);  
  ctx.rotate(circlea.degree*Math.PI/180);
  ctx.translate(-circlea.x-16,-circlea.y-16);
  ctx.drawImage(imgObj, circlea.x, circlea.y, 32,32);
  ctx.closePath();
  ctx.restore();

}
function createnewcircle123() {
    var x_rand=getRandomInt(0,WIDTH);
var y_rand=getRandomInt(0,HEIGHT);
var newid=circlenr;
var newcirc = {
x: x_rand,
y: y_rand,
radius: aaa,
color: getRandomColor(),
direction: randomdir(),
id: 're'+newid,
degree: 0
}
circles.push(newcirc);
drawcircle(newcirc);
}

function createnewcircle() {
    var x_rand=getRandomInt(0,WIDTH);
var y_rand=getRandomInt(0,HEIGHT);
var newid=circlenr++;
var newcirc = {
x: x_rand,
y: y_rand,
radius: aaa,
color: getRandomColor(),
direction: randomdir(),
id: 're'+newid,
degree: 0
}
circles.push(newcirc);
drawcircle(newcirc);
}

function createnewcirclexy(x,y) {
    var x_rand=x;
var y_rand=y;
var newid=circlenr++;
var newcirc = {
x: x_rand,
y: y_rand,
radius: aaa,
color: getRandomColor(),
direction: randomdir(),
id: 're'+newid,
degree: 0
}
circles.push(newcirc);
drawcircle(newcirc);
}



c.onclick = function (event)
{
    if(gamestatus=="stop") return;
}
var nameentered=false;

function displaytoppl() {
    //console.log("refreshing");
$.ajax({
url: 'process.php',
dataType: 'json',
type: 'POST',
async: true,
data: { action: 'get'},
success: function( data, textStatus, jQxhr ){                        
var data1=data;
//console.log(data);
var listofpl="Player &nbsp;&nbsp;&nbsp; Clicks<br>";
for(var i=0; i<data1.length; i++) {
listofpl=listofpl+data1[i]['playername']+" &nbsp;&nbsp;&nbsp;"+data1[i]['playerscore']+"<br>";
}
document.getElementsByClassName("toplist")[0].innerHTML = listofpl;
},
error: function( jqXhr, textStatus, errorThrown ){
/*
console.log("viga");
console.log(textStatus);
console.log(jqXhr);
console.log(errorThrown);
*/
}
});
}

function entername() {

    if(nameentered) return;
var name = prompt("Your name:", "");
    var psc=playerscore;
    nameentered=true;
$.ajax({
url: 'process.php',
dataType: 'text',
type: 'POST',
async: true,
data: { playername: name, playerscore: psc, action: 'add'},
success: function( data, textStatus, jQxhr ){
//console.log("added: "+data);
displaytoppl();
//console.log(data);
},
error: function( jqXhr, textStatus, errorThrown ){
//console.log("error: "+textStatus);
displaytoppl();
//console.log(jqXhr);
}
});
}


function makeamove(circle) {
switch(circle.direction) {
  case "right":
  {
      if(circle.x<WIDTH) {
circle.x=circle.x+aaa12;
break;
  } else {
      circle.direction=randomdir("right");
  makeamove(circle, circle.direction);
  break;
  }
  } break;
  case "left":
  {
      if(circle.x>0) {
circle.x=circle.x-aaa12;
break;
  } else {
      circle.direction=randomdir("left");
  makeamove(circle, circle.direction);
  break;
  }
  } break;
  case "up":
  {
      if(circle.y>0) {
circle.y=circle.y-aaa12;
break;
  } else {
      circle.direction=randomdir("up");
  makeamove(circle, circle.direction);
  break;
  }
  } break;
  case "down":
  {
      if(circle.y<HEIGHT) {
circle.y=circle.y+aaa12;
break;
  } else {
      circle.direction=randomdir("down");
  makeamove(circle, circle.direction);
  break;
  }
  }  break;
  default: 

}

}

var playingtime=0;
function gameofclicks() {
    if(nameentered) return;
//console.log(playingtime);
if(playingtime>35000) gamestatus="stop";
    //if(circles.length>100) alert(circles.length);
    if(circles.length>150) gamestatus="stop";

    if(nameentered == 'true') return;
    //console.log("game status: "+gamestatus);
    if(gamestatus == 'stop') entername();  
countt++;
    clear(WIDTH, HEIGHT);

for(var i=0; i<circles.length; i++) {
  var circle=circles[i];    
      makeamove(circle);
  circlenr++;
  drawcircle(circle);
         
  }
  
  currenttimea=currenttimea+50;
  currenttimeb=currenttimeb+50;
  currenttimec=currenttimec+50;
  
  document.getElementsByClassName("currtime")[0].innerHTML = parseInt(currenttimea/1000);

  if(currenttimec-lastimec>250) {
for(var i=0; i<circles.length; i++) {
circles[i].color=getnextcolor();     
}
        lastimec=currenttimec;
  }
  if(currenttimea-lastimea>700) {
      createnewcircle();
  lastimea=currenttimea;
for(var i=0; i<circles.length; i++) {
                circles[i].direction=randomdir(circles[i].direction);
}
  
  }

  if(currenttimeb-lastimeb>10000) {
      displaytoppl();
  lastimeb=currenttimeb;
  
  }   
  playingtime=playingtime+50;
      setTimeout(gameofclicks, 50);
  
  
}


$( document ).ready(function() {

    imgObj=new Image();
    imgObj.src = 'circle.png';

    displaytoppl();
createnewcircle123();
imgObj.onload = function()
{
ctx.drawImage(imgObj, circles[0].x, circles[0].y, 32, 32);
}
});

function startgameofclicks() {
  $("#startgame1").remove();
  setTimeout(gameofclicks, 50);
}


</script>
</body>
</html>


process.php:

<?php

//error_reporting( E_ALL );

class Person {
   public $playername;
   public $playerscore;
   public function __construct($aa,$bb) {
   $this->playername=$aa;
   $this->playerscore=$bb;
   
   }
}
function mysort($aa, $bb)
{
    if($aa->playerscore==$bb->playerscore) {
       return strcmp($aa->playername, $bb->playername);
    }
    return $aa->playerscore<$bb->playerscore;

}

$scores=array();
$filePath = getcwd().DIRECTORY_SEPARATOR."notice.txt";


//echo $filePath;

if(file_exists($filePath)) {
$objData = file_get_contents($filePath);
$scores = unserialize($objData);    
    if($scores==null) $scores=array();
} else {
$f=fopen($filePath, "w+");
    chmod($filePath, 0777);
    fclose($f);
}

$playername=null;
$playerscore=null;

$action=$_POST['action'];

if($action=="add") {
$playername=$_POST['playername'];
$playername=strip_tags($playername);
$playerscore=$_POST['playerscore'];
}

/*
$playername="Kristjan";
$playerscore=35;
$action="get";
*/

if($action=="add") {
    if($playername!=""&&$playerscore>-1&&$playerscore<48) {
$obj = new Person($playername,$playerscore);
            $scores[]=$obj;
$objData = serialize( $scores);
//echo "starting to add";
//unlink($filePath);
if(is_writable($filePath)) {
$fffa=fopen($filePath, "w+");
fwrite($fffa, $objData); 
//chmod($filePath, 0777);
fclose($fffa);
}
//echo "added";
//echo json_encode($scores);

}


} else if($action=="get") {
            //var_dump($_POST);
usort($scores, "mysort");
//var_dump($scores);
echo json_encode($scores,true);
}

?>

With the best wishes,
Kristjan Robam

Kristjan Robam

unread,
Dec 23, 2019, 4:28:07 AM12/23/19
to Selenium Users
Improved version of index.html:


<html>
<head>
<meta name="viewport" content="width=345, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0">
<script src="jquery.min.js"></script>
<style type="text/css">
.a1 {
color: #F0F0F0;
}
body {
background-color: black;
}
.a15 {
color: #f1c12a;
font-size:15px;
}
.currtime {
color: #f1c12a;
}
.a2 {
color: #b2bc33;
width: 345px;
position:absolute;
top:480px;
}
.link1 {
  color: #b2bc33;
}
a:link {
color: #b2bc33;
}
.a3 {
position:relative;
top:-1vw;
}
.myCanvas {
position:relative;
left:0vw;
display: inline-block;
top:-15px;
}
.score {
   font-size:15px;
   color: #f1c12a;
}
.currtime {
   font-size:15px;
}
.toplist {
   font-size:15px;
   color: #f1c12a;
}

.aaa1 {
    display:inline-block;
height: 520px;
display:absolute;
top:10px;
}
@media (max-width: 345px) {
   .topplayers {
   display:block;
   position:relative;
   width:345px;
   vertical-align:top;
  left: 0px;  
      top: -60px;
   }
}
@media (min-width: 345px) {
.topplayers {
   display:block;
   position:relative;
   width:345px;
   vertical-align:top;
   left: 0px;
   top: -60px;
}
}

/*
* {
  outline: 5px dotted green;
}
*/
</style>
</head>
<body>
<h1 class="a1"> Click game </h1>
<p class="a3"></p>
<div class="aaa1">
<canvas class="myCanvas" width="345" height="430" style="border:1px solid #d3d3d3;">
Error</canvas>
<p class="a2">Author: Kristjan Robam . Email: <br> robamm...@aol.com . <a href="clickgame4.7z">Download</a></p>
var newcirclecreationcount=0;
function circlescollidingextended(ca1_x, ca1_y, ca2_x, ca2_y, radiusa1) {
     if(Math.sqrt((ca1_x-ca2_x)*(ca1_x-ca2_x)+(ca1_y-ca2_y)*(ca1_y-ca2_y)<radiusa1*2)) return true;
return false;
}

function cancreatecircle(x111, y111) {
  var collision=false;
          for (var i=0; i<circles.length; i++) {
   if(circlescollidingextended(x111,y111,circles[i].x,circles[i].y,circles[i].radius)) {
  collision=true;
  return false;
  break;
   }
  }
  if(collision) return false;
  return true;
}

function circlescolliding(circlea1, circlea2) {
     if(Math.sqrt((circlea1.x-circlea2.x)*(circlea1.x-circlea2.x)+(circlea1.y-circlea2.y)*(circlea1.y-circlea2.y))<circlea1.radius*2) return true;
return false;
if(!cancreatecircle(x_rand,y_rand)) {
newcirclecreationcount++;
if(newcirclecreationcount>5000) {
    gamestatus='stop';
    return;
}
createnewcircle();
return;
var x_rand=getRandomInt(0,WIDTH);
var y_rand=getRandomInt(0,HEIGHT);

switch(circle.direction) {
  case "right":
  {
  var collision=false;
          for (var i=0; i<circles.length; i++) {
       if(circle.id!=circles[i].id) {
       if(circlescolliding(circle,circles[i])) {
      collision=true;
  circle.direction="left";
  circle.x=x_rand;
  circle.y=y_rand;
  return;
  break;
   }
   }
  }
  if(collision) break;
  if(circle.x<WIDTH) {
circle.x=circle.x+aaa12;
break;
  } else {
      circle.direction=randomdir("right");
  makeamove(circle);
  break;
  }
  } break;
  case "left":
  {
  var collision=false;
          for (var i=0; i<circles.length; i++) {
       if(circle.id!=circles[i].id) {
       if(circlescolliding(circle,circles[i])) {
      collision=true;
  
  circle.direction="right";
  circle.x=x_rand;
  circle.y=y_rand;

  return;
  break;
   }
   }
  }
  if(collision) break;  
      if(circle.x>0) {
circle.x=circle.x-aaa12;
break;
  } else {
      circle.direction=randomdir("left");
  makeamove(circle);
  break;
  }
  } break;
  case "up":
  {
  var collision=false;
          for (var i=0; i<circles.length; i++) {
       if(circle.id!=circles[i].id) {
       if(circlescolliding(circle,circles[i])) {
      collision=true;
  
  circle.direction="down";
  circle.x=x_rand;
  circle.y=y_rand;

  return;
  break;
   }
   }
  }
  if(collision) break;  
      if(circle.y>0) {
circle.y=circle.y-aaa12;
break;
  } else {
      circle.direction=randomdir("up");
  makeamove(circle);
  break;
  }
  } break;
  case "down":
  {
  var collision=false;
          for (var i=0; i<circles.length; i++) {
       if(circle.id!=circles[i].id) {
       if(circlescolliding(circle,circles[i])) {
      collision=true;
  circle.direction="up";
  circle.x=x_rand;
  circle.y=y_rand;

  return;
  break;
   }
   }
  }
  if(collision) break;  
      if(circle.y<HEIGHT) {
circle.y=circle.y+aaa12;
break;
  } else {
      circle.direction=randomdir("down");
  makeamove(circle);
      newcirclecreationcount=0;
Reply all
Reply to author
Forward
0 new messages