how to store multiple value in an array? - javascript

I'm a new leaner for JavaScript. I wanna create an array to store multiple x and y values for one object (array[0]), then use this values to compare with canvas drawing object x and y coordinates.
For example I have the fix x and y values as below:
(x : y)
585 : 225
584 : 231
579 : 254
573 : 271
570 : 279
570 : 280
I will get the drawing object x and y coordinates and compare with the above values. if more then 3 group of x and y values wrong then show:wrong answer. it's possible to do that? Thank you! please help...
here is the coding:
<!DOCTYPE html>
<html><head>
<style>
#contain {
width: 500px;
height: 120px;
top : 15px;
margin: 0 auto;
position: relative;
}
</style>
<script>
var touchList = [];
var plates = [];
var currentPlates;
var currentIndex = 0;
var canvas;
var ctx;
var lastPt=null;
var letsdraw = false;
var offX = 440, offY = 25;
function init() {
var touchzone = document.getElementById("layer1");
touchzone.addEventListener("touchmove", draw, false);
touchzone.addEventListener("touchend", end, false);
ctx = touchzone.getContext("2d");
}
function draw(e) {
e.preventDefault();
var selectedCoordinate = new Object();
selectedCoordinate.x = e.touches[0].pageX;
selectedCoordinate.y = e.touches[0].pageY;
touchList.push(selectedCoordinate);
console.log("X: " + e.touches[0].pageX + " Y: " + e.touches[0].pageY);
if (lastPt != null) {
ctx.beginPath();
ctx.moveTo(lastPt.x, lastPt.y);
ctx.lineTo(e.touches[0].pageX - offX,
e.touches[0].pageY - offY);
ctx.stroke();
}
lastPt = {
x: e.touches[0].pageX - offX,
y: e.touches[0].pageY - offY
};
}
function end(e) {
for(var i=0; i<touchList.length; i++)
console.log(touchList[i].x + " : " + touchList[i].y);
var touchzone = document.getElementById("layer1");
e.preventDefault();
//Terminate touch path
lastPt = null;
}
function clear_canvas_width ()
{
var s = document.getElementById ("layer1");
var w = s.width;
s.width = 10;
s.width = w;
}
function initPlates() {
plates[0] = new Plates(1, 568, 262);
generateQuestion(isEasy);
for(var i=0; i<currentPlates.length; i++) {
console.log("Index: " + i + " value: " + currentPlates[i].index);
}
}
function Plates(index, correct, deficient) {
this.index = index;
this.correct = correct;
this.deficient = deficient;
}
Plates.prototype.checkAnswer = function(answer) {
console.log("Checking user answer: " + answer);
this.userAnswer = answer;
if(answer == this.correct)
this.result = "Correct";
else
this.result = "Wrong";
}
</script>
</head>
<body onload="init()">
<div id="contain">
<canvas id="layer1" width="450" height="440" style="position: absolute; left: 0; top: 0;z-index:0; border: 1px solid #ccc;"></canvas>
</div>
</body>
</html>

You can try to store object instead of multidimensional array.
var coords=new Array();
coords.push({x:584,y:225});
coords.push({x:588,y:222});
var xcoord =coords[0].x;
var ycoord =coords[0].y;

Related

Please i need help: Trying to have my animation move from initial coordinates to new inputted coordinates using JavaScript

I have Layout with a machine, i intend to have this machine (purple animation) move from point A to point B based on input cordinate x and cordinate Y. I followed some online tutorials but still not been able to get it. The animation currently moves manually with arrow keys but i intend to have it move automatically. The aim is to have the animation move at a slow frame pace to the inserted coordinates. Any help will be appreciated.
HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title> Farm Harvest </title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="grid"></div>
<input type="number" id = 'cords1' placeholder="X-Cordinates">
<input type="number" id = 'cords2' placeholder="Y-Cordinates">
<button id = "mybtn" onclick="myCords();">Get Value</button>
<script src="app.js"></script>
</body>
</html>
CSS:
.grid {
position: absolute;
width: 560px;
height: 300px;
border: solid 1px black;
margin-top: 100px;
}
.user {
position: absolute;
width: 30px;
height: 20px;
background-color: blueviolet;
}
.block {
position: absolute;
width: 100px;
height: 20px;
background-color: blue;
}
JS:
const grid = document.querySelector('.grid')
const value1 = document.getElementById('cord1')
const value2 = document.getElementById('cord2')
const blockWidth = 100
const blockHeight = 20
const boardWidth = 560
const boardHeight = 300
var mouseX, mouseY;
var stepWidthFactor = 200;
const userStart = [10, 270]
let currentPosition = userStarnst userStart1 = [10, 270]
let currentPosition1 = userStart1
const user1 = [10, 270]
let currentPosition2 = user1
//my block
class Block {
constructor(xAxis, yAxis) {
this.bottomLeft = [xAxis, yAxis]
this.bottomRight = [xAxis + blockWidth, yAxis]
this.topRight = [xAxis + blockWidth, yAxis + blockHeight]
this.topLeft = [xAxis, yAxis + blockHeight]
}
}
class moveblock{
constructor(xAxis,yAxis){
this.xAxis = inputval0;
this.yAxis = inputval1;
let currentPosition3 = user2;
}
}
//all my blocks
const blocks = [
new Block(120, 210),
new Block(230, 210),
new Block(340, 210),
new Block(120, 140),
new Block(230, 140),
new Block(340, 140),
new Block(120, 70),
new Block(230, 70),
new Block(340, 70),
]
//draw my blocks
function addBlocks() {
for (let i = 0; i < blocks.length; i++) {
const block = document.createElement('div')
block.classList.add('block')
block.style.left = blocks[i].bottomLeft[0] + 'px'
block.style.bottom = blocks[i].bottomLeft[1] + 'px'
grid.appendChild(block)
console.log(blocks[i].bottomLeft)
}
}
addBlocks()
//add user
const user = document.createElement('div')
user.classList.add('user')
grid.appendChild(user)
drawUser()
//move user
function moveUser(e) {
switch (e.key) {
case 'ArrowLeft':
if (currentPosition[0] > 0) {
currentPosition[0] -= 10
console.log(currentPosition[0] > 0)
drawUser()
}
break
case 'ArrowRight':
if (currentPosition[0] < (boardWidth - blockWidth)) {
currentPosition[0] += 10
console.log(currentPosition[0])
drawUser()
}
break
case 'ArrowDown':
if (currentPosition1[0] < (boardHeight - blockHeight)) {
currentPosition1[0] += 10
console.log(currentPosition1[0]>0)
drawUser()
}
break
case 'ArrowUp':
if (currentPosition1[0] > 0) {
currentPosition1[0] -= 10
console.log(currentPosition1[0])
drawUser()
}
break
}
}
document.addEventListener('keydown', moveUser)
//draw User
function drawUser() {
user.style.top = currentPosition1 [0] + 'px'
user.style.left = currentPosition[0] + 'px'
user.style.bottom = currentPosition[0] + 'px'
user.style.right = currentPosition[0] + 'px'
}
function myCords(){
const user2 = [inputval0,inputval1]
let currentPosition3 = user2;
var inputval0 = document.getElementById('cords1').value;
var inputval1 = document.getElementById('cords2').value;
if(inputval0 < boardHeight && inputval1 < boardWidth && inputval0 != 0 && inputval1 != 0){
alert("good cords " + "X: "+ inputval0 + " " +"Y: " +inputval1)
}
else{
alert("wrong cordinates")
}
}document.addEventListener('onclick',myCords)
function drawnewUser(){
user.style.left = currentPosition + 'px';
user.style.top = currentPosition + 'px'
user.style.bottom = currentPosition + 'px'
user.style.right = currentPosition + 'px'
}

How can i implement a simple menu for my game made with HTML?

i'm making a simple game with HTML only, more or less it works... My question is if i can make a simple menu /with "click to start" or something similar/ with an image at the background and 1 button to start the game. And if i can make it in the same archive.
Thanks.
<canvas id="ctx" width="1024" height="800" style="border:3px solid #000000;"></canvas>
<script>
var Height = 800;
var Width = 1024;
var timeElapset = Date.now();
var ctx = document.getElementById("ctx").getContext("2d");
ctx.font = '30px Consolas';
var frameCount = 0;
var score = 0;
var player = {
x:50,
spdX:30,
y:40,
spdY:30,
name:'P',
hp:10,
width:20,
height:20,
color:'green',
};
var enemyList = {};
getDistance = function (Obj1,Obj2){
var vx = Obj1.x - Obj2.x;
var vy = Obj1.y - Obj2.y;
return Math.sqrt((vx*vx)+(vy*vy));
}
checkCollision = function (Obj1,Obj2){
var rect1 = {
x: Obj1.x - Obj1.width/2,
y: Obj1.y - Obj1.height/2,
height: Obj1.height,
width: Obj1.width,
}
var rect2 = {
x: Obj2.x - Obj2.width/2,
y: Obj2.y - Obj2.height/2,
height: Obj2.height,
width: Obj2.width,
}
return testCollisionRectRect(rect1,rect2); //true o false
}
Enemy = function (id,x,y,spdX,spdY,width,height){
var enemy = {
x:x,
spdX:spdX,
y:y,
spdY:spdY,
name:'E',
id:id,
width:width,
height:height,
color:'black',
};
enemyList[id] = enemy;
}
document.onmousemove = function(mouse){
var mouseX = mouse.clientX - document.getElementById('ctx').getBoundingClientRect().left;
var mouseY = mouse.clientY - document.getElementById('ctx').getBoundingClientRect().top;
if(mouseX < player.width/2)
mouseX = player.width/2;
if(mouseX > Width-player.width/2)
mouseX = Width - player.width/2;
if(mouseY < player.height/2)
mouseY = player.height/2;
if(mouseY > Height - player.height/2)
mouseY = Height - player.height/2;
player.x = mouseX;
player.y = mouseY;
}
updateEntity = function (Z){
updatePosition(Z);
drawPlayer(Z);
}
updatePosition = function(Z){
Z.x += Z.spdX;
Z.y += Z.spdY;
if(Z.x < 0 || Z.x > Width){
Z.spdX = -Z.spdX;
}
if(Z.y < 0 || Z.y > Height){
Z.spdY = -Z.spdY;
}
}
testCollisionRectRect = function(rect1,rect2){
return rect1.x <= rect2.x+rect2.width &&
rect2.x <= rect1.x+rect1.width &&
rect1.y <= rect2.y + rect2.height &&
rect2.y <= rect1.y + rect1.height;
}
drawPlayer = function(Z){
ctx.save();
ctx.fillStyle = Z.color;
ctx.fillRect(Z.x-Z.width/2,Z.y-Z.height/2,Z.width,Z.height);
ctx.restore();
}
update = function(){
ctx.clearRect(0,0,Width,Height);
frameCount++;
score++;
if(frameCount % 100 == 0)
randomGenerateEnemy();
for(var key in enemyList){
updateEntity(enemyList[key]);
var isColliding = checkCollision(player, enemyList[key]);
if(isColliding){
player.hp = player.hp -1;
}
}
if(player.hp <= 0){
var timeSurvived = Date.now() - timeElapset;
console.log("Has ganado Kappa, Tiempo vivo " + timeSurvived + " ms.");
ctx.fillText(" You Lose! ", Width/2, Height/2);
GameEngine();
}
drawPlayer(player);
ctx.fillText(player.hp + " Hp",20,30);
ctx.fillText('Puntuacion: ' + score/10,700,30);
}
GameEngine = function(){
player.hp = 13;
timeElapset = Date.now();
frameCount = 0;
score = 0;
enemyList = {};
randomGenerateEnemy();
randomGenerateEnemy();
randomGenerateEnemy();
randomGenerateEnemy();
}
randomGenerateEnemy = function(){
var x = Math.random()*Width;
var y = Math.random()*Height;
var height = 10 + Math.random()*70;
var width = 10 + Math.random()*70;
var id = Math.random();
var spdX = 5 + Math.random() * 5;
var spdY = 5 + Math.random() * 5;
Enemy(id,x,y,spdX,spdY,width,height);
}
GameEngine();
setInterval(update,30);
</script>
That's what i have.
The code also contains javascript.For proper gaming function .js file has to be called on your html page.Also use css to make it attractive.Consider this example
enter code here
<html>
<head>
<title>Your game title</title>
<script type="text/javascript" src="src/Common.js"></script>
<script type="text/javascript" src="src/Perlin.js"></script>
<script type="text/javascript" src="src/ChaikinCurve.js"></script>
<script type="text/javascript">
var app = null;
window.onload = function() {
utils.loadShaderXml("src/render/shaders.xml", null, function(shaders) {
if (shaders instanceof Exception) {
app = shaders;
} else {
try {
app = new App('canvas', shaders, null);
} catch (e) {
app = e;
}
}
});
document.onselectstart = function () {
return false;
};
};
function application() {
if (app == null) {
alert("Application is absent");
throw "no application";
} else if (app instanceof Exception) {
alert("An exception occured while creating the application:\n" + app.message);
throw app;
} else {
return app;
}
}
</script>
<style type="text/css">
body{
margin: 0px; padding: 0px; overflow: hidden;
background: #000;
}
#canvas-holder.active {
position: absolute;
padding: 0px;
left: 50%;
top: 50%;
}
#canvas-holder.inactive {
position: absolute;
top:50%;
width: 100%;
text-align: center;
}
#canvas {
padding: 0px;
width: 100%;
height: 100%;
color: #fff;
font-family: Allan, Arial;
font-size: 40px;
}
</style>
</head>
<body>
<div id="canvas-holder" class="inactive">
<div id="canvas">Your game` is loading...</div>
</div>
<div style="font-family: Lobster; visibility: hidden">one</div>
<div style="font-family: Allan; visibility: hidden">two</div>
<div style="font-family: Meddon; visibility: hidden">three</div>
<div style="font-family: Cuprum; visibility: hidden">four</div>
</body>
</html>

JavaScript function only affects first div with class

I have part of a game where the cursor is supposed to "slow down" when it passes over certain divs. I'm using a function that can detect a collision with the div. This works fine when the cursor meets the first div, but it doesn't work at all on the second div.
Check out this jsFiddle for a better idea of what I'm talking about. Pass the cursor over the first white block (class='thing') on the left and it slows down. Pass the cursor over the other block (also class='thing'), and nothing happens. I need this collision function to work on all divs where class='thing'.
HTML
<div id='cursor'>
</div>
<div class='thing' style='width:70px; height:70px; background: #fff; position: absolute; bottom: 350px; right: 800px; z-index: -1;'>
</div>
<div class='thing' style='width:70px; height:70px; background: #fff; position: absolute; bottom: 200px; right: 400px; z-index: -1;'>
</div>
JS
(function collide(){
var newInt = setInterval(function() {
function collision($cursor, $thing) {
var x1 = $cursor.offset().left;
var y1 = $cursor.offset().top;
var h1 = $cursor.outerHeight(true);
var w1 = $cursor.outerWidth(true);
var b1 = y1 + h1;
var r1 = x1 + w1;
var x2 = $thing.offset().left;
var y2 = $thing.offset().top;
var h2 = $thing.outerHeight(true);
var w2 = $thing.outerWidth(true);
var b2 = y2 + h2;
var r2 = x2 + w2;
// change 12 to alter damping higher is slower
var varies = 12;
if (b1 < y2 || y1 > b2 || r1 < x2 || x1 > r2){
} else {
varies = 200;
console.log(varies);
}
$xp += (($mouseX - $xp)/varies);
$yp += (($mouseY - $yp)/varies);
$("#cursor").css({left:$xp +'px', top:$yp +'px'});
}
$(collision($('#cursor'), $('.thing')));
//$('.result').text(collision($('#cursor'), $('.thing')));
}, 20);
})();
$thing is a collection of elements, like you want, but the problem here is that you ask specific attributes from $thing like offset().left;, which can not return more than one number, therefor it just takes the first. What you should do instead is use an .each() function to loop over all the elements in $thing.
$thing.each( function( index, element ){
//your code for each thing here
});
When you are selecting element by class name(in your case using .thing) in jQuery you will get an array of elements and collision() function will take first element in an array. so to overcome this you need to uniquely select both the elements this can be done using id as a selector,You can change your code like below to work it as expected
<div id='track'>
<div class = 'container'>
<div id='cursor' class='cursor'>
</div>
<div class='thing' id="a1" style='width:70px; height:70px; background: #fff; position: absolute; bottom: 175px; right: 400px; z-index: -1;'>
</div>
<div class='thing' id="a2" style='width:70px; height:70px; background: #fff; position: absolute; bottom: 100px; right: 200px; z-index: -1;'>
</div>
</div>
</div>
(function cursorMapping(){
var $mouseX = 0, $mouseY = 0;
var $xp = 0, $yp =0;
$(document).mousemove(function(e){
$mouseX = e.pageX;
$mouseY = e.pageY;
});
function showCoords(event) {
var x = event.clientX;
var y = event.clientY;
var coor = "X: " + x + ", Y: " + y;
}
var timestamp = null;
var lastMouseX = null;
var lastMouseY = null;
var mrefreshinterval = 500; // update display every 500ms
var lastmousex=-1;
var lastmousey=-1;
var lastmousetime;
var mousetravel = 0;
var lastmousetravel = 0;
var speed;
var marker1 = 1;
var marker2 = 1;
var timer = setInterval(function(){
marker1;
marker2;
}, 20);
$(function() {
var $speedometer = $('#speed'),
_speed = 0;
$('#track').cursometer({
onUpdateSpeed: function thisSpeed(speed) {
_speed = speed;
$speedometer.text(Math.ceil(speed * 100)/100);
},
updateSpeedRate: 20
});
});
var thisInterval = setInterval(function FXInterval(){
speed = $('#speed').text();
$('#cursor').css({'background-color': '#CE7A7A'});
}, 20);
$('html').mousemove(function(e) {
var mousex = e.pageX;
var mousey = e.pageY;
if (lastmousex > -1)
mousetravel += Math.max( Math.abs(mousex-lastmousex), Math.abs(mousey-lastmousey) );
lastmousex = mousex;
lastmousey = mousey;
var speed = lastmousex + lastmousey;
setTimeout(function(){
lastmousetravel = mousetravel;
}, 20);
});
(function collide(){
var newInt = setInterval(function() {
function collision($cursor, $thing) {
var x1 = $cursor.offset().left;
var y1 = $cursor.offset().top;
var h1 = $cursor.outerHeight(true);
var w1 = $cursor.outerWidth(true);
var b1 = y1 + h1;
var r1 = x1 + w1;
var x2 = $thing.offset().left;
var y2 = $thing.offset().top;
var h2 = $thing.outerHeight(true);
var w2 = $thing.outerWidth(true);
var b2 = y2 + h2;
var r2 = x2 + w2;
// change 12 to alter damping higher is slower
var varies = 12;
if (b1 < y2 || y1 > b2 || r1 < x2 || x1 > r2){
} else {
varies = 200;
console.log(varies);
}
$xp += (($mouseX - $xp)/varies);
$yp += (($mouseY - $yp)/varies);
$("#cursor").css({left:$xp +'px', top:$yp +'px'});
}
$(collision($('#cursor'), $('#a1')));
$(collision($('#cursor'), $('#a2')));
}, 20);
})();
})();

Draw a bendable arrow between two html elements

I am developing a view for some items in my web site. Currently I have the items displayed in the HTML but now I need to draw some lines between the elements that will represent a connection between them, it's like a Gantt Chart but it doesn't include any time functionality, I only need to connect the items with the ones associated to them. I'm using JSTL to bring some data from a controller and I managed to draw the elements like the following image: http://i271.photobucket.com/albums/jj131/djrickel/before.png
And the way I need to display is in the following image:
http://i271.photobucket.com/albums/jj131/djrickel/after.png
This is how I'm creating my table containing the elements that I want to display:
<div class="container">
<table>
<tbody>
<c:forEach items="${nodeGraphs}" var="nodeGraph">
<tr>
<c:forEach var="i" begin="0" end="5">
<td>
<c:if test="${nodeGraph.columnID == i}">
<label class="label label-default">${nodeGraph.nodeObject.item.type}${nodeGraph.nodeObject.item.contextId}</label>
</c:if>
</td>
</c:forEach>
</tr>
</c:forEach>
</tbody>
</table>
</div>
Does anyone know a way to create connecting lines between the elements using JQuery, JSon, Javascript or any HTML process? I can change from the table I'm using to div or span without any issue. I'm just looking the best way to display the information. Thanks in advance.
Probably the best way to do that is use HTML5 canvas, but if You want use div's try use this code:
(On JSFiddle: http://fiddle.jshell.net/22rar61n/9/)
var Line = (function() {
var diff = function(a, b) {
var d = Math.abs(a - b);
if (d === 0) {
d = 1;
}
return d;
}
var countWidth = function(line) {
return diff(line.endX, line.startX);
};
var countHeight = function(line) {
return diff(line.endY, line.startY);
};
var Line = function(options) {
this.startX = options.startX;
this.startY = options.startY;
this.endX = options.endX;
this.endY = options.endY;
}
Line.prototype.drowIn = function($container) {
var self = this;
var line = jQuery("<div></div>", {
class: "line " + self.LineType(),
css: {
"color": "red",
"top": self.startY,
"left": self.startX,
"width": countWidth(self),
"height": countHeight(self),
"background-color": "#000"
}
});
$container.append(line);
};
Line.prototype.LineType = function() {
if (this.startX != this.endX) {
return "horizontal";
}
return "vertical";
}
return Line;
})();
var Arrow = (function() {
var Arrow = function(start, end) {
this.start = start;
this.end = end;
}
Arrow.prototype.drowIn = function($container) {
var ArrowContainer = jQuery("<div></div>", {
class: "arrowContainer"
});
var line1 = new Line({
startX: this.start.x,
startY: this.start.y,
endX: this.start.x,
endY: this.end.y
});
line1.drowIn(ArrowContainer);
var line2 = new Line({
startX: this.start.x,
startY: this.end.y,
endX: this.end.x,
endY: this.end.y
});
line2.drowIn(ArrowContainer);
$container.append(ArrowContainer);
}
return Arrow;
})();
var Element = (function() {
var Element = function(options) {
var op = jQuery.extend({}, options);
this.x = op.x || -1;
this.y = op.y || -1;
this.content = op.content || "";
this.container = op.$container || "";
this.node = null;
this.subElements = [];
};
Element.prototype.addSubElement = function(element) {
element.container = this.container;
element.content = this.content + "." + (this.subElements.length + 1);
this.subElements.push(element);
};
Element.prototype.drow = function() {
var self = this;
this.node = jQuery("<div></div>", {
class: "element",
text: this.content,
css: {
top: self.y,
left: self.x
}
});
this.container.append(this.node);
var nexLvl = 0;
var lastHeight = nexLvl;
var lastLvl = 0;
var oldIndex = -1;
var outerHeightAndTop = jQuery(self.node).outerHeight() + jQuery(self.node).offset().top;
jQuery.each(this.subElements, function(index, element) {
var height = outerHeightAndTop * (index + 1 + lastLvl);
if (lastHeight != 0) {
height = lastHeight + outerHeightAndTop;
}
if (nexLvl != 0) {
oldIndex = index;
height = height + ((jQuery(self.node).outerHeight()) * nexLvl);
lastLvl = nexLvl;
}
lastHeight = height;
nexLvl = element.getMaxLevel();
element.x = jQuery(self.node).outerWidth() + jQuery(self.node).offset().left;
element.y = height;
element.drow();
self.connectWith(element);
});
};
Element.prototype.connectWith = function(element) {
var startY = jQuery(this.node).outerHeight() + this.y;
var startX = (jQuery(this.node).outerWidth() / 2) + this.x;
var endY = (jQuery(element.node).outerHeight() / 2) + element.y;
var arrow = new Arrow({
x: startX,
y: startY
}, {
x: element.x,
y: endY
});
arrow.drowIn(this.container);
};
function getLevelOnPosition(index) {
return this.subElements[index].getMaxLevel();
}
Element.prototype.getMaxLevel = function(initLvl) {
var lvl = initLvl || 0;
var maxLvl = lvl;
if (this.subElements.length > 0) {
maxLvl = lvl++;
}
jQuery.each(this.subElements, function(index, element) {
lvl = element.getMaxLevel(lvl);
if (lvl > maxLvl) {
maxLvl = lvl;
}
});
return maxLvl;
}
return Element;
})();
jQuery(document).ready(function() {
var container = jQuery("#container");
var e = new Element({
x: 10,
y: 10,
content: "a1",
$container: container
});
var sube = new Element();
e.addSubElement(sube);
var sube2 = new Element();
sube.addSubElement(sube2);
sube2.addSubElement(new Element());
var e2 = new Element();
e.addSubElement(e2);
e2.addSubElement(new Element());
e.addSubElement(new Element());
e.drow();
});
#container {
position: relative;
}
#container > .element {
position: absolute;
border: 1px solid black;
background-color: gray;
color: white;
padding: 2px;
z-index: 10;
}
#container > .arrowContainer {
position: absolute;
}
#container > .arrowContainer > .line {
position: absolute;
z-index: 50;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="container"></div>

How to add tooltip on draggable objects within Canvas?

In my code SVG is parse and drawn on Canvas and also orange1.png and green1.png images are plotted on SVg file. In this I am able to zoom and Pan canvas and also able to drag images which are plotted on it through JSON.
Now I want to add tooltip on the images (orange1.png and green1.png) When I click on those images or mouseover on those images.
showTooltip function is for showing the tooltip on those images(orange1.png , green1.png).
clearTooltip function is for clearing the tooltip.
Where and how should I add showTooltip and clearTooltip function in my updated code?
And which option will be better mouse click or mosehover for showing tooltip?
I tried some possibilities but I am missing something.
function showTooltip(x, y, index) {
var editedValue = [];
if (tooltip === null) {
tooltip = document.createElement('div');
tooltip.className = 'tooltip';
tooltip.style.left = (x) + 'px';
tooltip.style.top = (y) + 'px';
tooltip.innerHTML = "<input type='text' id='generic_txt' value='"+dataJSON[index].tooltiptxt[0]+"' /> <input type='submit' id='generic_edit' value='Edit'>"
document.getElementsByTagName('body')[0].appendChild(tooltip);
}
document.getElementById('generic_txt').setAttribute('disabled', 'disabled');
$("#generic_edit").click(function(){
if(document.getElementById('generic_edit').value == "Edit"){
document.getElementById('generic_txt').removeAttribute('disabled');
document.getElementById('generic_txt').focus();
document.getElementById('generic_edit').value = "Change";
} else {
document.getElementById('generic_txt').setAttribute('disabled', 'disabled');
document.getElementById('generic_edit').value = "Edit";
editedValue = $('#generic_txt').val();
dataJSON[index].tooltiptxt[0] = editedValue; // important line
}
return false;
});
}
function clearTooltip(doFade) {
if (tooltip !== null) {
var fade = 1;
function fadeOut() {
tooltip.style.opacity = fade;
fade -= 0.1;
if (fade > 0) {
setTimeout(fadeOut, 16);
} else {
remove();
}
}
function remove() {
document.getElementsByTagName('body')[0].removeChild(tooltip);
tooltip = null;
}
if (doFade === true) {
fadeOut();
//$('.first_cancel').click(fadeOut());
} else {
remove();
}
}
}
Following is my updated source code.
HTML Code :
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<style>
canvas {
border:1px solid #000
}
.tooltip{
*position:fixed;
position:absolute;
*background:#ff7;
background:green;
border:1px solid #000;
padding:7px;
font-family:sans-serif;
font-size:12px;
}
.tooltip2 {
*position:fixed;
position:absolute;
background:pink;
border:1px solid #000;
padding:7px;
font-family:sans-serif;
font-size:12px;
}
</style>
</head>
<body>
<script src="http://canvg.googlecode.com/svn/trunk/rgbcolor.js"></script>
<script src="http://canvg.googlecode.com/svn/trunk/StackBlur.js"></script>
<script src="http://canvg.googlecode.com/svn/trunk/canvg.js"></script>
<canvas id="myCanvas" width="800" height="700" style="border: 1px solid;margin-top: 10px;"></canvas>
<div id="buttonWrapper">
<input type="button" id="plus" value="+">
<input type="button" id="minus" value="-">
<input type="button" id="original_size" value="100%">
</div>
<script src="/static/js/markers.js"></script>
<script src="/static/js/draw.js"></script>
</body>
</html>
draw.js:
var dataJSON = data || [];
var dataJSON2 = data2 || [];
window.onload = function(){
//$(function(){
var canvas=document.getElementById("myCanvas");
var ctx=canvas.getContext("2d");
var canvasOffset=$("#myCanvas").offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;
var lastX=0;
var lastY=0;
var panX=0;
var panY=0;
var dragging=[];
var dragging2=[];
var isDown=false;
function loadImages(sources, callback){
var images = {};
var loadImages = 0;
var numImages = 0;
//get num of sources
for(var i in sources){
numImages++;
}
for(var i in sources){
images[i] = new Image();
images[i].onload = function(){
if(++loadImages >= numImages){
callback(images);
}
};
images[i].src = sources[i];
}
}
var sources = {orange : '/static/images/orange1.png', green : '/static/images/green1.png'};
// load the tiger image
var svgfiles = ["/static/images/awesome_tiger.svg"];
/*var tiger=new Image();
tiger.onload=function(){
draw();
}
tiger.src="tiger.png";*/
function draw(scaleValue){
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.save();
ctx.drawSvg(svgfiles[0],panX,panY,400*scaleValue, 400*scaleValue);
//ctx.drawImage(tiger,panX,panY,tiger.width,tiger.height);
//ctx.scale(scaleValue, scaleValue);
loadImages(sources, function(images){
ctx.scale(scaleValue, scaleValue);
for(var i = 0, pos; pos = dataJSON[i]; i++) {
ctx.drawImage(images.orange, parseInt(parseInt(pos.x) + parseInt(panX / scaleValue)), parseInt(parseInt(pos.y) + parseInt(panY / scaleValue)), 20/scaleValue, 20/scaleValue);
}
for(var i = 0, pos; pos = dataJSON2[i]; i++) {
ctx.drawImage(images.green, parseInt(parseInt(pos.x) + parseInt(panX / scaleValue)), parseInt(parseInt(pos.y) + parseInt(panY / scaleValue)), 20/scaleValue, 20/scaleValue);
}
ctx.restore();
});
};
var scaleValue = 1;
var scaleMultiplier = 0.8;
draw(scaleValue);
var startDragOffset = {};
var mouseDown = false;
// add button event listeners
document.getElementById("plus").addEventListener("click", function(){
scaleValue /= scaleMultiplier;
//checkboxZoomPan();
draw(scaleValue);
}, false);
document.getElementById("minus").addEventListener("click", function(){
scaleValue *= scaleMultiplier;
//checkboxZoomPan();
draw(scaleValue);
}, false);
document.getElementById("original_size").addEventListener("click", function(){
scaleValue = 1;
//checkboxZoomPan();
draw(scaleValue);
}, false);
// create an array of any "hit" colored-images
function imagesHitTests(x,y){
// adjust for panning
x-=panX;
y-=panY;
// create var to hold any hits
var hits=[];
// hit-test each image
// add hits to hits[]
loadImages(sources, function(images){
for(var i = 0, pos; pos = dataJSON[i]; i++) {
if(x >= parseInt(pos.x * scaleValue) && x <= parseInt((pos.x * scaleValue) + 20) && y >= parseInt(pos.y * scaleValue) && y <= parseInt((pos.y * scaleValue) + 20)){
hits.push(i);
}
}
});
return(hits);
}
function imagesHitTests2(x,y){
// adjust for panning
//x-=panX;
//x = parseInt(x) - parseInt(panX);
// y-=panY;
x-=panX;
y-=panY;
// create var to hold any hits
var hits2=[];
// hit-test each image
// add hits to hits[]
loadImages(sources, function(images){
for(var i = 0, pos; pos = dataJSON2[i]; i++) {
//if(x > pos.x && x < parseInt(parseInt(pos.x) + parseInt(20)) && y > pos.y && y < parseInt(parseInt(pos.y) + parseInt(20))){
if(x >= parseInt(pos.x * scaleValue) && x <= parseInt((pos.x * scaleValue) + 20) && y >= parseInt(pos.y * scaleValue) && y <= parseInt((pos.y * scaleValue) + 20)){
hits2.push(i);
}
}
});
return(hits2);
}
function handleMouseDown(e){
// get mouse coordinates
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
// set the starting drag position
lastX=mouseX;
lastY=mouseY;
// test if we're over any of the images
dragging=imagesHitTests(mouseX,mouseY);
dragging2=imagesHitTests2(mouseX,mouseY);
// set the dragging flag
isDown=true;
}
function handleMouseUp(e){
// clear the dragging flag
isDown=false;
}
function handleMouseMove(e){
// if we're not dragging, exit
if(!isDown){
return;
}
//get mouse coordinates
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
// calc how much the mouse has moved since we were last here
var dx=mouseX-lastX;
var dy=mouseY-lastY;
// set the lastXY for next time we're here
lastX=mouseX;
lastY=mouseY;
// handle drags/pans
if(dragging.length>0){
// we're dragging images
// move all affected images by how much the mouse has moved
for(var i = 0, pos; pos = dataJSON[dragging[i]]; i++) {
pos.x = parseInt(pos.x) + parseInt(dx);
pos.y = parseInt(pos.y) + parseInt(dy);
}
}
else if(dragging2.length>0){
for(var i = 0, pos1; pos1 = dataJSON2[dragging2[i]]; i++) {
pos1.x = parseInt(pos1.x) + parseInt(dx);
pos1.y = parseInt(pos1.y) + parseInt(dy);
}
}
else{
// we're panning the tiger
// set the panXY by how much the mouse has moved
panX+=dx;
panY+=dy;
}
draw(scaleValue);
}
// use jQuery to handle mouse events
$("#myCanvas").mousedown(function(e){handleMouseDown(e);});
$("#myCanvas").mousemove(function(e){handleMouseMove(e);});
$("#myCanvas").mouseup(function(e){handleMouseUp(e);});
// }); // end $(function(){});
}
markers.js:
data = [
{ "id" :["first"],
"x": ["195"],
"y": ["150"],
"tooltiptxt": ["Region 1"]
},
{
"id" :["second"],
"x": ["255"],
"y": ["180"],
"tooltiptxt": ["Region 2"]
},
{
"id" :["third"],
"x": ["200"],
"y": ["240"],
"tooltiptxt": ["Region 3"]
}
];
data2 = [
{ "id" :["first2"],
"x": ["225"],
"y": ["150"],
"tooltiptxt": ["Region 21"]
},
{
"id" :["second2"],
"x": ["275"],
"y": ["180"],
"tooltiptxt": ["Region 22"]
},
{
"id" :["third3"],
"x": ["300"],
"y": ["240"],
"tooltiptxt": ["Region 23"]
}
];
I think you can try out this :
<!DOCTYPE html>
<html>
<head>
<title>Canvas Links Example</title>
<script>
function OnLoad(){
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
ctx.translate(0.5, 0.5);
ctx.strokeStyle = "#5F7FA2";
ctx.strokeRect(50, 50, 25, 25);
var img = new Image();
img.src = "http://www.cs.washington.edu/education/courses/csep576/05wi/projects/project4/web/artifact/liebling/average_face.gif";
var img1 = new Image();
img1.src = "E:\Very IMP Projects\WinService\SourceCode\MVC\BpmPresentation\Images\loading.gif";
img.onload = function(){
ctx.drawImage(img, 50, 50);
canvas.addEventListener("mousemove", on_mousemove, false);
canvas.addEventListener("click", on_click, false);
Links.push(50 + ";" + 50 + ";" + 25 + ";" + 25 + ";" + "http://plus.google.com/");
}
var Links = new Array();
var hoverLink = "";
var canvas1 = document.getElementById("myCanvas1");
var ctx1 = canvas1.getContext("2d");
function on_mousemove (ev) {
var x, y;
if (ev.layerX || ev.layerX == 0) { // For Firefox
x = ev.layerX;
y = ev.layerY;
}
for (var i = Links.length - 1; i >= 0; i--) {
var params = new Array();
params = Links[i].split(";");
var linkX = parseInt(params[0]),
linkY = parseInt(params[1]),
linkWidth = parseInt(params[2]),
linkHeight = parseInt(params[3]),
linkHref = params[4];
if (x >= linkX && x <= (linkX + linkWidth) && y >= linkY && y <= (linkY + linkHeight)){
document.body.style.cursor = "pointer";
hoverLink = linkHref;
ctx1.translate(0.5, 0.5);
ctx1.strokeStyle = "#5F7FA2";
canvas1.style.left = x + "px";
canvas1.style.top = (y+40) + "px";
ctx1.clearRect(0, 0, canvas1.width, canvas1.height);
var img1 = new Image();
img1.src = "E:\Very IMP Projects\WinService\SourceCode\MVC\BpmPresentation\Images\loading.gif";
img1.onload = function () {
ctx1.drawImage(img1, 50, 50);
}
break;
}
else {
document.body.style.cursor = "";
hoverLink = "";
canvas1.style.left = "-200px";
}
};
}
function on_click(e) {
if (hoverLink) {
window.open(hoverLink);
//window.location = hoverLink;
}
}
}
</script>
</head>
<body onload="OnLoad();">
<canvas id="myCanvas" width="450" height="250" style="border:1px solid #eee;">
Canvas is not supported in your browser ! :(
</canvas>
<canvas id="myCanvas1" width="50" height="50" style="background-color:white;border:1px solid blue;position:absolute;left:-200px;top:100px;">
</canvas>
</body>
</html>

Categories