dat.GUI user input not working - javascript

I am building a simple web application. As part of it I want to use dat.GUI since it seems to be the easiest way.
What I want to do:
I am using three.js to display an object. Over this object I want some sort of GUI (currently using dat.GUI) which allows the user to input a search term and hit a button to then call a function which uses the search term.
So far, I have created a variable called search term and the added this to the GUI. This works fine and the value of the variable is displayed. The GUI is also able to listen to the variable and updates once it changes. But I am unable to modify the value. I also added a field to adjust the intensity of the a light I added to the szene in three.js. For this part of the GUI adjusting the value by dragging the bar works but trying to input a value does not.
Code looks something like this:
var searchterm = '';
...
function init(){
....
var gui = new dat.GUI();
gui.add(light, 'intensity').min(1).max(10).listen();
gui.add(this, 'searchterm').listen();
}
Any help on why I can't edit the values or suggestions for other easy to use GUIs would be appreciated.

Not sure if this will help, but this was the problem I was having. If you have any kind of camera controls associated with your three.js canvas, this could be interfering with the GUI. You would be able to adjust sliders, for example, but not edit text. When you attach controls to the three.js camera with, for example, new THREE.OrbitControls(camera);, make sure to specify the three.js dom element as the second parameter like this:
new THREE.OrbitControls(camera, document.getElementById('threeCanvas'));

I have the some problem.
It's coming from the " .listen()" function.
It's buggy.
remove .listen() and it'll work.

The z order might be becoming wrong? I can't find anything easier to use than dat gui.
.main {
z-index: 5;
}
Would make sure this element is at the front. Other than that I'm sure what the problem might be.

I've had the same problem. In my case it was caused by the following CSS:
span {
margin: 0 10px;
}
Applying the style to a newly created class instead of span solved it.

In my case it was a z-index issue. I fixed this with the following:
.dg.ac {
z-index: 1000 !important;
}

Related

Potree profile tool clip boxes not visible

I adjusted the viewer.js example from the Potree project to my own needs. I however find that the clipboxes for the Profile tool are not working anymore. When I start the profile tool I am able to draw the spheres, but no matter what clip mode I use (disabled, clip outside, clip inside) the entire Pointcloud remains visible. I have no idea where to start with the problem, as very little code in viewer.js seems to be related to the ProfileTool specifically. Is there something in the material that needs to be set in order for clipping to work? Should the update methods be called in certain order?
Code:
<button class="shortcut button btn" ng-click="tools.profile({ width: potree.pointcloud.boundingSphere.radius / 100})" tooltip-placement="right" uib-tooltip="Height Profiles">
module.controller('PCToolsController', function($rootScope) {
this.profile = function(options) {
return $rootScope.$broadcast('profile:start', options);
};
});
And in the update function (called before every render):
controls.update();
controls.profiles.forEach(function(profile) {
// Clear the clip boxes
ClipBoxes.length = 0;
profile.boxes.forEach(function(box) {
box.updateMatrixWorld();
var boxInverse = new THREE.Matrix4().getInverse(box.matrixWorld);
ClipBoxes.push(boxInverse);
});
});
controls.render();
The ClipBoxes are the array of clipboxes in the material, when I enter pointcloud.material.clipBoxes I can see the array being filled.
I know that this may be a little undescriptive, but I don't think sharing thousands of lines of viewer code in a JSFiddle will be of any help, and if I break down the issue by starting from the viewer.js as basis, I know that it will work, as the example works. I am therefore not so much looking into a final answer, but rather a direction too look in. Of course if it is beneficial of finding the definite answer I'd be willing to share more info.
Turns out you have to use material.setClipBoxes(clipBoxes) rather than updating the array of clipboxes.

issues with Raphaƫl and removing objects within svg

if you open the code pen there is a fire button. it will launch a bunch of ellipses and then when it hits it will cause a burst. if you look the ellipses ,which there are two sets of, they are still there. I have tried using the below
d3.selectAll("ellipse").remove()
$("ellipse").remove()
$("ellipse").each(function(){this.remove()})
http://codepen.io/daniel667/pen/QwMWrm
the code pen above will help show what im talking about the second fire button to the far right is what ive been trying to use to kill the ellipses so I don't wait for the animation the functions at the very bottom.
I would create a Raphael set, or an array and store the elemets in that, so you can reference them later to remove. If they will be used repeatedly, it may be worth not removing them, but just hiding them rather than recreating each time.
var mySet;
...
mySet = paper.set();
mySet.push( circi );
....
function throwss() {
mySet.forEach( function( el ) { el.remove(); });
}
Example: codepen
For speed, you may also want to look into Velocity.js, also be aware for animation filters can be quite resource heavy.

Ruby on Rails - Gmap4Rails popup for a bigger map

I'm a rails beginner and am using rails 3.2.3.
In my app I'm using the awesome Google-Maps-for-Rails by apneadiving (it's just awesome)
Everything works wonderfully but I have got an issue and didn't find any answers here and there for what I want to do.
Basically I'm displaying a small map and wanted to have a button bellow it and when users clicked it, a bigger map would be displayed of that location.
(basically it would be the same map, only with a bigger size)
Something like this:
<input type="button" onclick="myFunction()" value="Show a bigger map" />
Bu my question is what to put inside that javascript function and how do I say a bigger map with #gmaps values should be displayed?
Create a new id with bigger With and Height in the gmaps css?
How to provide the JS the data from my #gmaps?
Any tips?
Sorry if this is a naive question, I'm still getting used to RoR and the Gmaps4Rails gem.
Thanks in advance for your time.
Regards
I'm not quite sure of what you want to do, but I'd say it's really easy to copy the parameters of one map to another.
Indeed, the whole code needed to create a map is visible in your html, simply reproduce the steps.
The gmaps_helper will do the job for your little map. Basically, it follows the following steps:
Gmaps.map = new Gmaps4RailsGoogle();
//mandatory
Gmaps.map.initialize();
// then some code depending on your options
Gmaps.map.markers = some_array;
Gmaps.map.create_markers();
Whenever you want to duplicate the map, you should simply follow the same steps:
Gmaps.bigmap = new Gmaps4RailsGoogle();
//mandatory to have the map created in the proper place
Gmaps.bigmap.map_options.id = the_id_of_your_html_div;
//still mandatory
Gmaps.bigmap.initialize();
//copy the specific parameters from the other map
Gmaps.bigmap.markers = Gmaps.map.markers;
Gmaps.bigmap.create_markers();

Trying to fix table header, getting css issue

Initially I asked this Question and written my own plugin to achieve the same,But i am facing very strange issue regarding to css of table.
After applying the plugin table cells borders are getting dis-sorted.
jsFiddle of the problem: Problem demo
In fiddle you can see that after first cell of the first tr, the header border line and table border line don't line up. I want the border line of thead cells and td cells to line up.
Can anyone tell me how to achieve that?
Lets start by doing a bit of a clean up of the code you posted so I can actually read your code and maintain a firm grasp on reality while we go down this rabbit hole.
If you write clean code, your problems will be exceptionally easier to see.
So lets clean it up and watch as all the problems here reveal themselves.
Step one: Your jsFiddle sets it to run "onDomReady," which basically means you've got $(document).ready(...) calling all the code in the box, which is fine, except you're got another got $(document).ready(...) inside there. Lets change that.
Step two: Lets add some white space and proper indentation in there, and stop using these one letter variable names.
{} are scope brackets, they should indent, not cover everything, they let us know what part of scope something is in.
Don't write .each() loops on one line, this adds no value and makes your code confusing to read.
$t should be called something meaningful, lets try element, because it holds the $(this) element, which is the active element you're working with.
w should be called something meaningful, but since you only use it twice I'm just going with element.width().
o needs to be less ambiguious, lets go with obj.
Step three: Selection structures
if(typeof(i)=='number')o.height=i;
else if(typeof(i)=='object')o=i;
else if(typeof(i)=='undefined')o={height:300}
Break that up, make it readable. Saving lines doesn't make you a better program, writing clean and easily understandable code will.
Why not use the switch-case statement?
switch (typeof(i)){
case "number":
o.height=i;
break;
case "object":
o=i;
break;
case "undefined":
o={height:300};
break;
}
Step four: Don't in-line styles. Just don't. There's no reason to do it, and it makes everyone's life harder.
Instead, lets just place the styles gently into the style sheet where it belongs, and make the parent=$('...') line look like parent=$('<div><div></div></div>').appendTo('body');.
Step five: Closure doesn't pass any value to arguments
After a bit of clean up, we see this block of code:
self.width(self.width() -
function(width){
var parent,child;
if(width===undefined){
parent=$('<div><div></div></div>').appendTo('body');
child=parent.children();
width= (child.innerWidth()) - (child.height(99).innerWidth());
parent.remove();
}
return width;
}()
);
Okay, that's a problem. Lets cut out a few lines to point out the problem here:
self.width(
self.width() -
function(width){
/*...*/
if(width===undefined){
/*...*/
}
return width;
}()
);
So, a quick refresher on this pattern you have here:
(function(arg1){
/*code*/
})(data);
Data gets passed to arg1. Arg1 declaires a variable in the scope local to that function, it doesn't get anything from outside. Outside data is passed in through the set of () that call the function, which your code had left abandoned. Think of it this way:
var msg = function(text) {
alert(text);
};
Then you call it as...
msg("hello world");
What your closure is doing is almost the same thing, except where you define your function, you also call it. Thus...
(function(text) {
alert(text);
})("hello world");
So, you need to pass a value of some sort into there, other wise this whole thing is always undefined. Lets do that. What are we passing? I have no way to be sure. This is why programmers need to add comments to their code.
Step six: Comment your code so people other than yourself will look at this code and have not a damn clue what you truthfuly wanted to do, and can only guess. It's like you posted a 200 point bounty and didn't bother helping people who want to help you. Why are you doing this to yourself, dude? Why couldn't you just go //This is what this does to give me a hint? What did I ever do to you?
Step Seven: Lets see if we can make the JS changes work with the JS Fiddle
Great odin... that HTML's 2000 lines long?
Okay, I'm working with pastebin here for the sake of saving space in the post here.
Alright, you started off with this: http://pastebin.com/xjmm4cev
You're using a lot of no-wrap, and putting classes onto individual elements. You shouldn't have to do this on each HTML element, CSS takes care of that very effectively, so lets go ahead and just rip out all the nowrap=nowrap and class="header" stuff (we'll put it back in a moment, but only ONE per group, not each element).
Then lets get rid of the useless blank lines.
Lets run this through HTML tidy and get it nice and indented correctly.
http://pastebin.com/uHtSZ4h5
Much easier to read over. Okay, so what do we see here? Well, it looks like you keep going in circles, cutting and pasting the same thing again and again. You also in-line javascript such as using onchange and onclick attributes. This is generally an awful thing to do to your code, and makes it hard to maintain (as I'm sure you've seen with this 2000+ line beast of cut+paste 27 times in a row).
So, lets take a look here:
elements, not inside a form
Elements in a table that are outside of rows, but not head/body/footer sections of a table
Code that's a huge pain to maintain because it keep going in circles, if you need to change this, you're basically screwed.
Lets fix all that.
We're going to use events in the tags, rather than in-line things. So, all of those in-line onchange and click attributes get the boot.
All of these inputs that are just floating around need to get put into a form, and taken out of this place in tables that only rows or table sections belong in.
Figure out how we can not have excessive input elements, if we can help it.
What the heck is the )="" that you have on every input button? Deleted.
So, here's all of your hidden boxes: http://pastebin.com/LXZSkvyf which I've removed, because we don't have a anywhere.
And here's what the code looks like without all of these weird things in it: http://pastebin.com/MiaJTGpb
Much more readable, but still not quite there.
Step 8: What can you do to make the HTML of the table work better?
You're using Thead and Tbody, and that's good.
You're using attributes for things like cellpadding, that's bad.
You've given each body row an ID. I don't feel you needed to do this, but it's not always bad. However, I'll show you how you could work without it.
You give some selects a select-box class, but it's nowhere in the css. I've removed it.
You give a title attribute to the selects that says "option_value". The title attribute is generally used to make a tool-tip popup when you leave the mouse over something. I'm not sure what you're going to do here, but that's bound to confuse your user. I'd highly suggest giving something better than option_value in that place.
You keep using the ID Submit_FMS_AddDelivery. HTML ID tags are meant to be unique, and used only once on one element. You've got it 27 times, that's bad. I don't think you need an ID on it, so I've removed it.
You've also got input-btn going on, I'm removing it, because you haven't shown it's used anywhere.
You probably don't need any of these ID tags on select and TR to be honest, so I'm pulling them.
What's that look like? Basically, you've got what's almost just the data, in it's nice pure form. That's good. http://pastebin.com/UNS6CAtb
Step 9: What were you trying to do?
Lets step back and take a look here.
All you really wanted to do was keep a fixed header, but you've ended up doing a lot of JavaScript hacks and manipulating the DOM in a lot of places. We need to stop doing this. Is there a simpler way to do what you want?
I'll have to expand on how to make this function with the rest of your stuff, but I get up for work in a few hours. I'll update again with more... But we'll get there.
Right now, because I haven't fixed what I took out, it doesn't look right. But I'm tired.
So, here's where we are so far: http://jsfiddle.net/5C6z7/
Plus those inputs we took out (and will be going back in later, in a different way)
Looks like all you have to do is to take the padding into account: each cell has 3 px padding both left and righ so you have to add 6 px to the width:
$t.find('tr:first th').each(function(){cols.push($(this).width()+6);});
Otherwise the cells with only one word inside will "push" the actual width a bit wider so that the word will fit and other cells with space to move will compensate by becoming a bit narrower. The header and the body both do this independently with different contents which creates the difference in actual cell widths.
EDIT: For Firefox you also need to widen the table so that the cells fit. After calculating the column widths add
var actualWidth = $t.width()+cols.length*6;
$t.width( actualWidth );
And later change the wrapper to:
$wrap.css({width:actualWidth,height:o.height,overflow:'auto'});
EDIT 2: To have both the header and the body scroll simultaneously you need to wrap them both to an outer div that handles the scrolling.
var $outerWrap = $( '<div>' ).css( {width:"300px", overflow:'auto' } );
var $wrap=$('<div>').css(
{ width:actualWidth,height:o.height,"overflow-y":'auto', "overflow-x":'hidden' }
);
$firstRow.wrap( $outerWrap );
$firstRow.after( $wrap );
$wrap.append( $t );
Demo: http://jsfiddle.net/YcRTz/2/
What about replacing '<th>' tags with '<td>' tags?
No extra js code required.
http://jsfiddle.net/spQAh/7/
Okay so instead of troubleshooting or using anything complex, I came up with simple CSS + JS solution to your problem. Take a look at http://jsfiddle.net/TdLQT/
Obviously, the process of making header static, can be made dynamic, meaning trigger it after user scrolls a bit or have it there by default or count other object's position from top window and trigger static behavior when it reaches or exceeds certain pixels. I can provide that if you give me details on exact design of your HTML page.
Anyways, I as you can see, have used fixed pixel heights which you can choose not to or make them elastic or dynamic. What is important to know is that, though solution relies on JS a bit, output position is purely from CSS. I am using classes to manipulate the position.
the simple solution is that when you calculate the width of the column you do not include padding. So you need to change the line
$t.find('tr:first th').each( function() {
cols.push($(this).width());
});
to
$t.find('tr:first th').each( function() {
cols.push($(this).outerWidth());
});
if your cells have margins use .outerWidth(true)
This works in quirks mode with IE7&8 and Chrome IE8 has a problem in strict mode. However I believe that that problem is caused by the added scrollbar. If you want to use IE8 in strict mode you have to allow for the width of the vertical scrollbar..

images created dynamically do not appear on screen! -> Javascript

I'm trying to do something simple to practice my Javascript (which I learned some recently) and I'm trying to do a game on it (pacman to be precise).
I am trying to build that game board on the browser by creating images dynamically. I've done an array like this:
var images= new Array(25);
for(i=0;i<25;i++)
images[i]= new Array(25);
And, for the game board I used a matrix done with 0 and 1's with 25x25 size (not going to post it here cause is too big and would make my text hard to read) called board.
For the images that I am using right now I have something like this:
var image_empty = new Image();
image_empty.src="Images/empty.jpg";
var image_wall = new Image();
image_wall.src="Images/wall.jpg";
For the initialization function I have something like this:
function drawField()
{
for(i=0;i<board.length;i++)
{
for(j=0;j<board[i].length;j++)
{
if(board[i][j] == 0)
draw(i,j,image_empty);
else if(board[i][j] == 1)
draw(i,j,image_wall);
}
}
}
And for drawing the images themselves I am using this:
function draw(x,y,img)
{
images[x][y] = new Image(22,22);
images[x][y].src = img.src;
images[x][y].style.position = 'absolute';
images[x][y].style.left = 40+x*22;
images[x][y].style.top = 40+y*22;
}
Every time I run this code nothing appears on the screen. I've tried several times use a load of things but nothing happens. I am saving the pictures (at least I think I am) and still nothing.
Can someone give me some pointers of what could be wrong?
PS: Some people pointed me out using the appendChild method would solve the problem, still, since pacman will be moving around I can't use it to store my images (and I was planning to use the draw function to draw anything).
And btw nor Web Developer plugin or firebug point out errors (the code is correct from their perspective).
Creating an Image in the method you describe doesn't actually display the image. Even putting attributes and styling to make it appear a certain way doesn't add it to the DOM. The advice about append child is correct. For example, if you had:
<div id="main"></div>
and you called
document.getElementById("main").appendChild(images[x][y]);
this would insert the image inside the div. You could do this repeatedly to generate the equivalent of...
<div id="main">
<img src... />
<img src... />
...and so on
</div>
Then, your CSS styling and positioning would work.
There's nothing wrong with your script, but Firebug does display a rendered version of the DOM. As you run the script, you will actually see the HTML tab of Firebug changing with the images you've added to the page.
Also, keep in mind that the DOM must complete loading before you are able to run this. You can accomplish this by doing a simple:
<body onload="drawImages()">
UPDATE: Once you've actually added the 25x25 images, the array still references the elements - they're just now part of the DOM. So, you can change their source via:
images[x][y].src = "newImage.jpg";
If you, for some reason, wanted to remove an image from the board, leaving a gap, you can remove it from the DOM
document.getElementById("main").removeChild(images[x][y]);
or just hide it via CSS.

Categories