Adding events to Raphael elements - javascript
Hey, I'm trying to add a mousemove and click event to an SVG Raphael Rectangle:
Fiddle: http://jsfiddle.net/neuroflux/nXKbW/1/
Code:
tile = ctx.rect(x*10,y*(i*10),10,10).attr({
fill:'#000000',
stroke: '#ffffff'
});
tile.mouseover(function(e) {
pX = e.pageX;
pY = e.pageY;
});
tile.click(function() {
console.log('x: '+pX+'| y:'+pY);
});
Obviously, for some reason this doesn't function - I get no output onClick :'(
Ok I've got the click function to work. Finally ^_^.
<!DOCTYPE html>
<html>
<head>
<title></title>
<script type="text/javascript" src="https://github.com/DmitryBaranovskiy/raphael/raw/master/raphael-min.js"></script>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.6.1.min.js"></script>
<script type="text/javascript">
/* GLOBAL VARIABLES */
var drawFrames;
var canvas;
var ctx;
var universe = new Array();
var tile;
var pX,pY = 0;
universe = (
[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],
[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],
[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],
[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],
[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],
[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],
[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],
[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],
[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],
[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]]
);
/* WINDOW LOAD */
window.onload = function() {
init();
}
/* INITIALISATION */
function init() {
ctx = Raphael(10, 50, 320, 200);
drawFrames = setInterval(drawFrame, 40);
}
/* FRAME RENDER LOOP */
function drawFrame() {
//ctx.clear();
for (var x = 0; x < universe.length; x++) {
for (var y = 0; y < universe[x].length; y++) {
for (var i= 0; i < 11; i++) {
tile = ctx.rect(x*10,y*(i*10),10,10).attr({
fill:'#000000',
stroke: '#ffffff'
}).click(function(e) {
console.log('x: '+e.pageX+'| y:'+e.pageY);
})
}
}
}
}
</script>
</head>
<body>
<canvas id="main" width="800" height="600">
<h1>No Support I'm Afraid...</h1>
</canvas>
</body>
</html>
first give your raphael object an id then bind the click event to it.
tile = ctx.rect(x*10,y*(i*10),10,10).attr({
fill:'#000000',
stroke: '#ffffff'
});
tile.node.id='tile_id';
$('#tile_id').bind('click',function(){alert('clicked');});
Related
change css position to fixed on a created canvas with js
So the idea is - I want to get the canvas position style to be fixed through js, so I don't get the scroll bars. The thing is - I can change the style easily with chrome inspector and all works fine, but js refuses to corporate... function setup() { //full screen setup canvas = createCanvas(window.innerWidth*2,window.innerHeight*2); canStyle = canvas.style; canvas.style.position = "fixed"; mainWrap = document.getElementById('mainWrap'); canvas.parent(mainWrap); This is what I get instead : The html, body and main wrap are 100% , just the way I want it, but the canvas itself is stretched, but not fixed... I really don't know what I'm doing wrong... Ideas? The manual chrome inspector edit does the job... Whole Code HTML: <html> <head> <meta charset="utf-8"> <title>Sky</title> <link href="style.css" rel="stylesheet" type="text/css"/> <script language="javascript" type="text/javascript" src="libs/p5.js"></script> <script language="javascript" src="libs/p5.dom.js"></script> <script language="javascript" type="text/javascript" src="sketch.js"></script> <script language="javascript" type="text/javascript" src="star.js"></script> <style> body {padding: 0; margin: 0;} </style> </head> <body> <div id="mainWrap"> </div> </body> </html> css: html, body, #mainWrap { height:100%; width:100%; margin:0px; } body{ background-color: #222222; } JS: var mainWrap; var sky = []; var x; var y; var trans = false; function setup() { //full screen setup canvas = createCanvas(window.innerWidth*2,window.innerHeight*2); canStyle = canvas.style; canvas.style.position = "fixed"; mainWrap = document.getElementById('mainWrap'); canvas.parent(mainWrap); for(var i = 0; i < 1; i++){ var star = new Star(i, random(width),random(height), Math.floor(random(1,4))); sky[i] = star; console.log(sky[i]); } } function draw() { background(34,34,34); x = mouseX; y = mouseY; if(trans === false){ translate(x-(width/2),y-(height/2)); } for (var i=0; i < sky.length; i++){ sky[i].show(); sky[0].fall(0.4,0.3); } } Star obj: function Star(id,xCord, yCord, parallax) { this.parrlax = parallax; this.id = id; this.x = xCord; this.y = yCord; this.r = parallax; noStroke(); this.show = function(){ fill(255,255,255, random(30*this.parrlax,this.parrlax*40)); ellipse(this.x, this.y, this.r*2, this.r*2); } this.fall = function(xMove, yMove) { this.x += xMove; this.y += yMove; fill(100,100,100); ellipse(this.x,this.y,3,3); } }
Assuming createCanvas is a method form P5.js, you need to access the underlying DOM element of the created canvas: canvas = createCanvas(window.innerWidth*2,window.innerHeight*2); // canvas here refers to an instance of P5 canvas, not a HTML5 canvas element, // but the real DOM canvas is available as either .canvas or .elt canvas.elt.style.position = "fixed";
Why isnt the .clearRect function working properly?
So im making this space invaders game in javascript. My problem right now is that when the enemies move left and right they dont clear rect so you can see thier footage as shown here: I just wanted to know what i could fix to solve this problem. I would love if you could help here is my code: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Space Invaders</title> <script src="http://code.jquery.com/jquery-latest.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script> <style> canvas{ position: absolute; top:0px; left:0px; background: transparent; } #backgroundCanvas{ background-color: black; } </style> </head> <body> <canvas id="backgroundCanvas" width="550" height="600"></canvas> <canvas id="playerCanvas" width="550" height="600"></canvas> <canvas id="enemiesCanvas" width="550" height="600"></canvas> <script> (function(){ $(document).ready(function(){ var game = {}; game.stars = []; game.width = 550; game.height = 600; game.images = []; game.doneImages = 0; game.requiredImages = 0; game.keys = []; game.enemies = []; game.count = 0; game.division = 48; game.left = false; game.enemySpeed = 3; game.contextBackground = document.getElementById("backgroundCanvas").getContext('2d'); game.contextPlayer = document.getElementById("playerCanvas").getContext('2d'); game.contextEnemies = document.getElementById("enemiesCanvas").getContext('2d'); game.player = { x: game.width / 2 -50, y: game.height - 110, width:100, height:100, speed: 3, rendered: false } $(document).keydown(function(e){ game.keys[e.keyCode ? e.keyCode : e.which] = true; }) $(document).keyup(function(e){ delete game.keys[e.keyCode ? e.keyCode : e.which]; }) /* up -38 down-40 left -37 right-39 w-87 a-65 s-83 d-68 space-32 */ function init(){ for(i=0; i<600;i++){ game.stars.push({ x:Math.floor(Math.random()* game.width), y:Math.floor(Math.random()* game.height), size: Math.random()*5 }) } for(y=0;y<5;y++){ for(x =0;x<5;x++){ game.enemies.push({ x: (x*70) + (70*x) + 10, y: (y*70) + (10*y) + 40, width:70, height: 70, image:1 }) } } loop(); } function addStars(num){ for(i=0; i<num;i++){ game.stars.push({ x:Math.floor(Math.random()* game.width), y:game.height+10, size: Math.random()*5 }) } } function update(){ addStars(1); game.count++; for(i in game.stars){ if(game.stars[i].y <= -5){ game.stars.splice(i,1); } game.stars[i].y--; } if(game.keys[37] || game.keys[65]){ if(game.player.x>=0){ game.player.x-=game.player.speed; game.player.rendered = false; } } if(game.keys[39] || game.keys[68]){ if(game.player.x<=500-50){ game.player.x+=game.player.speed; game.player.rendered = false; } } if(game.count % game.division == 0){ game.left = !game.left; } for(i in game.enemies){ if(game.left){ game.enemies[i].x-=game.enemySpeed; }else{ game.enemies[i].x+=game.enemySpeed; } } } function render(){ game.contextBackground.clearRect(0,0,game.width,game.height) game.contextBackground.fillStyle = "white"; for(i in game.stars){ var star = game.stars[i]; game.contextBackground.fillRect(star.x,star.y,star.size,star.size); } if(!game.player.rendered){ game.contextPlayer.clearRect(0, 0, game.width, game.height); game.contextPlayer.drawImage(game.images[0], game.player.x, game.player.y, game.player.width, game.player.height); game.player.rendered = true; } for(i in game.enemies){ var enemy = game.enemies[i]; game.contextEnemies.clearRect(enemy.x, enemy.y, enemy.width, enemy.height); game.contextEnemies.drawImage(game.images[enemy.image], enemy.x, enemy.y, enemy.width, enemy.height); } } function loop(){ requestAnimFrame(function(){ loop(); }); update(); render(); } function initImages(paths){ game.requiredImages = paths.length; for(i in paths){ var img = new Image; img.src = paths[i]; game.images[i] = img; game.images[i].onload = function(){ game.doneImages++; } } } function checkImages(){ if(game.doneImages>=game.requiredImages){ init(); } else{ setTimeout(function(){ checkImages(); },1) } } game.contextBackground.font = "bold 50px monaco" game.contextBackground.fillStyle = "white"; game.contextBackground.fillText("loading" , game.width/2-100 ,game.height/2-25) initImages(["player.gif", "enemy.png", "bullet.png","Image1.png","Image2.png"]) checkImages(); }); window.requestAnimFrame = (function(){ return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function( callback ){ window.setTimeout(callback, 1000 / 60); }; })(); })(); </script> </body> </html>
Right now, you clear contextEnemies with this game.contextEnemies.clearRect(enemy.x, enemy.y, enemy.width, enemy.height); The problem here is that you are clearing the square where you are about to draw the enemy, not the square where it was drawn last time. You need to keep track of where you drew the enemy at previous render (enemy.x), and clear that part. Either you add something like enemy.lastx to the enemy object, to keep track of it's previous position. Or the easiest solution would be to just clear the entire contextEnemies as you are doing with contextBackground. game.contextBackground.clearRect(0, 0, game.width, game.height); game.contextEnemies.clearRect(0, 0, game.width, game.height); Hope that helps. Cheers!
problems with canvas
Here's my html document: <html> <head> <meta charset="utf-8"> <title>Automapper Editor</title> </head> <body> <nobr> <script> var img = new Image() img.src = "grass_main_0.7.png" for(var y=0; y < 16; y++) { for(var x=0; x < 16; x++) { var tilecanvas = document.createElement("canvas") var tilectx = tilecanvas.getContext("2d") tilecanvas.width = 64 tilecanvas.height = 64 tilecanvas.draggable = true tilectx.drawImage(img, x*64, y*64, 64, 64, 0, 0, 64, 64) document.body.appendChild(tilecanvas) } document.body.appendChild(document.createElement("br")) } </script> </nobr> </body> </html> I want to split an image with the size of 1024 pixel in 16 images with the size of 64 pixel. Then i want to draw them on canvas and write them to the document. This are my problems: The line tilecanvas.draggable = true doesn't work, this should do the same as <canvas draggable="true">. The <nobr> tag doesn't prevent the canvas from wrapping, but i want them to stay 16x16 on the screen. The first time you load the page you can't see the image, you can simulate this by pressing STRG+F5 (a.k.a. Ctrl-F5) in firefox.
You can solve it by: Using a container div for the tiles Set fixed width for container element Adjust the CSS for canvas element to float Live example (note: added random alpha for the tiles/demo to increase visibility) var img = new Image(); img.onload = render; img.src = "http://www.psdgraphics.com/file/colorful-triangles-background.jpg"; function render() { var cont = document.getElementById("cont"); for (var y = 0; y < 16; y++) { for (var x = 0; x < 16; x++) { var tilecanvas = document.createElement("canvas"); var tilectx = tilecanvas.getContext("2d"); tilecanvas.width = 64; tilecanvas.height = 64; tilecanvas.draggable = true; tilectx.globalAlpha = Math.random() + 0.5; // just to increase visuals tilectx.drawImage(img, x * 64, y * 64, 64, 64, 0, 0, 64, 64); cont.appendChild(tilecanvas); } } } #cont {width: 1024px;border: 1px solid #000} canvas {float:left} <div id="cont"></div>
As said by RienNeVaPlu͢s & Ken Fyrstenberg, make sure you give your image time to load with onload. Here's a proof-of-concept allowing html drag-drop of a spliced image-canvases: https://jsfiddle.net/m1erickson/g9nfuved/ <!doctype html> <html> <head> <link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css --> <script src="https://code.jquery.com/jquery-2.1.1.min.js"></script> <style> body{ background-color: ivory; padding:10px; } canvas{border:1px solid red; margin-left:0px;} #dropzone{width:250px;height:50px;border:1px solid blue;} </style> <script> $(function(){ var $results=$('#results'); var img=new Image(); img.onload=start; img.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/facesSmall.png"; function start(){ var w=img.width/4; var h=img.height; for(var x=0; x < 4; x++) { var tilecanvas = document.createElement("canvas"); var tilectx = tilecanvas.getContext("2d"); tilecanvas.width = w; tilecanvas.height = h; tilecanvas.draggable = true tilecanvas.id='canvas'+x; tilectx.drawImage(img, x*w,0,w,h, 0, 0, w, h) document.body.appendChild(tilecanvas) tilecanvas.addEventListener('dragstart', function(e){ e.dataTransfer.setData('text',e.target.id); }, false); tilecanvas.addEventListener('dragenter', handleEvents, false); tilecanvas.addEventListener('dragover', handleEvents, false); tilecanvas.addEventListener('dragleave', handleEvents, false); tilecanvas.addEventListener('dragend', handleEvents, false); } document.body.appendChild(document.createElement("br")) var dropzone=document.getElementById('dropzone'); dropzone.addEventListener('dragover',function(e){e.preventDefault(); return(false);}); dropzone.addEventListener('dragenter',function(e){return(false);}); dropzone.addEventListener('drop',function(e){ $results.text('You dropped: '+e.dataTransfer.getData('text')); return(false); }); } function handleEvents(e){ return(false); } }); // end $(function(){}); </script> </head> <body> <h4 id='results'>Drag 1+ of the image strips</h4> <div id='dropzone' droppable='true'>Drop Here.</div> </body> </html>
javascript working with mouse events
How can I get the image to be dragged around just if the mouse is clicked, not just follow the mouse around as it is doing right now. <head> <style> #flying { position: absolute; } </style> <script type="text/javascript"> function UpdateFlyingObj (event) { var mouseX = Math.round (event.clientX); var mouseY = Math.round (event.clientY); var flyingObj = document.getElementById ("flying"); flyingObj.style.left = mouseX + "px"; flyingObj.style.top = mouseY + "px"; } this.onmouseup = function() { document.onmousemove = null } </script> </head> <body onmousemove="UpdateFlyingObj (event);" > <h1><center>Homework 13.7<center></h1> <div style="height:1000px;"></div> <img id="flying" src="flying.gif" /> </body>
The key-point that needs to be considered is handling the ondragstart event of the image. Failing to return false from it means that the browser absorbs the event and gives odd behaviour. See comment in the source. Try this on for size. (dont forget to change the image-path) <!DOCTYPE html> <html> <head> <style> #flying { position: absolute; } </style> <script> function byId(e){return document.getElementById(e);} window.addEventListener('load', myInitFunc, false); function myInitFunc() { byId('flying').addEventListener('mousedown', onImgMouseDown, false); } function onImgMouseDown(e) { e = e || event; var mElem = this; var initMx = e.pageX; var initMy = e.pageY; var initElemX = this.offsetLeft; var initElemY = this.offsetTop; var dx = initMx - initElemX; var dy = initMy - initElemY; document.onmousemove = function(e) { e = e || event; mElem.style.left = e.pageX-dx+'px'; mElem.style.top = e.pageY-dy+'px'; } this.onmouseup = function() { document.onmousemove = null; } // try to comment-out the below line // doing so means the browser absorbs the ondragstart event and (in Chrome) drags a reduced-opacity copy of // the image, overlaid with a circle that has a diagonal line through it. - just like the usuall behaviour for // dragging an image on a webpage. this.ondragstart = function() { return false; } } </script> </head> <body> <h1><center>Homework 13.7<center></h1> <img id="flying" src="img/opera.svg"/> </body> </html>
Reduce radius of circle on mousemove kineticjs
I'm trying to create a html5 canvas painting application using kinetic.js where users can select various shapes and draw them on canvas . When a user selects circle and tries to draw it , the radius of circle should depend on the distance the mouse has covered on the canvas , now the problem is when the radius of circle increase it works fine but when I decrease it the circle remain of same size . It would be great if someone can point me to the right direction . Here is the link to fiddle . http://jsfiddle.net/45fEn/ <!DOCTYPE HTML> <html> <head> </head> <body> <div id="container"></div> <script src="kinetic.js"></script> <script src="js/jquery.js"></script> <script defer="defer"> $(document).ready(function() { var stage = new Kinetic.Stage({ container:'container', width:300, height:400 }); var layer = new Kinetic.Layer(); function drawCircle() { var circle = new Kinetic.Circle({ x:initialX, y:initialY , radius:tangant , fill:'green' }); layer.add(circle) ; stage.add(layer); } stage.add(layer); var painting =false , clicking = false ; var initialX , initialY , finalX , finalY , tangant , newTangant ,storeTime; $("canvas").mousedown(function(ev) { initialX = ev.clientX; initialY = ev.clientY; painting = true; clicking = true; }); $("canvas").mousemove(function(ev) { finalX = ev.clientX ; finalY = ev.clientY ; var diffX = initialX - finalX ; var diffY = initialY - finalY ; tangant = Math.sqrt ( Math.pow(diffX,2) + Math.pow(diffY,2) ) ; console.log(tangant); storeTime = setTimeout(function() { newTangant = tangant },200) ; if(newTangant < tangant) { console.log("new tan:"+newTangant); circle.remove(); drawCircle(); } if(clicking == true) { drawCircle(); } }); $("canvas").mouseup(function(ev) { painting = false; clicking = false; }); }); </script> </body> </html>
You’re close! BTW, you can also use stage.getContent to hook into stage mouse events. stage.getContent()).on('mousedown', function (event) { …do mousedown stuff… } Instead of removing and recreating the circle... ...just use circle.setRadius(newRadius) to resize the existing circle. $(stage.getContent()).on('mousemove', function (event) { if(!isDragging){return;} var pos=stage.getMousePosition(); var mouseX=parseInt(pos.x); var mouseY=parseInt(pos.y); var dx=mouseX-initialX; var dy=mouseY-initialY; var r=Math.sqrt(dx*dx+dy*dy); // this will resize the circle that is currently being created/resized draggedCircle.setRadius(r); layer.draw(); }); Here is code and a Fiddle: http://jsfiddle.net/m1erickson/KLcRc/ <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Prototype</title> <script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script> <script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.7.0.min.js"></script> <style> #container{ border:solid 1px #ccc; margin-top: 10px; width:400px; height:400px; } </style> <script> $(function(){ var stage = new Kinetic.Stage({ container: 'container', width: 400, height: 400 }); var layer = new Kinetic.Layer(); stage.add(layer); var draggedCircle,initialX,initialY; var radius=25; var isDragging=false; function newCircle(mouseX,mouseY){ initialX=mouseX; initialY=mouseY; var circle = new Kinetic.Circle({ x:initialX, y:initialY , radius:1, fill:'green' }); layer.add(circle) ; layer.draw(); return(circle); } $(stage.getContent()).on('mousedown', function (event) { var pos=stage.getMousePosition(); var mouseX=parseInt(pos.x); var mouseY=parseInt(pos.y); draggedCircle=newCircle(mouseX,mouseY); isDragging=true; }); $(stage.getContent()).on('mousemove', function (event) { if(!isDragging){return;} var pos=stage.getMousePosition(); var mouseX=parseInt(pos.x); var mouseY=parseInt(pos.y); var dx=mouseX-initialX; var dy=mouseY-initialY; var r=Math.sqrt(dx*dx+dy*dy); draggedCircle.setRadius(r); layer.draw(); }); $(stage.getContent()).on('mouseup', function (event) { isDragging=false; }); }); // end $(function(){}); </script> </head> <body> <p>Drag to create a resizable circle</p> <div id="container"></div> </body> </html>