I have a question...
I'm trying to figure out how to touch draw shapes on an HTML5 canvas. I've been searching everywhere and so far it's been impossible to find any descent tutorial on matter. Can somebody please help me out? I know how to "draw" shapes on the canvas (with code), but how do you draw/paint with (touch) your finger for mobile apps?
Here's my code so far...
Javascript:
// draws a Square to the x and y coordinates of the mouse event inside
// the specified element using the specified context
function drawSquare(mouseEvent, sigCanvas, context) {
var position = getPosition(mouseEvent, sigCanvas);
context.strokeStyle = "color";
context.strokeRect(x,y,width,height);
}
// draws a square from the last coordiantes in the path to the finishing
// coordinates and unbind any event handlers which need to be preceded
// by the mouse down event
function finishDrawing(mouseEvent, sigCanvas, context) {
// draw the line to the finishing coordinates
drawSquare(mouseEvent, sigCanvas, context);
context.closePath();
// unbind any events which could draw
$(sigCanvas).unbind("mousemove")
.unbind("mouseup")
.unbind("mouseout");
}
HTML5:
<div id="squareButton">
<p><button onclick="drawSquare();">Square</button></p>
</div>
Thanks a lot,
Wardenclyffe
Not really a tutorial, but MDN has a solution here https://developer.mozilla.org/en/DOM/Touch_events#Drawing_as_the_touches_move
additionally you might want to look into the touch events ( also available on the same link above )
here is an excerpt from the link I provided
function startup() {
var el = document.getElementsByTagName("canvas")[0];
el.addEventListener("touchstart", handleStart, false);
el.addEventListener("touchend", handleEnd, false);
el.addEventListener("touchcancel", handleCancel, false);
el.addEventListener("touchleave", handleEnd, false);
el.addEventListener("touchmove", handleMove, false);
}
Related
I'm using drawing manager to draw polygon.
I want to display live moving data on polygon vertex.
I have tried used two methods below.
google.maps.event.addListener(polygon.getPath(), 'set_at', processVertex);
google.maps.event.addListener(polygon.getPath(), 'insert_at',processVertex);
But its call after vertex end moving/ drag end.
i want something while moving ...
I have this fiddle and data i'm displaying.
http://jsfiddle.net/subhashchavda/6a8db64z/65/
I want something like this
listener(polygon.getPath(), 'vertex_drag',function(){
update_data(); /* dragging/moving */
});
Is there any way /trick for listen vertex dragging ?
There is no in build function available in google map doc. so right now if want to it to workout you can use custom code like listening vertax click and drag on map.
Here is some code you can try with that.
google.maps.event.addListener(polygon, 'mousedown', function(e){
if(e.vertex){
// flag for vertax drag start
}
});
google.maps.event.addListener(map, 'mousemove', function(e){
if(e.vertex){
// flag for vertax dragging
}
});
google.maps.event.addListener(polygon, 'mouseup', function(e){
if(e.vertex){
// flag for vertax drag stop
}
});
But i'm not sure it will work with every conditions.
you need to more workout with this code.
I have an application where I need an information card to follow the position of the mouse.
I have used the following code:
stage.addEventListener("tick", fl_CustomMouseCursor.bind(this));
function fl_CustomMouseCursor() {
this.NameTag.x = stage.mouseX;
this.NameTag.y = stage.mouseY;
}
It works perfectly in Firefox but in Chrome and Safari the further away the mouse gets from 0,0 on the canvas the larger the distance between NameTag and the mouse (by a factor of 2).
I look forward to any comments.
I see the issue in Chrome as well as Firefox - I don't believe it is a browser issue.
The problem is that the stage itself is being scaled. This means that the coordinates are multiplied by that value. You can get around it by using globalToLocal on the stage coordinates, which brings them into the coordinate space of the exportRoot (this in your function). I answered a similar question here, which was caused by Animate's responsive layout support.
Here is a modified function:
function fl_CustomMouseCursor() {
var p = this.globalToLocal(stage.mouseX, stage.mouseY);
this.NameTag.x = p.x;
this.NameTag.y = p.y;
}
You can also clean up the code using the "stagemousemove" event (which is fired only on mouse move events on the stage), and the on() method, which can do function binding for you (among other things):
stage.on("stagemousemove", function(event) {
var p = this.globalToLocal(stage.mouseX, stage.mouseY);
this.NameTag.x = p.x;
this.NameTag.y = p.y;
}, this);
Cheers,
I'm new to the canvas tag and am playing around with some animation. Basically, I'm trying to setup a "ground" section composed of multiple images (similar to an 8bit side scroller game like Mario Brothers). The ground will be composed of multiple images, which I've built a constructor function to load these and tile them across the bottom.
function Ground(context,ImageName,ImgX,ImgY,ImgW,ImgH){
this.width=ImgW;
this.height=ImgH;
this.x=ImgX;
this.y=ImgY;
img=new Image();
img.onload=function(){context.drawImage(img,ImgX,ImgY,ImgW,ImgH);};
img.src='images/'+ImageName;};
This seems to work out just fine. I've then setup the rest of the animation, including a basic setup for Key Left/Right events, like so:
window.onload=function(){
var canvas=document.getElementById('canvas'),
context=canvas.getContext('2d'),
Grounds=[],
ImgX=-150; // INITIAL STARTING X FOR FIRST GROUND TILE
// INSERT GROUND ELEMENTS
for(var i=0,l=8; i<l; i++){
var ImgX+=150;
Grounds[i]=new Ground(context,"ground.png",ImgX,650,150,150);
};
// ASSIGN LEFT/RIGHT KEYS
window.addEventListener('keyup',function(event){
switch(event.keyCode){
case 37:
for(var i=0,l=Grounds.length; i<l; i++){
Grounds[i].x+=10;
};
break;
case 39:break;
};
});
// ANIMATION LOOP
(function drawFrame(){
window.mozRequestAnimationFrame(drawFrame,canvas);
context.clearRect(0, 0, canvas.width, canvas.height);
}());
};
I know exactly what my problem is, but don't know how to solve it. The animation loop is clearing the canvas every frame, but not redrawing the updated position (if any) when the user presses the left arrow key.
I'm missing the redraw part here and I'm not exactly sure how to handle this or if I'm approaching this entirely wrong. Any help is very appreciated! Thanks!
First of all you're incrementing the property x of the ground tiles but that property is not even used anywhere in your code. Modify your code so that the onload event of those image objects draws the image according to their own x property so changes to it will actually affect what is drawn. Also add the image object as a property of the Ground object so you can access it later on from outside.
Your approach is really not so good but if you want to do it without going back to 0 do it as follows:
function Ground(context,ImageName,ImgX,ImgY,ImgW,ImgH){
this.width=ImgW;
this.height=ImgH;
this.x=ImgX;
this.y=ImgY;
var self = this; // Add local reference to this Ground instance
this.img=new Image(); // img is now a property too
this.img.onload=function(){context.drawImage(this, self.x, self.y,self.width,self.height);};
this.img.src='images/'+ImageName;};
Ok so now you can change the property x of the ground tiles and call the draw function of it again (which is the onload event).
Grounds[i].x+=10;
Grounds[i].img.dispatchEvent(new Event("load"));
Please note that you should really make the updates of all the values first and then all the draw calls separately.
Can you not just add a draw method? You usually so something like this:
init -> update -> clear, redraw -> update -> clear, redraw -> ...
// ANIMATION LOOP
(function drawFrame(){
window.mozRequestAnimationFrame(drawFrame,canvas);
context.clearRect(0, 0, canvas.width, canvas.height);
contect.drawImage(...);
}());
I have to make a map of Europe with its countries
and then I need a few pics of products from those countries
After that I have to match the pic with the country with drag and drop
if the product is dropped on the correct country it should send me to another page (with more info about the product)
if it's wrong it should display a message
anyone have an idea? I checked for some basic drag and drop stuff but since I'm new to html5 etc and webdesign in general it's really hard to make this from scratch
thanks!
EDIT: also only use HTML, CSS, JS
This can be achieved with the MapQuest JavaScript API. What I would start with is by adding polygon overlays to the map for each country, the colour can be sett to completely transparent by setting the opacity for the overlay to 0.0. From each overlay add a mouseup event listener to each overlay, this event listener can then be used to determine what it was you were dragging in the first place.
For the drag start functionality you can either do this yourself or you could use something like the jQuery UI draggable support, you could then use the dragstop event from the draggable API in conjunction with mouseup on the overlay to perform your logic.
Check out the basic map to get a map going.
Some code to start with
var countryCode;
// Adds an overlay and wires an event for mouseup.
function addMapOverlay(points, cc) {
var poly = new MQA.PolygonOverlay();
poly.setShapePoints(points);
poly.color = "#ffffff";
poly.colorAlpha=0.0;
poly.fillColor = "#ffffff";
poly.fillColorAlpha=0.0;
poly.addListener(rectangle, 'mouseup', function(evt) {
if (evt.eventName === "mouseup") {
// Here you have the event firing for the mouse-up on the overlay.
countryCode = cc;
}
});
}
For the drag-start.
$("#some-country-item").draggable({
start: function(event, ui) {
countryCode = null;
},
stop: function(event, ui) {
if (countryCode === "what you expected") {
// Released on correct country.
} else {
// Did not release on correct country.
}
}
});
You may need to test the event handling to ensure that the correct events are fired in the right order, or use the mouseover event on the overlay object.
The code samples are theoretical and should help you find the right direction to go.
I have a slight problem here I try to solve. As I start to do animation with HTML5 and Canvas I want to have a constant animation flow and also be able to capture mouse movement without interrupting the animation flow. This right now seems like a problem. Ill bring
some code from my test code here.
function mainInit()
{
canvas = document.getElementById('canvas');
context = canvas.getContext('2d');
ballArray.push(new Ball(30,30,2,4,15,"#EEEEEE"));
setInterval(drawScene,20);
}
function drawScene()
{
// main drawScene function
clear(); // clear canvas
// draw animated objects
for(var i = 0; i < ballArray.length; i++)
{
ballArray[i].draw();
}
Event_MouseMove();
}
var messageMousePos = '';
function Event_MouseMove()
{
canvas.addEventListener('mousemove', function(evt)
{
var mousePos = getMousePos(canvas, evt);
messageMousePos = "Mouse position: " + mousePos.x + "," + mousePos.y;
context.font = '10pt Calibri';
context.fillStyle = 'black';
context.fillText(messageMousePos , 5, 15);
}, false);
}
The problem is that when I move the eventListner for mouse movement overrides the draw interval and makes it go much slower. How/where should I put the code for the mouse event so it do not interrupt this draw interval, but still draw the mouse events according to the interval?
At a glance, it looks like the code will try to add an event listener every frame...While JS will dump duplicate handlers, it will slow your code down. It's unclear whether you are trying to only capture mouse movement every interval, or constantly, because your code is kinda trying to do both. Here's the best of both worlds solution:
Call addEventListener once outside the loop, and have the function it calls save the mouse position in messageMousePos. Then, within the drawScene function, put your font/fillstyle/filltext code if you really do only want the text outputting every 20ms. This might look choppy compared to how smoothly the text would change if you were constantly rendering the mouse position text.
Here is an example of constantly capturing and displaying the mouse position, as you might actually want to do.