JS console error- object not defined - html5-canvas
I have the following JS function, which I'm using to detect whether a 'draggable' image on my HTML5 canvas is dragged on top of a static 'description box' image, also displayed on the canvas:
function isHit(mouseX, mouseY){
if(draggingImage == true){
console.log("if dragging image == true statment is being called");
if(mouseY > 420){
if((mouseX > 80) && (mouseX < 200) && (obj.shape.index >= 0) && (obj.shape.index <= numImagesAssets)){
console.log("Correct");
}else{
console.log("Incorrect");
}
}
}
}
The idea is that there will be a number of static images on the canvas (which will be the description boxes), and a greater number of draggable images. The user will be required to drag each of the draggable images to the relevant description box.
At the moment, my if statement is just checking to see whether the image currently being dragged belongs in the first of four description boxes.
Since the description boxes are all displayed in a row towards the bottom of the canvas, I've set my function to only check for a collision when the mouseY variable (y position of the cursor on the canvas) is greater than 420- since 420 is the top 'boundary' of the description box images.
Then, if the draggingImage variable is true, and the cursor's mouseY value is greater than 420, I want to start checking whether the cursor hovers over any of the description boxes. The first one is displayed between the X positions 80 and 200, so I'm checking if mouseX is greater than 80 and less than 200.
If it is, the function should then check whether the value of obj.shape.index is greater than or equal to 0 and less than the value of numImagesAssets. If it is, the console should log "correct", and if not, it should log "incorrect".
The variable obj.shape.index gets the position of the image that has been clicked in my array of images (this array contains all of the draggable images displayed on the canvas). If value of that is between a certain range, then I know that the image belongs to the first description box, if it's between another range, it belongs to the next description box, etc.
In this example, the value of the variable numImagesAssets is 10 (as displayed in the console by a console.log line in my code)
In my mousedown function, I have the line:
console.log("value of variable obj:" + output + ". Shape is " + obj.shape + ". index is " + obj.shape.index);
and when I click on an image on my canvas, this console.log line displays the value of the variable property obj.shape.index, for example, I just clicked on one of the draggable images on the canvas, and this line printed the following output to the console:
value of variable obj:shape: [object Object]; pixel: [object Uint8ClampedArray]; . Shape is [object Object]. index is 8
So I know that the image I clicked that time was at position 8 in my images array (I've checked this manually several times, clicking a different image each time, and it was always displaying the correct position).
Now, the problem I'm having, is that when I actually go and drag an image over its correct description box, I get a console error that says "obj is not defined", and it's complaining about the line:
if((mouseX > 80) && (mouseX < 200) && (obj.shape.index >= 0) && (obj.shape.index <= numImagesAssets)){
But, strangely, if I drag an image to one of the description boxes it doesn't belong to, the else clause in my if statment is triggered correctly, and the word "Incorrect" is printed to the console....
I can't figure out why it's not working when I drag an image to the correct description box, or why it says that "obj" is not defined in that case, but then is happy to use "obj" for the 'else' clause in the if statement.
Anyone have any ideas?
Edit 19/03/2013 # 12:00
Ok, I've edited my isHit function a little, to add another console.log line which will show the value of obj.shape.index within my isHit function. The function now looks like this:
function isHit(mouseX, mouseY, obj){
if(draggingImage == true){
console.log("if dragging image == true statment is being called");
if(mouseY > 420){
console.log("Value of obj.shape.index = " +obj.shape.index);
if((mouseX > 80) && (mouseX < 200) && (obj.shape.index >= 0) && (obj.shape.index <= numImagesAssets)){
console.log("Correct");
}else{
console.log("Incorrect");
}
}
}
}
I have the following console log line just before the call to isHit:
console.log("obj.shape.index = " + obj.shape.index);
This line displays that the value of obj.shape.index is 0 when I first click on the image (which is correct- it is the first image in my array of images), however, as I then drag the image around the canvas, the value of obj.shape.index seem to increase randomly... at one point the console was displaying that it was 23, then that it was 25, and then when I finally drag it to its description box, the console logs the line:
if dragging image == true statment is being called
showing that the isHit function is being called, and the next thing printed to the console is the line:
Value of obj.shape.index = 34
Any idea why the value of obj.shape.index keeps increasing? Is it not actually the position of the element within the array? I'm sure it is though, because when I click on one of the other images, it displays the value of their position within the array, so I don't understand why the value keeps increasing as I move the image around the canvas... it's position within the array isn't being altered at all...
If obj.shape.index is valid before entering isHit(), you probably have a scoping issue.
Try this -- supply obj to isHit:
// call isHit and also supply obj
console.log("obj = "+obj); // Test obj for validity just before calling isHit
var isItHit = isHit(mouseX, mouseY, obj); // Then call isHit WITH obj
// and modify isHit to accept the obj
function isHit(mouseX,mouseY,obj) { ...
Related
Songs not shuffling for button - Processing
I have a shuffle button image that I'm using an an actual button. If the user 'clicks' on this image, the current song playing (if there is one) should stop playing and a random song from my list should play. If there is no song play, you would still play a random song from the list. I'm having trouble with this 'button' because the song isn't shuffling at all, infact nothing happens at all. I've used this same technique with 2 other buttons and had no problems so I think it may be the way I'm calling this method but I'm not sure what I'm doing wrong. I put in a print statement and shuffling... only prints once so I know it works but no songs are shuffling. Does anyone know what I could be doing wrong? //Image for shuffle button imageMode(CORNER); image(shuffle, 140, 15, 50, 50); void shufflePlayList() { current=0; tableau.shuffle(); } //Shuffle button if(mouseX > 140 && mouseX < 190 && mouseY > 15 && mouseY < 65){ println("shuffling..."); shufflePlayList(); }
The conditional only checks whether the mouse is within a certain area not if the button is clicked. so it will run every frame (providing it is within the draw function) if you're hovering over it
Xcode UITest scrolling to the bottom of an UITableView
I am writing an UI test case, in which I need to perform an action, and then on the current page, scroll the only UITableView to the bottom to check if specific text shows up inside the last cell in the UITableView. Right now the only way I can think of is to scroll it using app.tables.cells.element(boundBy: 0).swipeUp(), but if there are too many cells, it doesn't scroll all the way to the bottom. And the number of cells in the UITableView is not always the same, I cannot swipe up more than once because there might be only one cell in the table.
One way you could go about this is by getting the last cell from the tableView. Then, run a while loop that scrolls and checks to see if the cell isHittable between each scroll. Once it's determined that isHittable == true, the element can then be asserted against. https://developer.apple.com/documentation/xctest/xcuielement/1500561-ishittable It would look something like this (Swift answer): In your XCTestCase file, write a query to identify the table. Then, a subsequent query to identify the last cell. let tableView = app.descendants(matching: .table).firstMatch guard let lastCell = tableView.cells.allElementsBoundByIndex.last else { return } Use a while loop to determine whether or not the cell isHittable/is on screen. Note: isHittable relies on the cell's userInteractionEnabled property being set to true //Add in a count, so that the loop can escape if it's scrolled too many times let MAX_SCROLLS = 10 var count = 0 while lastCell.isHittable == false && count < MAX_SCROLLS { apps.swipeUp() count += 1 } Check the cell's text using the label property, and compare it against the expected text. //If there is only one label within the cell let textInLastCell = lastCell.descendants(matching: .staticText).firstMatch XCTAssertTrue(textInLastCell.label == "Expected Text" && textInLastCell.isHittable)
Blaines answer lead me to dig a little bit more into this topic and I found a different solution that worked for me: func testTheTest() { let app = XCUIApplication() app.launch() // Opens a menu in my app which contains the table view app.buttons["openMenu"].tap() // Get a handle for the tableView let listpagetableviewTable = app.tables["myTableView"] // Get a handle for the not yet existing cell by its content text let cell = listpagetableviewTable.staticTexts["This text is from the cell"] // Swipe down until it is visible while !cell.exists { app.swipeUp() } // Interact with it when visible cell.tap() } One thing I had to do for this in order to work is set isAccessibilityElement to true and also assign accessibilityLabel as a String to the table view so it can be queried by it within the test code. This might not be best practice but for what I could see in my test it works very well. I don't know how it would work when the cell has no text, one might be able to reference the cell(which is not really directly referenced here) by an image view or something else. It's obviously missing the counter from Blaines answer but I left it out for simplicity reasons.
Animate images in Xamarin Forms
I have 5 images that is to be displayed at the bottom of my screen. Now what i want is the images to appear one after the other and in a infinite loop type display (i.e After the 5th Image the 1st image should appear). This should go on as long as the user is on this page. I tried Carousel, but after the 5th image, an auto rewind action takes place and the 1st image is loaded(Horrible). How do i achieve the same using simple animation ?
Did you tried something like this: string[] image = { "image1","another","third","oneMore","lastImage"}; int index = 0; Device.StartTimer(TimeSpan.FromSeconds(5), () => { if(index >= (image.Length - 1)) index = 0; else index++; imgView.FadeTo(0.1, 250, Easing.Linear); imgView.Source = ImageSource.FromResource(image[index]); imgView.FadeTo(1, 250, Easing.Linear); return true; }); Use a simple Image instead of the CarouselView. Maybe you'll need surround the actions over imgView with a "Device.BeginInvokeOnMainThread". Check it out.
How I make a pushbutton invisible in a GUI?
I want to play my wav on percussion background image area with my pushbutton, so i need my pushbutton invisible on my figure window. My script: % --- Executes on button press in pushbutton1. function pushbutton1_Callback(hObject, eventdata, handles) % hObject handle to pushbutton1 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) [s,fs]=wavread('filename.wav'); sound(s,fs); Thankyou..
To make your push button invisible when you click it, set visibleto off in the callback function set(hObject, 'Visible', 'off') To make it invisible from other parts/functions in your GUI, just replace hObject with the handle of your push button. Update: You could make a clickable image and play different sounds for different click positions. Use the callback 'ButtonDownFcn' to trigger at a click event in the image. You can the retrive the position of the click by using the axes property 'CurrentPoint'. This return as 2x3 matrix with x-y-z projected coordinates. But as you are using a 2D plot you could simply pick the first 2 values, read more here. Then use the x/y coordinates to find out what in the image that the user clicked on and play the sound for that. A simple example: % Draw an image figure() imHandle = image(imread(figPath)); % Set callback function (target function could have any name) set(imHandle,'ButtonDownFcn', #ImgClickCB); And the callback function (displays the x and y coord.) function ImgClickCB(hObject, ~) clickPoint = get( get(hObject,'Parent'), 'CurrentPoint'); fprintf('Clicked at x: %0.f y: %0.f \n', clickPoint(1,1), clickPoint(1,2));
The following example hides, and shows a pushbutton. I created a sample, without using guide. You can copy and paste the code into Matlab m file for execution. Creating GUI without guide tool, better suit Stack Overflow site, because there is no need to attach a fig file. You better use guide tool, because creating a GUI without it is complicated. The following code sample hide (and show) pushbutton: %TestNoGuideHideButton.m %Create GUI with two buttons, without using GUIDE. function TestNoGuideHideButton() %Create figure. h.fig = figure('position', [800 400 260 80]); %Add button, with callback function Button1 h.buttonOne = uicontrol('style', 'pushbutton',... 'position',[10 20 100 40], ... 'string' , 'Button1', ... 'callback', {#Button1}); %Add button, with callback function hideButton h.buttonTwo = uicontrol('style', 'pushbutton', ... 'position',[150 20 100 40], ... 'string' , 'Hide Button1', ... 'callback', {#hideButton}); function Button1(hObject, eventdata) %Modify color of Button1 to random color. set(h.buttonOne, 'BackgroundColor', rand(1, 3)); end function hideButton(hObject, eventdata) is_visible = isequal(get(h.buttonOne, 'Visible'), 'on'); if (is_visible) %Hide buttonOne if Visible. set(h.buttonOne, 'Visible', 'off'); set(h.buttonTwo, 'string', 'Show Button1'); %Replace string. else %Restore buttonOne if hidden. set(h.buttonOne, 'Visible', 'on'); set(h.buttonTwo, 'string', 'Hide Button1'); %Replace string. end end end For the problem you described above, you obviously can't add a button for showing and hiding the other button. You can restore the button when playing finishes. You can also add a callback function for the background figure (look for WindowButtonDownFcn in guide). Pressing anywhere on the figure, triggers the callback, were you can restore the hidden button.
You might want to have a look at this blog entry where I discussed how to manipulate the CData property of uicontrols. I've added some code below to show a simple example: f = figure(); % create a figure with an axes on it pb = uicontrol('Style','checkbox', 'Units','pixels', 'Position',[10 10 300 200], ... 'Callback',#(a,b)msgbox('play clown!')); % read some data data = load ( 'clown' ); % extract out the image img = data.X; % convert image to RGB for displaying on checkbox img = ind2rgb(img,colormap(f)); % Set the cdata property of the checkbox to be the image of interest set(pb, 'CData', img ) The above code creates a figure with an image of a clown which you can click on (this could be your drum). The "button" stays there the whole time you don't need to make it invisible Note: I use a checkbox instead of a button -> because sometimes a button can have a "border" when its in focus which can detract from the image whereas a checkbox doesn't. I've copied the image produced below (after I clicked on the button):
Get position of range
I need to be able to get the coordinates of the caret (as in the blinking cursor line) on the page. The intention is then I am going to overlay a tooltip-like element absolutely positioned to look like a tooltip is appearing below the caret. I already am getting the range (CKEDITOR.dom.range) from the selection before this runs, and the range is always collapsed, so the method I'm writing needs to get the position for a collapsed range. This is what I have so far: /** * Get the position of a range * * #param {CKEDITOR.dom.range} range The range (i.e. indicating where the caret is) * #returns {void} */ this.getRangePosition = function( range ){ /* Start with wherever we are scrolled to */ var top = (window.pageYOffset || document.documentElement.scrollTop) - (document.documentElement.clientTop || 0); var left = (window.pageXOffset || document.documentElement.scrollLeft) - (document.documentElement.clientLeft || 0); /* Figure out where the containing element (usually the <p>) is and add that's position on */ var containingElement = range.startContainer.getParent(); // We know range range.startContainer is always text so getParent() takes us to the element var rect = containingElement.getClientRect(); top += rect.top + rect.height; left += rect.left; /* And then figure out how far along we are... */ }; The problem is I'm not sure how to figure out what to do from there. How I have it now gets the correct value for top but not for left as I'm not sure to figure out how far along the range is from the outside of the element. Any ideas on how I could achieve this?
For anyone else coming across this, I ended up doing this: Create a snapshot of the editor and a bookmark for the current selection Insert an element, then use jQuery's .offset() method on that tp figure out the position Restore the snapshot (without that element) and the selection bookmark var snapshot = editor.getSnapshot(); var bookmarks = editor.getSelection().createBookmarks2( true ); var fakeElement = new CKEDITOR.dom.element( 'span' ); editor.insertElement( fakeElement ); var position = $(fakeElement.$).offset(); editor.loadSnapshot( snapshot ); editor.focus(); editor.getSelection().selectBookmarks( bookmarks );