Drawing 3D objects - javascript

I'm looking to draw a 3D cylinder with javascript by copying the layers and applying an increased margin to these elements. I have tried to set the height of the element in my input and run the copy function while total margin of the copied elements is lower than the set height of elements.
http://jsfiddle.net/yuX7Y/3/
<form>
<input type="number" id="userHeight" />
<button type="submit" onclick="circleHeight">Submit</button>
</form>
<div class="circle">
</div>
<div class="slice">
</div>
$(document).ready(function(){
var initMargin = 4;
var totalMargin = 0;
var i = 0;
function copy(){
$(".slice").clone().appendTo( ".content" ).css({'margin-top': totalMargin + "px"});
console.log("cloned");
i++;
totalMargin = initMargin + 4;
}
function setH(){
while(i < (document.getElementById("userHeight").value)){
copy();
}
if(i>100){
initMargin = 4;
i=0;
}
}
});

Jump To The Result: http://jsfiddle.net/yuX7Y/15/
Notes
This Fiddle/question intrigued me so I went ahead and looked at it for a little while. There were actually a number of issues, some obvious and some less obvious. Somewhat in the order I noticed them these are some of the issues:
jQuery wasn't included in the fiddle
The click event wasn't wired up correctly - it was actually trying to submit the form. You need to use e.preventDefault to stop the form from submitting. Since you were already using jQuery I just wired up with the jQuery click event:
$("#recalculateHeight").click(function (e) {
e.preventDefault();
setH();
});
Because of the use of "global" variables (variables not initialized within the routines), the submit would only work once. Instead of this, I moved variable declarations to the appropriate routine.
Calling $(".slice").clone() clones ALL slice elements on the page. The first time you clone, this is fine. But after that you are cloning two elements, then three elements, etc (as many slice elements as are on the page). To solve this I created a slice template like:
<div class="slice" id="slice-template" style="display: none"></div>
Then you can clone to your hearts content like $("#slice-template").clone(). Just don't forget to call the jQuery show() method or set display back to block on the cloned element.
Finally, if you want to repeat the process many times you need to be able to clear previous elements from the page. I find this easiest to do by creating containers, then clearing the contents of the container. So I put all of the "slices" into this container:
<div class="content">
Now when you want to clear the content node you can just call $(".content").empty();.
I also made a few style based changes in my Fiddle, but those don't make it work or not work, they just help me read the code! So, there you have it! Best of luck!

Related

How do I removeAttribute() hidden from p2? doesn't seem to do anything as is

I'm trying to change the attribute of an object with removeAttribute to take away the hidden status of it but so far nothing seems to work.
My code seems to have no effect. Am I doing something wrong?
function changePage() {
document.getElementById.("p2");
p2.removeAtribute.("hidden") ;
}
I've also tried it all on one line as well like so
function changePage() {
document.getElementById.("p2").p2.removeAtribute.("hidden") ;
}
I've never seen the use of dots before opening parentheses.
E.g.
document.getElementById.("p2").p2.removeAtribute.("hidden") should be document.getElementById("p2").removeAtribute("hidden")
(You are also referencing the element by id after you just retrieved it, which is unnecessary.)
Your first example didn't work because you retrieved the element and did nothing with it, then tried to access a p2 variable that wasn't declared. Again, you also have the . before parentheses.
Here's the js example:
function changeVisibility()
{
var p2 = document.getElementById('p2');
switch (p2.style.visibility)
{
case 'hidden':
document.getElementById('p2').style.visibility = 'visible';
break;
case 'visible':
document.getElementById('p2').style.visibility = 'hidden';
break;
}
}
<div id="p2" style="visibility:hidden">
test
</div>
<br />
<button onclick="changeVisibility()">
change visibility with basic js
</button>
And here's the jQuery example:
function changePage()
{
$('#p2').toggle();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="p2" style="display:none">
test
</div>
<br />
<button onclick="changePage()">
change visibility with basic js
</button>
The basic JS version uses the visibility style, and you can see that it doesn't collapse the element, it only makes it invisible.
jQuery has a nice built-in .toggle function that changes the display of the element. If it is hidden, it collapses the element. When the element is displayed, it is re-assigned whatever the display style is for that element. Building that in basic js would take a lot more work, as you are then tracking state (if you want to make the method reusable). You can make jQuery work similarly to the basic js version if you use the css properties, but toggle is quite nice and simple.
Your main issue is that you were mixing the getting of the element with methods that are only available on jQuery objects. I suggest reading the jQuery tutorials for basic accessors, which can get elements by id, class name, etc.

How do I make an OnClick function that will change a word when a user clicks it to another word?

Okay so, I want to make an OnClick function in JavaScript that makes it so when a user clicks on it, it will change the word. Is there a replaceword() function or something that which will let me do so? I know this is not real code, but for example:
<p>Quickly <span onclick="replaceword('Surf');">Search</span> The Web!</p>
If there is, then can someone tell me also how to reverse the code maybe? So when they click on it the second time, it will change back to "Search"?
If you want to jump between multiple words, you'll need to store them someplace. You could have two words in the sentence, and toggle the visibility of one or the other (which doesn't scale well), or you could even store them as values on an attribute placed on the element itself.
<p>Hello, <span data-values="World,People,Stack Overflow">World</span>.</p>
I have placed all possible values within the data-values attribute. Each distinct value is separated from the other values by a comma. We'll use this for creating an array of values next:
// Leverage event-delegation via bubbling
document.addEventListener( "click", function toggleWords ( event ) {
// A few variables to help us track important values/references
var target = event.target, values = [], placed;
// If the clicked element has multiple values
if ( target.hasAttribute( "data-values" ) ) {
// Split those values out into an array
values = target.getAttribute( "data-values" ).split( "," );
// Find the location of its current value in the array
// IE9+ (Older versions supported by polyfill: http://goo.gl/uZslmo)
placed = values.indexOf( target.textContent );
// Set its text to be the next value in the array
target.textContent = values[ ++placed % values.length ];
}
});
The results:
The above listens for clicks on the document. There are numerous reasons why this is a good option:
You don't need to wait for the document to finish loading to run this code
This code will work for any elements added asynchronously later in the page life
Rather than setting up one handler for each element, we have one handler for all.
There are some caveats; you may run into a case where the click is prevented from propagating up past a particular parent element. In that case, you would want to add the eventListener closer to your target region, so the likeliness that bubbling will be prevented is less.
There are other benefits to this code as well:
Logic is separated from markup
Scale to any number of values without adjusting your JavaScript
A demo is available for your review online: http://jsfiddle.net/7N5K5/2/
No, there isn't any native function, but you can create on your own.
function replaceword(that, word, oword) {
that.textContent = that.textContent == oword ? word : oword;
}
You can call it like this:
<p>Quickly<span onclick="replaceword(this,'Surf','Search');">Search</span>The Web!</p>
Live Demo: http://jsfiddle.net/t6bvA/6
<p id="abc">Hello</p>
<input type="submit" name="Change" onclick="change()">
function change(){
var ab=document.getElementById('abc').value;
ab.innerHTML="Hi, Bye";
}
I think so this should help you, you should go to site such as w3schools.com, its basic and it will answer your doubt
You can try something like this if you wanna use jQuery
http://jsfiddle.net/R3Ume/2/
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<body>
<p>Hello <a id='name'>John<a></p>
<input id="clickMe" type="button" value="replace" onclick="onClick();" />
<script>
function onClick() {
$('#name').text('world');
}
</script>

Drag/Drop Functionality with div tags purely using javascript

I need to create a nested drag/drop functionality using purely Javascript (No Jquery or other plugins please).
The Idea is to have a several div tags as groups and having ability to drag that div tag/group on top of another div tag/group to create a sub group within itself(as a child of that group) max level of sub subs allowed is 4. To Illustrate what I am talking about please look at this Jquery Plugin NestedSortabled example, It defines exactly what I am looking for.
NestedSortable Jquery Example
Another similar example: http://dbushell.com/2012/06/17/nestable-jquery-plugin/
I need to develop my code to function exactly like the example above, but using purely old school javascript only, please dont suggest any Jquery code.
Here is what I have currently working, However I am stuck right now and cant figure out how to get the sub grouping functionality to work. Please Help!!
My working Demo: http://jsbin.com/IzAfutI/1
My working Demo + Code: http://jsbin.com/IzAfutI/3/edit?html,css,js,output
Edit:
Let me example the code in more detail. StartDrag and StopDrag contain the main logic behind the functionality. Basically when user drags a div tag I am currently creating a container on top of or underneath a already existing div tag for the item that is to be dragged to be placed into, however when I use this same funcionality to create that container within another container(via creating sub group) I am getting an error. which means Maybe I am going at the problem the wrong way maybe my logic might be wrong or else something else wrong with the code.
HTML mark up of group div tag:
<div class="dragContainerUsed">
<div id="a7b94a42-fb00-4011-bd5a-4b48e6e578c5" class="dragPanel">
<input type="hidden" value="1|fa7989d7-1708-4a90-9bf6-c91f6cef6952" />
<div onmousedown="startDrag(event, this.parentNode)" class="dragPanelHeader">
<div style="margin-left:4px; margin-top:3px; float:left;">1 - Group 1<span id="gta7b94a42-fb00-4011-bd5a-4b48e6e578c5"></span></div>
</div>
</div>
<div class=\"dragSubContainerUnUsed\"></div>
</div>
<div class="dragContainerUnUsed"></div>
So what I want to happen is when user drags another div on top of the div dragSubContainerUnUsed it should be placed within that subContainer....
On start drag, I create a array to store all the containers and subContainers:
containers = new Array();
subContainers = new Array();
containers.push(dragTarget);
for (i = 0; i < divs.length; i++) {
if (divs[i].className.toLowerCase() == "dragcontainerunused") {
containers.push(divs[i]);
}
}
for (i = 0; i < divs.length; i++) {
if (divs[i].className.toLowerCase() == "dragSubcontainerunused") {
subContainers.push(divs[i]);
}
}
and currently the part where I am stuck is in the functions onDrag and stopDrag, I dont know how to get the subContainers to work via to create the subgroups...
For Instance if I drag Group 3 on top of Group 2, I want group 3 to be a sub group of 2 Like this:
and I should be able to add max of 4 groups into each sub group, with max of 4 sub groups.
like this:
and finally there should only be a max of 4 levels of subgrouping
like this:
Please Help in anyway you can, if you can identify the problem than please tell me or if there needs to be a change in logic for my code tell me, Even if you can completely re-write/ create your own new code to make this application work would be very much appreciated. I have been trying to tackle this for a few days any and all help will be greatly accepted...
Check This code
function allowDrop(ev){
ev.preventDefault();
}
function drag(ev)
{
ev.dataTransfer.setData("Text",ev.target.id);
}
function drop(ev)
{
ev.preventDefault();
var data=ev.dataTransfer.getData("Text");
ev.target.appendChild(document.getElementById(data));
}
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)">
</div>"
<img id="drag1" src="img_logo.gif" draggable="true" ondragstart="drag(event)" width="336" height="69">`
Been working on this, completed it couple of months ago. but forgot about this post. so i decided to post the complete solution for anyone else that might be looking for a answer to this enjoy.
The entire code is too long to post it in here, but here is the link to the code:
Drag/Drop Functionality with Div Tags
DEMO: http://jsbin.com/aTUHULu/1
You have to divide the drop rectangle into 4 areas , if you drop it in the first one it will be on level 1 and if you drop it on the next 40px lets say it will be considered level 2 and hence
I would post the code as well if you want but I think the approach itself would work if you try and implement it. Here is the approach
Instead of div, add the item as a listitem . This would auto intend the control and it would be very easy for you to parse it at the end. What you need to do here is that onDrop, take the text (and other properties) from the div, create a li and add the div in that li. This would enable your code to redrag and drop the div further. Note - remember to remove the li (or ul according to the parent of div) when drag ends.

Using JQuery/Javascript arrays to form two sided fading layout

When I do sites for clients I constantly get the request to have a two sided layout, where buttons on the left cause divs on the right to fade in and fade out appropriately. For a long while I've been writing each case. (which is a bit silly and time consuming). I want to systematize that, but I've been having a hard time since I don't understand how javascript/jquery works with .click() and arrays.
$(document).ready(function(){
var left = new Array($('#a'),$('#b'), $('#c'),$('#d'), $('#e'));
var right = new Array($('#1'),$('#2'),$('#3'),$('#4'),$('#5'));
// left[0].click(function(){right[0].fadeIn('fast');})
var numbers = new Array(1,2,3,4,5);
function fadey(x){
left[x].click(function(){
right[x].fadeIn('fast');
})
}
for (var i = 0; i < left.length; i++) {
fadey(i);
};
})
This code gets it so that the left hand side buttons cause the corresponding right hand div to appear. The problem is that I can't seem to get the other divs to disappear without causing all the divs to disappear.
Ideally it would be dope if I could have one line of code that simply checks when the left-hand jquery object array is clicked, gets its index value, and causes the corresponding right hand side jquery object array to appear, while also hiding the other ones.
This way I can just plug elements into each array and then never have to worry about writing these cases one by one.
Thank you so much for your help!
You could just make a generic event handler with classes instead of IDs:
$('.left button').click(function() {
var index = $(this).index();
$('.right section').eq(index).fadeIn('fast');
});
I'm assuming your HTML looks something like this:
<aside class="left">
<button>One</button>
<button>Two</button>
<button>Three</button>
</aside>
<aside class="right">
<section>One</section>
<section>Two</section>
<section>Three</section>
</aside>

Javascript show/hide - I don't want it to hide the entire element

This is probably a fairly easy question, but I'm new to JavaScript and jquery....
I have a website with a basic show/hide toggle. The show/hide function I'm using is here:
http://andylangton.co.uk/articles/javascript/jquery-show-hide-multiple-elements/
So here's my question..... I would really like the first 5-10 words of the toggled section to always be visible. Is there some way I can change it so that it doesn't hide the entire element, but hides all but the first few words of the element?
Here's a screenshot of what I would like it to do:
http://answers.alchemycs.com/mobile/images/capture.jpg
There are many different implementation possibilities:
You can divide the contents up into the first part and the second part (two separate spans or divs inside your main object) and hide only the child object that represents the second part, not hide the parent object.
Rather than hide the object at all, you can set its height to only show the first part (with overflow: hidden)
Change the contents of the main object to only have the first part as the contents (requires you to maintain the full contents somewhere else so you can restore it when expanded again).
Here's a working example of option 1: http://jsfiddle.net/jfriend00/CTzsP/.
You'd need to either:
Put in a span/etc. after the first n words, and only hide that part, or
Change the viewable region, or
Replace or toggle the span/etc. with the "collapsed" view.
The last is a bit more customizable; using two separate elements allows trivial games to be played (showing an image, for example, like a little curly arrow) without modifying adding/removing DOM elements.
I tend towards the last because it's simple and obvious, but that's a personal preference, and really isn't as true as it used to be.
You can do some plugin authoring,I did a sample demo here ,based on your screenshot
<div class="toggle">ShowHide</div>
<div class="content">some content some content some content some content some content <br/> some content some content some content </div>
<div class="toggle">ShowHide</div>
<div class="content">some content some content some content some content some content <br/> some content some content some content </div>
here is javascript/jquery code
jQuery.fn.myToggle = function(selector, count) {
var methods = {
toggle: function(selector, count) {
if ($(selector).is(':visible')) {
var span = $('<span>');
span.text($(selector).text().substr(0, count) + "...");
span.insertAfter($(selector));
$(selector).hide();
}
else {
$(selector).show();
$(selector).next('span').hide();
}
}
};
$(this).each(function() {
methods.toggle($(this).next(selector), count);
$(this).click(function(evt) {
methods.toggle($(this).next(selector), count);
});
});
};
$(function() {
$('.toggle').myToggle('.content', 3);
});
Here is a solution using css properties only instead of mangling the dom.
http://jsfiddle.net/AYre3/4/
Now if you want some sort of animation happening as well you'll probably need to do a bit of measurement along the way.

Categories