I'm a beginner in AS3 so please if possible to give a point for a noob as answer. I want to have a specific button that is clicked to create a line, for example I click the button then I need to click twice on the stage
I click it and it is selected
I click first time on the stage to select the starting point of the line
I click second time on the stage to select the finishing point.
I tried to do it but i can`t manage to, if it is possible please help me. This is the code i wrote
dr_line.addEventListener(MouseEvent.CLICK,drawln);
var test:Boolean;
function drawln(e:MouseEvent):void{
test=true;
stage.addEventListener(MouseEvent.CLICK,reportClick);
}
var sx,sy,fx,fy:int;
var j:int;
function reportClick(event:MouseEvent):void
{
j=0;
j++;
if (test==true && j==1) {
sx=event.localX;
sy=event.localY;
}
j++;
test=true;
trace(j);
trace(test);
if (test==true && j==2) {
fx=event.localX;
fy=event.localY;
j=0;
test=false;
var line:Shape = new Shape();
line.graphics.beginFill(0x00FF00);
line.graphics.moveTo(sx,sy);
line.graphics.lineTo(fx,fy);
this.addChild(line);
}
}
How should i make it so this will work .. please help me , Thanks !!!! ,and yes the function reportClick should always be checked .... but i can`t get it going or when i press the dr_line button it should be active so it will be checked ....
You are assigning j=0 in click handler... you should do that in drawLn instead. Also, you require only one j++ in click handler.
But a cleaner approach would be to have two click listener point1ClickListener and point2ClickListener. You should attach to point1ClickListener in drawLn. Then inside point1ClickListener remove listening clicks to point1ClickListener and attach a click listener for point2ClickListener. Again, when point2ClickListener gets called remove listening for clicks to point2ClickListner.
Related
I am following this tutorial to build a store locator page with a Mapbox map.
I don't want to add custom markers because I already have custom map labels (symbols?), which means I don't need the optional last section of the tutorial and stop right after Add Event Listeners.
Once this is completed, the page should react to clicks in the side panel list, as well as on the map (2 event listeners). However, in the demo provided in the tutorial for that particular step, you can tell the code for the second event listener, the one making the map clickable, is not functioning, which makes me believe there is a mistake in the provided code:
// Add an event listener for when a user clicks on the map
map.on('click', function(e) {
// Query all the rendered points in the view
var features = map.queryRenderedFeatures(e.point, { layers: ['locations'] });
if (features.length) {
var clickedPoint = features[0];
// 1. Fly to the point
flyToStore(clickedPoint);
// 2. Close all other popups and display popup for clicked store
createPopUp(clickedPoint);
// 3. Highlight listing in sidebar (and remove highlight for all other listings)
var activeItem = document.getElementsByClassName('active');
if (activeItem[0]) {
activeItem[0].classList.remove('active');
}
// Find the index of the store.features that corresponds to the clickedPoint that fired the event listener
var selectedFeature = clickedPoint.properties.address;
for (var i = 0; i < stores.features.length; i++) {
if (stores.features[i].properties.address === selectedFeature) {
selectedFeatureIndex = i;
}
}
// Select the correct list item using the found index and add the active class
var listing = document.getElementById('listing-' + selectedFeatureIndex);
listing.classList.add('active');
}
});
Would anyone be able to tell what is wrong with this code?
Turns out the code is incomplete in that the cursor doesn't change to a pointer as you hover over a map label/marker so it doesn't clue you into realising you can click on it, hence my assumption it wasn't working at all. I assume the general users who would then face the map would be equally deceived unless the pointer shows up. So in the tutorial, if you do go ahead and click the marker, it will have the expected behaviour and display the popup, although no pointer is shown.
Here is how to create the pointer, based on this fiddle: https://jsfiddle.net/Twalsh88/5j70wm8n/25/
map.on('mouseenter', 'locations', function(e) {
// Change the cursor style as a UI indicator.
map.getCanvas().style.cursor = 'pointer';
});
map.on('mouseleave', 'locations', function() {
map.getCanvas().style.cursor = '';
});
I am trying to let the user click a button and that button determines which "tool" he/she is using. There will be multiple buttons and I need to distinguish the difference between them. For example, the user clicks the first button for one tool, then clicks the second button for the second tool. I thought I had it down, but i'm missing something. Here is what I have
function mMove(MouseEvent): void
{
if (mouseHolding && mouseY > 85 && mouseX < 610)
{
clearTemp();
switch (currentTool)
{
case thisTool:
temporaryDrawing.graphics.lineTo(mouseX, mouseY);
break;
}
thisTool.addEventListener(MouseEvent.CLICK, changeMode);
function changeMode(evt: MouseEvent): void
{
var button: Button = evt.target as Button;
currentTool = evt.currentTarget; // I get an error on this line.
}
Can I have some guidance on what i'm doing wrong, thanks :D
It looks like your mMove is missing a closing brace. Could that be the problem?
I've solved my own question :) I just needed to figure out a way to set which button is active by creating separate functions.
Working a bit with AS3 and hit a wall on how to program through this situation. I have a class which represents a number say 103. I have a movieclip for each digit which I add to a holding movieclip and then add to the stage. I want to enable the ability to single click a digit like the zero in the number 103 and have it react since it is an individual movieclip and at the same time double click the entire number and have that react. Is there a way to cleanly do this wtihout confusing the code below is what I have thus far.
public function test()
{
numberimage = new MovieClip();
var images:Vector.<MovieClip> = generateNumericArray("");
for (var i:int = 0; i < String(value).length; i++) {
var temp:MovieClip = parsevalue(String(value).substr(i,1),images);
temp.x = i*50;
temp.addEventListener(MouseEvent.CLICK,click)
numberimage.addChild(temp);
}
numberimage.addEventListener(MouseEvent.MOUSE_DOWN,drag);
numberimage.addEventListener(MouseEvent.MOUSE_UP,drop);
numberimage.addEventListener(MouseEvent.MOUSE_OVER,doubleClick);
stage.addChild(numberimage);
}
any help on this would be much appreciated
Do, doubleclick on clip : stop listening to main movie, and listen now to sub clips. On click outside the main clip, listen back to the main movie and stop listening to its children.
Not sure if this is 100% what you are looking for: use the following, depending on what you are adding the listener to. You do have to enable double clicking first
numberimage.doubleClickEnabled = true;
numberimage.addEventListener(MouseEvent.DOUBLE_CLICK, click);
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
There is an event which is dispatched when the context menu (right click menu) in actionscript for flash has been opened:
ContextMenuEvent.MENU_SELECT
Now, is there an event which is dispatched when the menu has been closed?
Good question.
That would make a nice feature request, an ContextMenuEvent.MENU_CLOSED event :)
I think I have half you're answer. Here's my idea:
var myContextMenu:ContextMenu = new ContextMenu();
var menuLabel:String = "Custom Item";
var rightClicking:Boolean;
addCustomMenuItems();
myContextMenu.addEventListener(ContextMenuEvent.MENU_SELECT, menuSelectHandler);
stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseUpHandler);
var redRectangle = makeRedRectangle();
redRectangle.contextMenu = myContextMenu;
function makeRedRectangle():Sprite{
redRectangle = new Sprite();
redRectangle.graphics.beginFill(0x990000,.2);
redRectangle.graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
redRectangle.mouseChildren = false;
addChild(redRectangle);
return redRectangle;
}
function addCustomMenuItems():void {
myContextMenu.hideBuiltInItems();
var item:ContextMenuItem = new ContextMenuItem(menuLabel);
myContextMenu.customItems.push(item);
item.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, menuItemSelectHandler);
}
function menuSelectHandler(event:ContextMenuEvent):void {
trace("menuSelectHandler: " + event);
rightClicking = true;
}
function menuItemSelectHandler(event:ContextMenuEvent):void {
trace("menuItemSelectHandler: " + event);
}
function mouseUpHandler(event:MouseEvent):void{
if(rightClicking){
trace('ContextMenu Closed\nThank You! Come Again!');
rightClicking = false;
}
}
Basically I create a sprite that sits on top of everything, but has mouseChildren set to false, so clips bellow it can get the clicks. You might want to have this one transparent. I used this so you get an event fired when you right click over it. When that happens I set rightClicking to true, meaning, I know the right click was pressed, I'm just waiting for something else to happen. There are two options:
The user selects an item from the menu.
The user click away to make the menu go away.
For option 1, if the user selects any of your custom items, that's cool, you can handle that, if not, at least you know what might happen.
For option 2 I've setup the listener for the MOUSE_DOWN event, so if the rightClicking was turned on and you got to the mouse down, that's your menu closing.
Hope this helps!
I know, it looks like hacky old school as2, and the code is modified from the documentation example, but it's a thought :)