Create line connecting two DIVs - javascript

I am creating a relationship editor. The user create some elements and is able to link them creating a relationship (bidirectional). I've created the first part (users creating elements). Now I need to create lines connecting two DIVs when users double click an element, for example.
I know that may have a couple of ways to do it, but actually I have no idea how to start it. What would be a starting point?
$(function() {
$("#BtInsert").button()
.click(function() {
var pad = "000000"
var cor = "" + Math.floor(Math.random() * 16777215).toString(16);
cor = "#" + pad.substring(0, pad.length - cor.length) + cor;
var newDIV = document.createElement('div');
$(newDIV).addClass("base")
.appendTo($("#container"))
.html('N')
.dblclick(function() {
alert('Want to start to create a line from this div to another double click');
})
.draggable({
containment: "parent"
})
.css({
left: Math.floor(Math.random() * ($("#container").width() - $(".base").width())),
top: Math.floor(Math.random() * ($("#container").width() - $(".base").width()))
})
.css("background-color", cor);
})
});
#BtInsert {
top: 405px;
width: 400px;
position: absolute;
}
body {
margin: 0px;
padding: 0px;
}
#container {
border: solid 1px #CCC;
width: 400px;
height: 400px;
padding: 0;
margin: 0;
top: 0;
left: 0;
background-color: whitesmoke;
}
.base {
height: 50px;
width: 50px;
top: 30px;
left: 30px;
border-radius: 25px;
box-shadow: 2px 2px 2px #888888;
vertical-alignment: middle;
line-height: 50px;
text-align: center;
margin-bottom: 5px;
font-family: Calibri;
font-weight: bold;
font-size: 2em;
color: white;
background-color: #CCC;
cursor: pointer;
-webkit-transition: width 3s, height 3s, border-radius 3s, line-height 3s, box-shadow 3s;
transition: width 3s, height 3s, border-radius 3s, line-height 3s, box-shadow 3s;
float: left;
position: absolute;
z-index: 0;
}
.base:hover {
z-index: 1000;
color: #333;
width: 80px;
height: 80px;
border-radius: 50px;
line-height: 80px;
box-shadow: 4px 4px 4px #888888;
-webkit-transition: width 1s, height 1s, border-radius 1s, line-height 1s, box-shadow 1s;
transition: width 1s, height 1s, border-radius 1s, line-height 1s, box-shadow 1s;
}
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
<div id="container">
</div>
<a href="#" id="BtInsert">
Insert an element
</a>
JS Fiddle

Its better to use SVG instead of HTML for this kind of representations. you will have more flexibility in drawing shapes in SVG.
You can take a look at http://d3js.org/ or http://raphaeljs.com/
See this examples:
http://bl.ocks.org/enoex/6201948
http://blog.stephenboak.com/2012/06/15/d3-flow-vis-tutorial.html
-> https://web.archive.org/web/20130108020533/http://blog.stephenboak.com:80/2012/06/15/d3-flow-vis-tutorial.html
it's doing something similar to what you want.

Related

Is it possible to change the style of an element when a specific div/element is scrolled into view?

Specifically, I want to change colors of sticky and fixed elements on my page dynamically as the user scrolls into specific sections. I know that this is possible with the pixel height on scroll, but I can't use this technique, because the background of my page consists of a stack of images. This causes the pixel height of the page to change dramatically on window resize due to the height needing to increase as the image gets wider
.
I guess it would be possible to do this with a bunch of media calls, but I'm trying to avoid this, and I'm not even sure it would work.
My main goal would be:
When a div is scrolled into view, the style (mainly color and font-weight) of the navigation bar and fixed footer change.
Also - This has to be in Vanilla JS.
If someone has a pure CSS solution, that's very acceptable as well, I just can't think of a way this would work.
Thank you!
How About Using This?
These are VanillaJS SpyScroll
https://github.com/cferdinandi/gumshoe
https://github.com/ederssouza/vanillajs-scrollspy
From Codepen zchee/pen/ogzvZZ
HTML
<div class="m1 menu">
<div id="menu-center">
<ul>
<li><a class="active" href="#home">Home</a>
</li>
<li>Portfolio
</li>
<li>About
</li>
<li>Contact
</li>
</ul>
</div>
</div>
<div id="home" class="section"></div>
<div id="portfolio" class="section"></div>
<div id="about" class="section"></div>
<div id="contact" class="section"></div>
SCSS
body, html {
margin: 0;
padding: 0;
height: 100%;
width: 100%;
}
.menu {
width: 100%;
height: 75px;
background-color: rgba(0, 0, 0, 1);
position: fixed;
background-color: rgba(4, 180, 49, 0.6);
-webkit-transition: all 0.3s ease;
-moz-transition: all 0.3s ease;
-o-transition: all 0.3s ease;
transition: all 0.3s ease;
}
.light-menu {
width: 100%;
height: 75px;
background-color: rgba(255, 255, 255, 1);
position: fixed;
background-color: rgba(4, 180, 49, 0.6);
-webkit-transition: all 0.3s ease;
-moz-transition: all 0.3s ease;
-o-transition: all 0.3s ease;
transition: all 0.3s ease;
}
#menu-center {
width: 980px;
height: 75px;
margin: 0 auto;
ul {
margin: 15px 0 0 0;
li {
list-style: none;
margin: 0 30px 0 0;
display: inline;
}
}
}
.active {
font-family: 'Droid Sans', serif;
font-size: 14px;
color: #fff;
text-decoration: none;
line-height: 50px;
}
a {
font-family: 'Droid Sans', serif;
font-size: 14px;
color: black;
text-decoration: none;
line-height: 50px;
}
#home {
background-color: grey;
height: 100%;
width: 100%;
overflow: hidden;
}
#portfolio {
height: 100%;
width: 100%;
}
#about {
background-color: blue;
height: 100%;
width: 100%;
}
#contact {
background-color: red;
height: 100%;
width: 100%;
}
JS
(function() {
'use strict';
var section = document.querySelectorAll(".section");
var sections = {};
var i = 0;
Array.prototype.forEach.call(section, function(e) {
sections[e.id] = e.offsetTop;
});
window.onscroll = function() {
var scrollPosition = document.documentElement.scrollTop || document.body.scrollTop;
for (i in sections) {
if (sections[i] <= scrollPosition) {
document.querySelector('.active').setAttribute('class', ' ');
document.querySelector('a[href*=' + i + ']').setAttribute('class', 'active');
}
}
};
})();

Pure CSS Checkbox with JS toggle not working

Searched all over the internet, and I can't beat this issue.
I have a pricing section with a pricing plan switch. The logic itself is working fine, however, the CSS checkbox toggle itself isn't switching from left to right.
I assume it has to do with the CSS itself or the way I select the elements with JS. I've also read some topics on SO where they say that it's a checkbox issue with WordPress, didn't find my answer there, unfortunately.
The issue
On Chrome desktop, the CSS checkbox toggle isn't working.
On Safari, iPhone X the CSS checkbox switch checkbox does work but only if you click the label elements with text
Here's a link to the page
Link to Dropbox of me demonstrating the issue on iPhone
window.onload = function() {
var e = document.getElementById("firstPlan"),
d = document.getElementById("secondPlan"),
t = document.getElementById("switcher_iOS"),
m = document.getElementById("firstPlan_box"),
y = document.getElementById("secondPlan_box");
if (document.getElementById("switcher_iOS") == null) {
var node = document.createElement("input");
node.id = "switcher_iOS";
node.type = "checkbox";
node.className = "toggle_iOS--check";
var elm = document.getElementsByClassName('toggle_iOS')[0];
elm.insertBefore(node, elm.firstChild)
t = document.getElementById("switcher_iOS");
}
e.addEventListener("click", function() {
t.checked = false;
e.classList.add("togglePricing--is-active");
d.classList.remove("togglePricing--is-active");
m.classList.remove("hide");
y.classList.add("hide");
});
d.addEventListener("click", function() {
t.checked = true;
d.classList.add("togglePricing--is-active");
e.classList.remove("togglePricing--is-active");
m.classList.add("hide");
y.classList.remove("hide");
});
t.addEventListener("click", function() {
d.classList.toggle("togglePricing--is-active");
e.classList.toggle("togglePricing--is-active");
m.classList.toggle("hide");
y.classList.toggle("hide");
t.checked = !t.checked;
})
}
/* Toggle */
#switcher_iOS {
width: 100%;
}
.toggle_iOS,
.togglePricing {
display: inline-block;
vertical-align: middle;
margin: 10px;
}
.togglePricing {
color: #ccc9c9;
cursor: pointer;
transition: .1s;
font-weight: bold;
font-size: 17px;
}
.togglePricing--is-active {
color: #181818;
}
.toggle_iOS {
position: relative;
width: 58px;
height: 28px;
border-radius: 100px;
background-color: #1D8BF1;
overflow: hidden;
box-shadow: inset 0 0 2px 1px rgba(0, 0, 0, 0.05);
}
.toggle_iOS--check {
position: absolute;
display: block;
cursor: pointer;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0;
z-index: 6;
}
.toggle_iOS--check:checked~.toggle_iOS--switch {
right: 2px;
left: 57.5%;
transition: 0.15s cubic-bezier(0.785, 0.135, 0.15, 0.86);
transition-property: left, right;
transition-delay: .01s, 0s;
}
.toggle_iOS--switch {
position: absolute;
left: 2px;
top: 2px;
cursor: pointer;
bottom: 2px;
right: 57.5%;
background-color: #fff;
border-radius: 36px;
z-index: 1;
transition: 0.15s cubic-bezier(0.785, 0.135, 0.15, 0.86);
transition-property: left, right;
transition-delay: 0s, .01s;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
}
<label class="togglePricing togglePricing--is-active" id="firstPlan">Payment Plan</label>
<div class="toggle_iOS">
<label for="switcher_iOS"><input type="checkbox" onclick="void(0);" id="switcher_iOS" class="toggle_iOS--check" checked></label><b onclick="void(0);" class="toggle_iOS--switch"></b>
</div>
<label class="togglePricing" id="secondPlan">One Payment</label>
I have simplified your css, and in order for this to work, you have to remove your JS that reset the state of the checkbox from the checkbox on click event such as
t.checked = !t.checked;
var t = document.getElementById("switcher_iOS");
t.addEventListener("click", function(){
console.log("i am", this.checked);
})
.toggle_iOS{
position: relative;
width: 58px;
height: 28px;
border-radius: 100px;
background-color: #1D8BF1;
overflow: hidden;
box-shadow: inset 0 0 2px 1px rgba(0,0,0,0.05);
}
.toggle_iOS--switch{
position: absolute;
left: 2px;
top: 2px;
cursor: pointer;
bottom: 2px;
right: 57.5%;
background-color: #fff;
border-radius: 36px;
z-index: 1;
transition: 0.15s cubic-bezier(0.785,0.135,0.15,0.86);
transition-property: left,right;
transition-delay: 0s,.01s;
box-shadow: 0 1px 2px rgba(0,0,0,0.2);
}
[type=checkbox]:checked + .toggle_iOS--switch{
left: 57.5%;
right: 2px;
}
.toggle_iOS [type=checkbox]{
position: absolute;
display: block;
cursor: pointer;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0;
z-index: 6;
}
<div class="toggle_iOS">
<input type="checkbox" id="switcher_iOS">
<div class="toggle_iOS--switch"></div>
</div>

Make arrow in button point down after menu slides out

I have a button that has an arrow appended to it when a user hovers over it. When clicked, a content div slides out in its wrapper using jQuery.slideToggle().
Once the div slides out, I want to make the arrow in the button rotate 180 degrees to signify that pressing it will make the content div go down if clicked again.
I made a JsFiddle to show what I have so far: https://jsfiddle.net/414mwv17/
What would be the best way to make the arrow point down after the button is clicked?
Create a new class for how you want the carat to appear :
#makeGroupButton span.rotate:after
{
transition: opacity 0.5s, top 0.5s, right 0.5s;
transform: rotate(135deg);
}
Note the class addition in the selector.
Then change the javascript/jQuery to just toggle that class:
$('#makeGroupButton').bind('click', function(){
$('#slideout').slideToggle(500);
$(this).children('span').toggleClass('rotate');
});
You can't directly select the :after and :before pseudo selectors with jQuery, so just changing the class, and adding CSS is customarily the easiest method.
Updated fiddle
Have started it for you to build on. Check this out and let me know your feedback. Thanks!
Added the following style:
#makeGroupButton span.open:after {
border: 3px solid #FFF;
border-top: none;
border-right: none;
margin-top: -15px;
}
and some js too:
$('#makeGroupButton').bind('click', function(event) {
event.preventDefault();
$('#slideout').slideToggle(500);
$(this).find('span').toggleClass('open');
});
#wrapper{
height: 500px;
width: 300px;
position:relative;
border: 2px solid blue;
}
#slideout {
height: 95%;
width: 95%;
border: 2px solid red;
position: absolute;
bottom: 0;
left: 2.5%;
}
#makeGroupButton
{
clear: both;
text-align: center;
color: white;
width: 220px;
background:black;
overflow: hidden;
transition: all 0.5s;
}
#makeGroupButton:hover, #makeGroupButton:active
{
text-decoration: none;
background-image: linear-gradient(to bottom, #3cb0fd, #3498db);
}
#makeGroupButton span
{
display: inline-block;
position: relative;
padding-right: 0;
transition: padding-right 0.5s;
}
#makeGroupButton span:after
{
content: '';
position: absolute;
top: 0;
right: -20px;
opacity: 0;
width: 15px;
height: 15px;
margin-top: -5px;
background: rgba(0, 0, 0, 0);
border: 3px solid #FFF;
border-bottom: none;
border-left: none;
transition: opacity 0.5s, top 0.5s, right 0.5s;
transform: rotate(-45deg);
}
#makeGroupButton:hover span, #makeGroupButton:active span
{
padding-right: 30px;
}
#makeGroupButton:hover span:after, #makeGroupButton:active span:after
{
transition: opacity 0.5s, top 0.5s, right 0.5s;
opacity: 1;
border-color: white;
right: 0;
top: 50%;
}
#makeGroupButton span.open:after {
border: 3px solid #FFF;
border-top: none;
border-right: none;
margin-top: -15px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="wrapper">
<div id="slideout" style="display: none;"></div>
</div>
<a href="#" id="makeGroupButton">
<span>New Group</span>
</a>
I would add a class rotate on click then apply the following css :
#makeGroupButton.rotate span:after {
top: 0px;
-webkit-transform: rotate(-228deg) !important;
}
I have update your js fiddle https://jsfiddle.net/414mwv17/2/.
A much cleaner way to do it would be use an arrow icon then just rotate that icon by 180 degrees.
Hope this helps

Load width transition when page gets to certain point in scroll?

I'm trying to trigger an animation through when the page is scrolled to a certain point. Here's what I have so far (Codepen version):
$(window).scroll(function () {
var hT = $('#photoshop').offset().top,
hH = $('#photoshop').outerHeight(),
wH = $(window).height(),
wS = $(this).scrollTop();
console.log((hT - wH), wS);
if (wS > (hT + hH - wH)) {
// I need the CSS to happen here, so it happens when the page is scrolled to "photoshop". //
}
});
body {
background-color: black;
}
#photoshop {
font-family: 'Roboto', sans-serif;
color: #FF5444;
text-align: left;
background-color: transparent;
width: 20%;
margin-left: 24%;
margin-bottom: 3px;
padding: 2px;
margin-top: 10px;
padding-left: 3px;
font-size: 80%;
}
/* this is what I need to happen when the page is scrolled to id="photoshop"
#photoshop {
width: 40%;
background-color: #134;
transition: ease-in 400ms;
-moz-transition: ease-in 400ms;
-webkit-transition: ease-in 400ms;
transition-delay: 200ms;
}
*/
.percent {
display: inline;
color: #fff;
margin-right: 3px;
font-size: 80%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div id="photoshop">
<div class="percent">80%</div> photoshop
</div>
</body>
I've tried doing a get element by ID function, but it won't load the css when I need it to. I don't know much about JavaScript and would like to do this with as little scripting as possible. Is there a way to change CSS after the if (wS > (hT + hH - wH)) { line?
Try the below,
You can use jQuery addClass method,
Just create a new class using css and apply that class using addClass method when the div is visible in the viewport
$(window).scroll(function() {
var hT = $('#photoshop').offset().top,
hH = $('#photoshop').outerHeight(),
wH = $(window).height(),
wS = $(this).scrollTop();
console.log((hT - wH), wS);
if (wS > (hT + hH - wH)) {
$('#photoshop').addClass("photoshop_trans");
}
});
body {
background-color: black;
}
.dummy {
height: 500px;
}
#photoshop {
font-family: 'Roboto', sans-serif;
color: #FF5444;
text-align: left;
background-color: transparent;
width: 20%;
margin-left: 24%;
margin-bottom: 3px;
padding: 2px;
margin-top: 10px;
padding-left: 3px;
font-size: 80%;
}
/* this is what I need to happen when the page is scrolled to id="photoshop" */
#photoshop.photoshop_trans {
width: 40%;
background-color: #134;
transition: ease-in 400ms;
-moz-transition: ease-in 400ms;
-webkit-transition: ease-in 400ms;
transition-delay: 200ms;
}
.percent {
display: inline;
color: #fff;
margin-right: 3px;
font-size: 80%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div class="dummy"></div>
<div id="photoshop">
<div class="percent">80%</div>photoshop
</div>
</body>
You can use the jquery .css() function (see docs). It takes a json object with the css properties and values you wish to apply. So you would do something like this:
if (wS > (hT + hH - wH)) {
$('#photoshop').css({
'width': '40%',
'background-color': '#134',
'transition': 'ease-in 400ms',
'-moz-transition': 'ease-in 400ms',
'-webkit-transition': 'ease-in 400ms',
'transition-delay': '200ms',
});
}

Scripted image won't wrap with text

just trying to align some text with an image on the right, the image is using javascript to transition between 2 images. I need the transitional effects to stay but also be able to have text wrap to the left of it in the same container. Can anyone help please?
HTML
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Kawasaki Motorcycle Club UK</title>
<link rel="stylesheet" href="main.css">
</head>
<body>
<div id="wrapper">
<div id="header">
</div>
<nav>
<ul class="navbar">
<li>BIKES</li>
<li>NEWS</li>
<li>EVENTS</li>
<li>JOIN</li>
<li>CONTACT</li>
</ul>
</nav>
</div>
<div class="contentbox">
<div id="maincontent">
CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT
CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT
CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENTtestestestest
<img name = "slides" id="slides" src="images/mybike.jpg"/>
<img name = "slides" id ="slides" src="images/racergreen.jpg"/>
<script> //adapted from https://www.youtube.com/watch?v=e1AYSgA57h8
var interval = 4 * 20; // seconds between change
var images = document.getElementsByName("slides");
var imageArray = [];
var imageCount = images.length;
var current = 0;
var randomize = function(){
return (Math.round(Math.random() * 3 - 1.5));
}
for(var i = 0; i < imageCount; i++){
images[i].className = 'fade-out';
imageArray[i] = images[i];
}
imageArray.sort(randomize);
var fade = function(){
imageArray[current++].className = 'fade-out';
if(current == imageCount){
current = 0;
imageArray.sort(randomize);
}
imageArray[current].className = 'fade-in';
setTimeout(fade, interval * 100);
};
fade();
</script>
</div>
</div>
<br>
<div>
<div class="socialcontainer">
<img id="facebookbutton"/>
<img id="twitterbutton"/>
<img id="googlebutton"/>
</div>
</div>
</body>
CSS
body {
font-family: 'Arial', sans-serif;
background-color: #000;
}
#wrapper {
max-width: 1000px;
margin: 0 auto;
background-color: #fff
padding: 32px;
}
#header {
height: 110px;
background: url(images/header.png);
}
header h1 { //NOT NEEDED
text-align: center;
color: #FFF;
}
header h2 { //NOT NEEDED
font-variant: small-caps;
text-align: center;
color: #fff;
}
.navbar {
padding: 5px 0 5px 0;
text-align: center;
line-height: 35px;
background: url(images/navbar.png);
background-size: contain;
}
ul.navbar {
margin-top: 15px;
}
.navbar li {
display: inline;
padding: 0 40px 0 40px;
font-size: 30px;
font-weight: 800;
}
a:hover, a:visited, a:link, a:active {
text-decoration: none;
background: #60bf19;
color: #FFF;
text-shadow:
-5px -5px 0 #000;
}
a:hover {
color:dimgrey;
text-shadow:
-5px -5px 0 #000;
}
a:active {
color: #FFF
text-shadow:
-5px -5px 0 #000;
}
.contentbox {
width: 1000px;
position: relative;
margin: 0 auto;
background-color: #383131;
border-radius: 5px;
height: 1000px;
}
#maincontent {
color: #FFF;
position: relative;
float: left;
}
#slides{
-webkit-transition-property:opacity;
-webkit-transition-duration:3s;
position:absolute;
right: 0
}
#slides.fade-out {
opacity:0;
}
#slides.fade-in {
opacity:1;
}
.socialcontainer {
width: auto;
height: auto;
text-align: center;
}
#facebookbutton {
background-image: url(images/facebook-hover.png);
height: 48px;
width: 48px;
-webkit-transition: all ease 0.3s;
-moz-transition: all ease 0.3s;
-o-transition: all ease 0.3s;
-ms-transition: all ease 0.3s;
transition: all ease 0.3s;
}
#facebookbutton:hover {
background-position: 0px -48px;
box-shadow: 0px 0px 4px 1px rgba(0,0,0,0.8);
}
#twitterbutton {
background-image: url(images/twitter-hover.png);
height: 48px;
width: 48px;
-webkit-transition: all ease 0.3s;
-moz-transition: all ease 0.3s;
-o-transition: all ease 0.3s;
-ms-transition: all ease 0.3s;
transition: all ease 0.3s;
}
#twitterbutton:hover {
background-position: 0px -48px;
box-shadow: 0px 0px 4px 1px rgba(0,0,0,0.8);
}
#googlebutton {
background-image: url(images/google-hover.png);
height: 48px;
width: 48px;
-webkit-transition: all ease 0.3s;
-moz-transition: all ease 0.3s;
-o-transition: all ease 0.3s;
-ms-transition: all ease 0.3s;
transition: all ease 0.3s;
}
#googlebutton:hover {
background-position: 0px -48px;
box-shadow: 0px 0px 4px 1px rgba(0,0,0,0.8);
}
Assuming I understand what you are trying to do..
you could place the text and images inside the #maincontent element within seperate div tags respectively and then align them side-by-side with their own css. Technically they aren't within the SAME container like you said you wanted but they are still both within the #maincontent container.
here is my JSFiddle that hopefully helps. note that I included random images inplace of your ones for the fade effect.
<div id="maincontent">
<div id="content-box">CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENT CONTENTtestestestest
</div>
<div id="image-box">
<img name="slides" width="500px" id="slides" src="images/mybike.jpg" />
<img name="slides" width="500px" id="slides" src="images/racergreen.jpg" />
</div>
</div>
added css:
#content-box {
width: 500px;
height: 100%;
background-color: '#3e4';
float: left;
overflow: hidden;
}
#image-box {
width: 500px;
height: 100%;
background-color: '#3e4';
float: left;
overflow: hidden;
}

Categories

Resources