2
\$\begingroup\$

Here's a live demo to what my code does, it works pretty well:

http://brainlessdeveloper.com/demos/javascriptdynamicshadow.html

It's supposed to do what it does: it follows your mouse and rotates the items in the center depending on the position of your mouse. The following JS calculates at which angle relative to the horizontal (passing through the element's center) your mouse is and rotates the circles so that the box-shadows are in the opposite direction (or in the same direction if the shadow is inset).

var circles = document.getElementsByClassName("circle"),
	circlesdown = document.getElementsByClassName("circledown"),
	circle = document.getElementById("circle1"),
	hypotenuseIndicator = document.getElementById("hypotenuseIndicator"),
	indicator = document.getElementById("indicator"),
	circleDiameter = circle.clientHeight,
	circleRadius = circleDiameter / 2,
	centerPosition = circle.getBoundingClientRect(),
	topOffset = centerPosition.top + circleRadius,
	leftOffset = centerPosition.left + circleRadius,
	adjacent, hypotenuse, cosine,
	degrees,
	x,
	y;
	console.log("Circle center position is " + topOffset + "px from top, " + leftOffset + "px from left.");
	console.log("Circle diameter is " + circleDiameter + "px.");
	// FIGURING OUT MOUSE POSITION
function getCoords(event) {
	x = event.clientX;
	y = event.clientY;
	var mousePosition = "X: " + x + ", Y: " + y;
	indicator.innerHTML = mousePosition;
}
function getAngle () {
	// X-AXIS DISTANCE OF THE MOUSE WITH RESPECT TO THE CIRCLE CENTER
	adjacent = x - leftOffset;
	// DISTANCE BETWEEN THE MOUSE AND THE CIRCLE CENTER
	hypotenuse = Math.sqrt(Math.pow(leftOffset - x, 2) + Math.pow(topOffset - y, 2));
	hypotenuseIndicator.innerHTML = hypotenuse;
	// GETTING ANGLE RELATIVE TO THE X-AXIS
	var theta = Math.atan2(topOffset - y, adjacent);
	degrees = theta * (180 / Math.PI);
	degreesIndicator.innerHTML = degrees;
	// PRINTING OUT STYLES, NORMAL AND INSET SHADOW
	for (var i = 0; i < circles.length; i++) {
		circles[i].style.transform="rotate(" + degrees * (-1) + "deg)";
		circles[i].style.boxShadow= "-" + Math.abs(hypotenuse / 50) + "px 0px " + Math.abs(hypotenuse / 20) + "px rgba(0,0,0,0.2)";
	}
	for (var i = 0; i < circlesdown.length; i++) {
		circlesdown[i].style.transform="rotate(" + degrees * (-1) + "deg)";
		circlesdown[i].style.boxShadow= "inset -" + Math.abs(hypotenuse / 30) + "px 0px " + Math.abs(hypotenuse / 10) + "px rgba(0,0,0,0.2)";
	}
	// REMOVING SHADOWS IF THE USER IS CLOSE TO THE CENTER OF THE CIRCLE
	if (hypotenuse < 30) {
		for (var i = 0; i < circles.length; i++) {
			circles[i].style.boxShadow= "-" + Math.abs(hypotenuse / 50) + "px 0px " + Math.abs(hypotenuse / 20) + "px rgba(0,0,0,0)";
		}
		for (var i = 0; i < circlesdown.length; i++) {
			circlesdown[i].style.boxShadow= "inset -" + Math.abs(hypotenuse / 30) + "px 0px " + Math.abs(hypotenuse / 10) + "px rgba(0,0,0,0)";
		}
	}
}
body, html {
		background:white;
		position:absolute;
		top:0;
		height:100vh;
		width:100vw;
		margin:0;
		padding:0;
		overflow:hidden;
	}

	.centertext {
		position:absolute;
		z-index:20;
		font-family:Raleway;
		width:400px;
		font-size:18px;
		color:#BEBEBE;
		text-align:center;
		line-height:60px;
		top:calc(50% - 35px);
		left:calc(50% - 200px);
	}

	#indicator {
		position:fixed;
		bottom:0;
		right:0;
	}

	#hypotenuseIndicator {
		position:fixed;
		bottom:20px;
		right:0;
	}

	#degreesIndicator {
		position:fixed;
		bottom:40px;
		right:0;
	}

	.indicator {
		display:none;
	}

	.circle {
		padding:0;
		display:block;
		position:absolute;
		vertical-align:middle;
		border-radius:50%;
		will-change:transform;
	}

	.circledown {
		padding:0;
		display:block;
		position:absolute;
		vertical-align:middle;
		border-radius:50%;
		will-change:transform;
	}

	#circle1 {
		background:#FFFFFF;
		left:calc(50% - 200px);
		top:calc(50% - 200px);
		width:400px;
		height:400px;
		z-index:10;
	}

	#circle2 {
		background:#FFFFFF;
		left:calc(50% - 350px);
		top:calc(50% - 350px);
		width:700px;
		height:700px;
	}
<body onmousemove="getCoords(event); getAngle();">
	<p class="centertext">JAVASCRIPT DYNAMIC BOX SHADOW</p>
	<div id="circle1" class="circle"></div>
	<div id="circle2" class="circledown"></div>
	<div class="indicator" id="indicator"></div>
	<div class="indicator" id="hypotenuseIndicator"></div>
	<div class="indicator" id="degreesIndicator"></div>
</body>

Question:

I think my code looks like spaghetti. And I'm sure there's a couple of mistakes/inefficiencies in the logic of my code. Also, as a moderately new developer, I'm sure I'm not structuring my code properly.

What are your suggestions in order to improve the quality of this JS code (please ignore the HTML&CSS)?

\$\endgroup\$
3
\$\begingroup\$

Variables

Have you developed an aversion to the var keyword? In other words, why declare all your variables in one declaration - spread them out a little. I tend to have one declaration per group of related variables, so perhaps:

var circles = document.getElementsByClassName("circle"),
    circlesDown = document.getElementsByClassName("circledown"),
    circle = document.getElementById("circle1");

var hypotenuseIndicator = document.getElementById("hypotenuseIndicator"),
    indicator = document.getElementById("indicator");

var circleDiameter = circle.clientHeight,
    circleRadius = circleDiameter / 2;

var centerPosition = circle.getBoundingClientRect(),
    topOffset = centerPosition.top + circleRadius,
    leftOffset = centerPosition.left + circleRadius;

var adjacent, hypotenuse, cosine;
var degrees;
var x, y;

Naming

What's circlesdown? What's circle1? You should name your variables according to the data they hold. If that's an element, name it majorCircleElement or something similar. Sequential naming (x1, x2, x3) is bad.

COMMENTS

You don't need to shout at yourself, you haven't done anything wrong! Additionally, try to make your comments a description of why your code does what it does, rather than just telling us what it does - if the code is good, you should be able to figure out what it does by reading the code, not the comments.

Minor Points

degrees * (-1)

could be written much more concisely:

-degrees

Lastly, consider adding a few blank lines between sections of your code, to space out related lines into sections.

\$\endgroup\$
  • \$\begingroup\$ Those are some awesome comments! I'm rewriting the same thing using drop-shadow filters now and I have your post on my second monitor ^^ \$\endgroup\$ – Fausto NA Apr 20 '16 at 20:10
  • \$\begingroup\$ I re-coded this into something similar but different and started a GitHub repo, in case you're interested. \$\endgroup\$ – Fausto NA Apr 22 '16 at 0:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.