Mouse movement, while mouse down not working in Dart? - html

How do you get mouse movements but only when you're have clicked.
I know this is how you track whether or not the mouse is clicked:
canvas.onMouseDown
and this is how you track mouse movement canvas.onMouseMove
so I tried doing this:
//when the mouse is clicked
canvas.onMouseDown.listen((onData){
print("Mouse is down!" + "(" + onData.client.x.toString() + ", " + onData.client.y.toString() + ")");
//check where it's being dragged
canvas.onMouseMove.listen((onData){
mouseMovementsDown(onData.client.x, onData.client.y);
});
});
But the problem is it doesn't stop once I stop clicking. I want to track the movement so long as the mouse is down and once the mouse is no longer down, I want to stop tracking the mouse's movement. Can anyone help me? For some reason this thing continues reporting canvas.onMouseMove even after I've put the mouse up.
I also tried this:
if(canvas.onMouseDown.listen(onData) == true)
But apparently that's not how things work in dart >.>;
I read more about streams on the dart api docs, can someone explain to me how close is used? I think it said that's how you stop getting input from a mouse event, but how is that done I don't really understand how the code would be written to stop the canvas.onMouseMove.listen stream when canvas.onMouseUp happens.

You can store a reference to the mouseMove StreamSubscription and cancel it on mouseUp:
canvas.onMouseDown.listen((onData) {
StreamSubscription mouseMoveStream = canvas.onMouseMove.listen((onData) {
// Do things...
});
canvas.onMouseUp.listen((onData) => mouseMoveStream.cancel());
});

Related

as3 stopping sound removes eventListener?

I am having an issue with stopping a sound and then starting it back up. After I stop the sound and start it again the eventListener seems to be gone.
Now the "easy" fix seems to be just "add" another one when you start the sound again.
This can not be done easily because the sound channel "Praying" has dynamic listener
added to it with a different function called at the end of each. So I would have to know what listener was added to it and what function should be called when done.
Again, I simply want to "pause" the currently prayed prayer with mouse click and start it up in the same spot with another click. But the issue is that it is removing the eventListener with the instructions for what to do after the sound is done playing.
Any thoughts on a work around? Or maybe this is an easy fix?
/// EXAMPLE 1
Praying = OFE.play();
Praying.addEventListener(Event.SOUND_COMPLETE, prayDecade );
/// EXAMPLE 2
Praying = JES.play();
Praying.addEventListener(Event.SOUND_COMPLETE, doSomethingElse);
public function togglePraying(e:Event = null)
{
if(nowPraying)
{
Praying.stop();
nowPraying = ! Praying;
trace("Praying: " + currentSound);
}
else
{
Praying = currentSound.play();
nowPraying = ! Praying;
trace("Praying: " + Praying);
}
}
This is normal, when you call OFE.play(), you get a SoundChannel reference and if you call it another time, you get a NEW REFERENCE. You need to register the event again, but don't forget to remove the listener.
if(nowPraying)
{
Praying.removeEventListener(Event.SOUND_COMPLETE, doSomethingElse);
Praying.stop();
nowPraying = ! Praying;
trace("Praying: " + currentSound);
}

Making simple paint in html 5 canvas

I have simple code to "draw" in canvas element:
function doFirst(){
var x = document.getElementById('canvas');
canvas = x.getContext('2d');
window.addEventListener("mousemove", rys, false);
}
function rys(e){
var xPos = e.clientX;
var yPos = e.clientY;
canvas.fillStyle="#000";
canvas.beginPath();
canvas.arc(xPos-7,yPos-7,10,0,Math.PI*2,true);
canvas.closePath();
canvas.fill();
}
window.addEventListener("load", doFirst, false);
As you can see, the function is working only when the mouse is over the canvas element. Now i want to make it "draw" when the mouse is clicked (just like in paint). Can someone tell me how to do it (with code)?
Thx for help
You need to keep track of the current mouse button state (pressed or not pressed) independently of the mouse movements.
You can do this by attaching event handlers to the "mousedown" and "mouseup" events, similar to how you attached to the "mousemove" event.
In these event handlers, you could keep track of the current state of the first mouse button by updating a global variable indicating whether or not the button is currently pressed. Then, in your "mousemove" handler, you can check this global variable and determine whether or not to paint when the mouse is moved.
When using the "mouseup" and "mousedown" events, you may want to limit your handling to only when the first mouse button is pressed. You can do this by checking that the event property "button" is 0. Note, that you can check for other buttons and keep track of them, also.
You can see a working example of this here: http://jsfiddle.net/mQtKz/

HTML5 Animation, capture mouse movement without interruption?

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.

AS3 - MouseWheelDown listener

Is there any way to detect if the mouse wheel is held down? I need to pan my scene while the middle button or mouse wheel is pushed down (I thought holding the mouse wheel down was the same as middle mouse button, but it aint working).
Thanks!
Though I never used it there's MIDDLE_CLICK event which works only in AIR apps. Does your app run in browser or on desktop?
Also, just my 2 cents, it's so damn inconvenient to use scrollwheel button in an application. Each time I am forced to do that in some 3D modelling tool I want to smash my monitor. I'd use just shift/alt/ctrl + mouse1/mouse2.
How about trying out this:
this.onEnterFrame = function() {
if (ASnative(800, 2)(1)) {
trace ("You have pressed or depressed the left mouse button");
}
}
this detects the left mouse... if you substitute the argument (1) with (2) you get the right mouse button so...
this.onEnterFrame = function() {
if (ASnative(800, 2)(2)) {
trace("You have pressed or depressed the right mouse button");
}
}
and if you put in a (4) you get the middle mouse or often the wheel button...
this.onEnterFrame = function() {
if (ASnative(800, 2)(4)) {
trace("You have pressed or depressed the middle mouse or wheel button");
}
}
Source: http://www.actionscript.org/forums/showthread.php3?t=68209
PS: I would suggest not using the middle mouse or wheel button because not everyone has a middle mouse button. So if you still want the usability of a middle mouse button, please adjust your functions accordingly so a person without a middle mouse button can still pan the canvas.
EDIT:
Ok, I made a booboo! Didn't catch it had to be for AS 3.0.
The support for the middle/right mouse button click is no longer available in AS 3.0.
Atleast not directly.
One way to do it is using JS to detect the mouse button that's being pressed and then giving that variable as a string into Flash.
How to detect a mouse click in JS:
http://www.quirksmode.org/js/events_properties.html
How to put this variable into Flash: (ExternalInterface)
http://learn.adobe.com/wiki/display/Flex/External+Interface
Or you can do it directly through a hack in AS 3.0: (limited browser & OS support)
http://flashpunk.net/forums/index.php?topic=2549.0
DEMO: http://www.shinyhappypixels.com/punk-forums/clicky-hook/
This is possible with as3, came across this so here it is:
import flash.events.MouseEvent;
function handleMouseWheel(event:MouseEvent):void {
if ((event.delta > 0 && box_mc.y < 270) || (event.delta < 0 && box_mc.y > 0)) {
box_mc.y = box_mc.y + (event.delta * 3);
}
}
stage.addEventListener(MouseEvent.MOUSE_WHEEL, handleMouseWheel);

Fake mouseclick on hover AS3

This morning I stumbled to this question:
When hovering a button, is it possible to click it automatically after X seconds? So the user doesn't need to click it with his mouse?
How can I let Flash believe my mouse really clicked some button on the stage or brought up with as3?
I have a lot of buttons in my movie. So I prefer to use some code which will cover this function for all existing or coming up buttons in my movie.
I would normally use a code like this but is there some workaround to accomplish this in a different way? I do no want to add code to every button.
this.addEventListener(MouseEvent.OVER, onMouseClickEvent);
public function onMouseClickEvent(event:Event)
{
trace(event);
if(event.buttonDown) // if button goes down normally
trace("MOUSE CLICKED NORMALLY");
else
trace("left button was not down");
}
The easiest way i think, is to subclass Button.
Then you should add mouse over/out listeners, add click listener that looks like that
:public function clickListener(event:MouseEvent = null){...}
When the mouse is hovering, raise a flag that the mouse is on the object, start a timer and when the timer callback function is called, you check the if the flag (you turn the flag down, when the mouse is out) is true and just call clickListener()
Listen for MouseEvent.MOUSE_OVER and start a timer, at the end of which the button will send the MouseEvent.CLICK event. In the mouseover handler, use the SystemManager to add a listener for MouseEvent.MOUSE_OUT which cancels the timer. The timer removes the listener using the SystemManager as well. So does clicking the button.
Finally! Solved!
This did the trick:
public function runOnce(event:TimerEvent):void {
btnSignal.dispatch("KEYBOARD", btnCode);
}
Robusto & Radoslav Georgiev: Thank you for pointing the right direction!
(I'm answering this a little late but would like to give input for future people).
One way to 'skin this cat' is to simply let your hover event trigger a timer (i.e. 3 seconds). In an EnterFrame or other function let a number or Boolean change when 3 seconds is reached.
//Pseudo code
if(timer == 3)
{ numberVar = 1;
//or
BooleanVar = True;
}
else
{
numberVar = 0;
//or
BooleanVar = false;
}
//end
Then just as you connected your methods to a mouseEvent, connect those same methods to fire when numberVar == 1 or BooleanVar == True. That's it.
For super simplicity and readability let your MouseClickEvent just be numberVar = 1 or BooleanVar = True.
These become super simple to implement over time and in my experience are 'very' error proof. Easy to fix also in the case of a typo or something else. No super elusive imports either. Hope that helped.
Great question by the way (+ 1)
:D