I am trying to design a little game using JS, and what I want it to do is make a random number say... 1-100 and then randomly scatter the dots (I used periods with the font size at 200) on the screen. By random, I just mean that I don't want them to be arranged in rows and columns. What I have so far achieves all but scattering the dots, so how do I do that?
var i=0;
var inhtml="."
var num=10
function exe(){
i=Math.floor(Math.random()*100)
//alert(i)
while (i<=100){
document.getElementById("dot").innerHTML = inhtml + "."
inhtml = document.getElementById("dot").innerHTML
if (inhtml.length>num){
inhtml=document.getElementById("dot").innerHTML+"<br />"
num=num+20
}
i++;
}
}
Instead of using a single element containing several periods at a large size, I'd recommend using separate elements for each dot. Then, (besides not having to use 200px periods), you can use CSS to position each element however you want. I have an example here.
Edit: I don't know what the exact problem with getting the dots to not overlap you're having is, but you basically need to do this:
First you pick a position. Then, you check that position against all the other positions (which you'd probably want to do using Manhattan distance). If the point is valid, you use that point and add it to the array of taken positions. Otherwise, go back to the first step.
You may want to check your syntax errors before progressing; I do not know whether you copied all of your code, but you are missing semicolons at the end of your lines. Syntactical issues aside, one possible way to achieve what you describe would be to assign the x- and y-coordinate of each point to a random number. Examination of the code reveals that only the initial value of i is assigned to the value of random(). Incrementing i will make the coordinates of future points dependent on the initial value of i, which is something you may want to take into account. But nowhere in your code do I see you changing the position of the each element based on the values you generate.
I strongly suggest that you use the HTML5 Canvas instead of attempting to move HTML elements; the latter would be cumbersome and lead to messy and inefficient code. If you still want to stick to the method you are trying to use now, check to make sure that the CSS display property is set to block for these elements. You are using the getElementById() method, which is not very useful in this circumstance, since IDs are unique in HTML files. I would suggest using getElementsByTagName() and using those returned elements with a specific class attribute instead.
You might want to look at the HTML 5 Canvas. It allows you draw arcs (aka circles) In any postion, size, and fill color.
Look here for details, here for a tutorial, and here for a demo.
To not be bound by the browser's text layout constraints, you pretty much have to absolutely position your dots:
<div style="position: absolute; top: {random number}; left: {random number}">.</div>
Related
I want to create one single slider in Qualtrics where the min, the MAX and the intervals are chosen according to 4 different embedded data. I need help with the Javascript.
Why do I need one single slider? I need a single slider because I have 16 questions in total, and it is easier to recall 16 questions ID rather than 64 different questions ID.
How should the slider change? I need the slider MAX to be either 1, 10, 100 or 177. Moreover, I always need to have 100 possible choices. Therefore, I need to introduce 2, 1, 0 and 0 decimals, respectively.
Why Javascript? Qualtrics does not allow dynamic custom slider values.
What I have tried so far:
I tried using the default options, but they are not helpful.
I tied looking for resolved questions on StackOverflow but only found this thread: Qualtrics: Dynamically adjusting max value of slider
What your post asks is not a specific question, but rather an entire project. To aid you in this, I have broken up your question into subproblems, all of which can be resolved with simple googling.
First, set up your slider so that it ranges from 0 to 100 - that will ensure that the user always has 100 options. You can then perform a calculation to adjust that to any range you would like based on your embedded data (information how to get embedded data in JS can be found in this post or on the Qualtrics JS API). For more information on how to scale to any rage, here's a good place to start. This calculation is critical as you will use it later on to set the exact value of the grid lines (i.e. intervals) as well as the displayed value (if you opt to display value).
NB: Unfortunately, you are forced to set up the slider to range from 0-100, as you cannot set up more than 20 grid lines. If you could, you could have just set up 100 grid lines and removed the grid lines values and used labels instead for guidance, but there you go.
Next, start with a slider that has a single grid line in the options. You can now adjust these grid lines to your intervals. Specifically, to get the field where these gridlines are defined, get the ul with class name numbers in your slider question. This could look something like this:
let numbers = document.getElementById('QID1').getElementsByClassName('numbers')[0]
This numbers variable will now contain an HTML element with its children being a list of li elements, with each defining a different interval - calculate those interval however your heart desires and add them to the numbers element on the DOM. Tip: to see how this works, play around by examining the DOM when you vary the number of grid lines. Hint: careful when you set the widths (as this is your property to calculate) - for 2 grid lines or 4, all of the li elements have a width of 50 or 25, respectively, but for 11 grid lines the two li elements with classes first and last have width of 5 and the rest of the in-between li elements have a width of 10.
To customize the number that is shown in those intervals (to however many decimal places you want), adjust the innerHTML of those li elements.
Your next step is to make sure that if you do end up showing the value to the participant, then that value can only be a "legit" value. After all, we set the slider from 0 to 100, but it could be 50 to 250 and it must only show values 50-52-54 etc. To achieve that, find the element that displays the value and overwrite it with your calculation (the current value scaled to your desired range). To find the elements, use something like this:
document.getElementById('QID1~1~toolTipBox')
This will look for question with ID QID1 and then look at the first choice's toolTipBox. Overwrite the contest by change its innerHTML.
Finally, don't forget to adjust your data when you process it later on. After all, you have access to all embedded fields in the data, simply scale those to get the actual values (as the ones you will get will most likely be 0-100, though I am not 100% sure how Qualtrics decides what value to save in the data).
I have a group of elements that are masked by a rect in SnapSVG and I want to translate the elements, bringing new ones into view (and hiding ones that are currently in view). The code is really simple - here's a codepen: http://codepen.io/austinclemens/pen/ZbpVmX
As you can see from the pen, box1, which starts outside the mask element (clip) should cross through it when animated, but it never appears. Moreover, box2, which should move out of the clipping area, remains visible.
This example seems to do a similar thing and has no problems: http://svg.dabbles.info/snaptut-masks2
Here's the code from codepen:
var t = Snap('#target')
var clip=t.rect(200,200,200,200).attr({fill:'#fff'})
var box1=t.rect(300,100,50,50).attr({fill:'#000'})
var box2=t.rect(300,300,50,50).attr({fill:'#000'})
var boxgroup=t.group(box1,box2)
boxgroup.attr({mask:clip})
boxgroup.animate({transform:'t100,300'},2000)
I notice that the svg.dabbles examples translates the clip region by 0,0 at one point, but adding something like that doesn't seem to get me anywhere.
Ok, I figured this out thanks in part to this really great article about SVG transforms: http://sarasoueidan.com/blog/svg-transformations/
The upshot is that when I translate the box group, it takes the mask with it. This is a little confusing to me still - I guess the mask attribute is causing this somehow? Anyways, the solution is to apply an opposite translation to the mask to keep it in place. Check the pen to see it in action but basically I just had to add:
clip.animate({transform:'t-100,-300'},2000)
The tricky part of this is that you now need to synchronize the movement of the mask and the movement of the box group.
edit - I now demonstrate how synchronization can be achieved using snap's set.animate method on the codepen.
I have a mathematical problem that I am trying to solve and want to realize in javascript.
I have a "space" meaning: a rectangular format. This shall work as a kind of container.
Then I have smaller forms: other rectangular ones and circles.
I need to find out a solution how to calculate how many of these forms fit into the container.
So I kind of need the ideal way, how to stack these items in there.
If it is too many, leaving out some. And if it is too few, stacking them from bottom up.
I am trying to realize this in Javascript but not getting far.
From my vision it should be kind of like this:
var items = [circle1,2],[rect1,2,4],[rect2,5,6]]; // array with the forms to put inside container, stating a radius for circle and width/height for rectangles
var container = [10, 4]; // given the size of the container in width and height.
function stackItIn (container, items){
// now this is where I am totally lost
}
The premium part would be even showing it graphically at the end.
Any help would be appreciated!
Thank you!
You can try a treemap. Sort the tiles and pick the first and create a node in a tree. Split the tree on both axis and pick the next tile and find the best fit of the nodes.
I'm experimenting with rotating/animating an environment using CSS3 and javascript. So I have a cube object with faces, which lives inside a "rotator" object, which is the object that gets interacted with in the UI. I want to make it so that when you click a face, it appends it to a div outside of the rotator div, but applies the transformation matrices to the object from its parents, so that it appears with the same orientation on the outside of the "rotator" as it did inside, but can be animated and become independent of the rest of the objects in the "rotator" div.
Here is the function for the click event that should do this:
This depends on several custom functions, please see the fiddle for full code and reference to functions.
jQuery('#top').on('click',function(){
if(jQuery(this).parent().is('#cube')){ // only do this if it isn't already detached
M = jQuery(this).getTransMatrix(); // get the local transform of this
M = M.multiply(jQuery('#rotator').getTransMatrix()); // multiply it by the rotator's transform to get the final transform
jQuery(this).appendTo('#container'); // move this to the container div outside of the rotator
jQuery(this).css(CSS3.prefix+'transition','none'); // make sure that style changes, etc happen instantly
// wtf here
console.log(M.cssTransformString()); // just to check, we see the transform string before it is assigned. It's what it should be in my tests
jQuery(this).css(CSS3.prefix+'transform',M.cssTransformString()); // we apply the string. The wrong transformation results. If I double-check it from the console, it is NOT the string from the previous line
}
});
If you check out the fiddle, you will be able to drag around to rotate the cube. Clicking on the face will have some effect. The top face with the star is the one in question. When clicked, simply does not apply the transformation. Even if I log to console the transform string it's about to apply, the next operation does NOT result in that string being applied. It simply does not stick. HOWEVER, if I click and drag slightly, then release with the cursor still on the face, THEN the transform sticks. I have tried tracing virtually everything and I cannot figure out why the transform is only sticking if you click normally (without holding/moving at all)
Fiddle here:
http://jsfiddle.net/spaceboycoop/PWkB9/
I'm not sure if this is possible, but here goes:
I want to find the y co-ordinate of some text. For my purposes, the y co-ordinate of the element containing that text does not suffice. Here's why:
http://jsfiddle.net/3kh3p/
In the above jsfiddle are two characters, one in Georgia, one in Verdana. They are both positioned absolutely with top:0. As you can see, the Verdana character begins at a lower point than the Georgia character.
I need to get the y co-ordinate of the text itself, fairly accurately, because I am using that value to write text to an image using PHP's imagettftext function, and being 5 or 10 pixels out is not OK.
Is there a way?
The only way I can think of would be to draw the text (fillText) into a canvas element, and then query the element's pixel data (getImageData and such) to find out where a given character actually starts vertically according to whatever criteria you want to use (e.g., do you want to ignore upward serifs or not, etc.). Not for the faint of heart, if there's any other way to achieve your overall goal, I'd look elsewhere.