Change one div's class using another div's click handler - javascript

I am in a class that is writing an online UNO game (this is not a graded assignment, just a class project). I am currently trying to develop the functionality to play a card. Basically, the player needs to be able to click on a card in their hand and have it appear in the discard pile. I thought about animating this, but we have 1 week left and a lot to get done, so my idea is to just have the player double-click on the card and it will appear in the discard pile.
Each of the cards in all the players' hands are separate divs created in javascript via information from the back end. I do not, however, have the code connected to the back end yet because I need to be able to test my functions and script now. Thus I have currently hard-coded the cards.
The discard pile has one card on it. I have determined that we don't actually need every single card to be placed on the discard pile. Rather, it should be enough to change the color and the rank of the card on the discard pile to reflect the card discarded and just eliminate that div from the player's hand. If you think I am wrong about this, please tell me.
That is where my problem is. I have a bit of script here that is supposed to erase the color of the discard pile card and replace it with the color of the div card that was clicked on in the player's hand. Here is the code (full code posted later in the post):
/*
The double-click on the card in the player's hand does erase the color from the discard pile card, but it doesn't add the color of the card from the hand to the discard pile card. I have tried different variations of the code, but none seem to work. Can anyone help me? Or am I thinking about this the wrong way?
*/
$(document).ready(function() {
function playCardThisPlayer(game) {
currCardColor = $(this).color;
$(".card").dblclick(function() {
$(".discardPile").removeClass(game.discardPile.color);
$(".discardPile").addClass.$(currCardColor);
});
}
playCardThisPlayer(gameTurn);
var gameTurn = {
deckCount: 40,
discardPile: {
color: "yellow",
rank: "2"
},
players: [{
name: "David", //players[0].name
hand: [{
color: "yellow",
rank: "3"
},
{
color: "blue",
rank: "3"
},
{
color: "red",
rank: "4"
},
{
color: "black",
rank: "w"
},
{
color: "blue",
rank: "7"
},
{
color: "blue",
rank: "8"
},
{
color: "green",
rank: "S"
}
]
},
{
name: "Dan", //players[1].name
hand: 4 //players[1].hand
},
{
name: "John", //players[2].name
hand: 5 //players[2].hand
},
{
name: "Kent", //players[3].name
hand: 10 //players[3].hand
},
{
name: "Amy",
hand: 15
}
]
};
function makePlayerList(game) {
for (i = 0; i < game.players.length; i++) {
$(".list").append("<p>" + (i + 1) + ". " + game.players[i].name + "</p>");
}
}
makePlayerList(gameTurn);
function createCards(game) {
var currPlayer = game.players[0];
var hand = $("<div class='hand'></div>");
for (var i = 0; i < currPlayer.hand.length; i++) {
var card = $("<div class='card'></div>" /*<div class='playerLabel'></div>"*/ );
card.addClass(".oval-shape");
var corner1 = $("<div></div>");
var middle = $("<div></div>");
var corner2 = $("<div></div>");
var oval = $("<div></div>")
corner1.append(currPlayer.hand[i].rank);
corner1.addClass("corner1");
middle.append(currPlayer.hand[i].rank);
middle.addClass("middle");
oval.addClass("oval-shape");
card.append(oval);
corner2.append(currPlayer.hand[i].rank);
corner2.addClass("corner2");
card.append(corner1);
card.append(middle);
card.append(corner2);
card.addClass(currPlayer.hand[i].color);
hand.append(card);
}
$("#table").append(hand);
}
function createCardBacks(game) {
for (var i = 1; i < game.players.length; i++) {
var hand = $("<div class='hand'></div>");
for (var j = 0; j < game.players[i].hand; j++) {
var cardBack = $("<div class='cardBack black'></div>");
var oval = $("<div></div>")
oval.addClass("oval-shape");
cardBack.append(oval);
hand.append(cardBack);
}
$("#table").append(hand);
}
}
function createDiscardPile(game) {
var topOfDiscardPile = $(".discardPile");
topOfDiscardPile.addClass(".oval-shape");
var corner1 = $("<div></div>");
var middle = $("<div></div>");
var corner2 = $("<div></div>");
var oval = $("<div></div>")
corner1.append(game.discardPile.rank);
corner1.addClass("corner1");
middle.append(game.discardPile.rank);
middle.addClass("middle");
oval.addClass("oval-shape");
topOfDiscardPile.append(oval);
corner2.append(game.discardPile.rank);
corner2.addClass("corner2");
topOfDiscardPile.append(corner1);
topOfDiscardPile.append(middle);
topOfDiscardPile.append(corner2);
topOfDiscardPile.addClass(game.discardPile.color);
}
createCards(gameTurn);
createCardBacks(gameTurn);
createDiscardPile(gameTurn);
function playCardThisPlayer(game) {
currCardColor = $(this).color;
$(".card").dblclick(function() {
$(".discardPile").removeClass(game.discardPile.color);
$(".discardPile").addClass.$(currCardColor);
});
}
playCardThisPlayer(gameTurn);
function fan(container, angle) {
var num = $(container).children().length;
var rotate = -angle * Math.floor(num / 2);
$(container).children().each(function() {
$(this).data("rotate", rotate);
$(this).css("transform", "translate(-50%,0) rotate(" + rotate + "deg)");
$(this).css("transform-origin", "0 100%");
rotate += angle;
});
$(container).children().mouseenter(function() {
var rotate = parseInt($(this).data("rotate")) * Math.PI / 180;
$(this).css("top", (-3 * Math.cos(rotate)) + "vmin");
$(this).css("left", (3 * Math.sin(rotate)) + "vmin");
});
$(container).children().mouseleave(function() {
$(this).css("top", 0);
$(this).css("left", 0);
});
}
var rotate = 0;
var num = $("#table").children().length;
var angleInc = 360 / num;
$("#table").children().each(function(idx) {
$(this).css("transform", "rotate(" + rotate + "deg)");
$(this).append("<div class='playerLabel'><span>" + (idx + 1) + "</span></div>")
$(this).css("transform-origin", "50% -18vmin");
fan(this, (idx == 0) ? 7 : 2.5);
rotate += angleInc;
});
});
* {
margin: 0;
padding: 0;
}
body {
background: #00a651;
}
#table {
width: 100vmin;
height: 100vmin;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
background-color: #00FF00;
border-radius: 50%;
}
.card {
position: absolute;
top: 0;
left: 0;
display: inline-block;
}
.discardPile {
position: absolute;
bottom: 0;
left: 0;
display: inline-block;
}
.card,
.discardPile {
width: 15vmin;
height: 22vmin;
border-radius: 1vmin;
background: #fff;
-webkit-box-shadow: 3px 3px 7px rgba(0, 0, 0, 0.3);
box-shadow: 3px 3px 7px rgba(0, 0, 0, 0.3);
text-shadow: 2px 2px 0px #808080;
border: .3em solid white;
transition: all 0.125s;
}
.hand {
position: absolute;
left: 50%;
bottom: 10vmin;
width: 0;
height: 22vmin;
}
span {
position: absolute;
z-index: 100;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.playerLabel {
margin-top: -10vh;
background-color: red;
width: 3vmin;
height: 3vmin;
border: 1px solid black;
border-radius: 50%;
}
.list {
color: yellow;
font-family: 'Gloria Hallelujah', cursive;
font-size: 3vmin;
}
.yellow {
background-color: yellow;
}
.blue {
background-color: blue;
}
.red {
background-color: red;
}
.green {
background-color: green;
}
.black {
background-color: black;
}
.corner1 {
position: absolute;
font-size: 3.5vmin;
left: .5vmin;
top: .5vmin;
color: white;
}
.corner2 {
position: absolute;
font-size: 3.5vmin;
right: .5vmin;
bottom: .5vmin;
color: white;
}
.middle {
position: absolute;
font-size: 10vmin;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.oval-shape {
width: 10vmin;
height: 22vmin;
background: white;
border-radius: 7vmin / 15vmin;
transform: translate(-50%, -50%) rotate(25deg);
margin: 0 auto;
position: absolute;
left: 50%;
top: 50%;
}
.slide-out {
top: -3vmin;
}
.cardBack {
position: absolute;
top: 0;
display: inline-block;
width: 15vmin;
height: 22vmin;
border-radius: 1vmin;
-webkit-box-shadow: .3vmin .3vmin .7vmin rgba(0, 0, 0, 0.3);
box-shadow: .3vmin .3vmin .7vmin rgba(0, 0, 0, 0.3);
text-shadow: .2vmin .2vmin 0 #808080;
border: .3em solid white;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>UNO Cards</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://fonts.googleapis.com/css?family=Gloria+Hallelujah" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="style.css">
<script src="https://code.jquery.com/jquery-3.2.1.js" integrity="sha256-DZAnKJ/6XZ9si04Hgrsxu/8s717jcIzLy3oi35EouyE=" crossorigin="anonymous"></script>
</head>
<body>
<div class="list"></div>
<div class="discardPile"></div>
<div id="table"></div>
<script src="script.js"></script>
</body>
</html>
Thanks!

Related

Website code works fine on Chrome and Firefox, desktop or mobile, but does not work on Safari

A certain piece of my website works fine on Chrome and Firefox, but does not seem to work on Safari. I checked and all the people trying the website on iPhones had Javascript enabled. Is there something about my code that cannot be read by Safari? Are there any tools out there to test how code would be perceived on Safari that I can use with a windows computer?
Below is the code to the piece of my website. I had to replace all images and text with different content because I am forbidden to share the actual content. Essentially, this piece of the website would allow someone to input a certain metric in, via a slider bar, and see what something would look like with said metric. The slider bar seems to be movable, but images are not appearing, nor are they moving when viewing through Safari. As an additional note, I converted this code to https (what Wix refers to as all in one text block) and inserted it into my Wix website as an html element.
I realize that my JavaScript has quite a few redundancies, such as defining the same variable locally twice instead of defining it globally once. I'm looking to fix those later and get this working first (although this could be why it doesn't work on Safari?). I've never developed anything before, so any help at all would be much appreciated.
Update: I had a few people send me screenshots and the slider bar AND javascript are working, the images are just not showing up on Safari.
HTML
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<meta name="description" content="">
<meta name="author" content="">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
<!-- Box-->
<div class="wholething">
<div class="box">
<!-- Dude -->
<img class="img-square img-dude" src="https://i.pinimg.com/474x/ff/5a/74/ff5a741afd59d527f4492c593b329106--free-clipart-downloads-free-clipart-images.jpg" id="dude" </img>
<!-- Banana-->
<img class="img-square img-bn" src=" https://upload.wikimedia.org/wikipedia/commons/0/0a/Candy-clipart.svg" id="flag">
</img>
<div class="whitebox" id="whiteboxID">
</div>
<img class="gorilla" src="https://openclipart.org/download/249534/1464300474.svg" id="gorillaID" </img>
</div>
<h1 class="sliderlabel" id="sliderlabelID">Hunger level</h1>
<h1 class="sliderlabelinfo" id="sliderlabelinfoID">(drag to select)</h1>
<!-- Slider -->
<div class="slidecontainer">
<input type="range" min="3" max="10" value="5" step="0.1" class="slider" id="inchslider">
<output name="rangeVal" id="value"></output>
</div>
</div>
</body>
</html>
CSS
html {
overflow-y: hidden;
}
.wholething {
height: 100%;
width: 100%;
left: 0;
right: 0;
margin-left: auto;
margin-right: auto;
position: absolute;
}
.box {
background-color: #F5F4EF;
height: 60%;
width: 81.25%;
position: absolute;
left: 0;
right: 0;
margin-left: auto;
margin-right: auto;
border-radius: 5%;
}
.img-dude {
position: absolute;
top: 0;
bottom: 0;
margin-top: auto;
margin-bottom: auto;
margin-left: 20px;
height: 90%;
}
.img-bn {
position: absolute;
top: 0;
bottom: 0;
margin-top: auto;
margin-bottom: auto;
z-index: 2;
height: 10.125%;
}
.whitebox {
position: absolute;
background-color: #F5F4EF;
top: 0;
bottom: 0;
height: calc(15% + 15px);
width: calc(15% + 20px);
margin-top: auto;
margin-bottom: auto;
z-index: 1;
}
.gorilla {
position: absolute;
top: 0;
bottom: 0;
right: 0%;
margin-top: auto;
margin-bottom: auto;
z-index: 2;
height: 90%;
display: none;
}
.sliderlabel {
position: absolute;
left: 12.5%;
top: 61%;
font-size: 16px;
font-family: Arial;
font-weight: 900;
}
.sliderlabelinfo {
position: absolute;
left: 12.5%;
top: 66.5%;
font-size: 14px;
font-family: Arial;
font-weight: 500;
}
.slidervalue {
position: absolute;
top: 20px;
left: 28.5%;
}
.slidecontainer {
width: 75%;
position: absolute;
left: 0;
right: 0;
top: 90%;
margin-left: auto;
margin-right: auto;
}
.slider {
-webkit-appearance: none;
-moz-apperance: none;
width: 100%;
height: 10px;
background-image: -webkit-gradient( linear, left top, right top, color-stop(0.15, #4BD1A0), color-stop(0.15, #F5F4EF));
position: absolute;
outline: none;
opacity: 0.7;
-webkit-transition: .2s;
transition: opacity .2s;
border-radius: 5px;
left: 0;
right: 0;
margin-left: auto;
margin-right: auto;
}
.slider:hover {
opacity: 1;
box-shadow: 0 0 0 2px #4BD1A0;
}
.slider::-webkit-slider-thumb:hover+output {
display: block;
transform: translateX(-50%);
box-shadow: 0 0 0 2px #4BD1A0;
}
.slider:active {
opacity: 1;
box-shadow: 0 0 0 2px #4BD1A0;
}
.slider::-webkit-slider-thumb:active {
box-shadow: 0 0 0 2px #4BD1A0;
}
.slider::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 25px;
height: 25px;
background: #F5F4EF;
cursor: pointer;
border-radius: 50%;
}
.slider::-moz-range-thumb {
width: 25px;
height: 25px;
background: #4CAF50;
cursor: pointer;
}
output {
position: absolute;
top: -50px;
left: calc(28.57% + 3.25px);
width: 80px;
height: 30px;
border: 1px solid #e2e2e2;
background-color: #4BD1A0;
border-radius: 10px;
color: white;
font-size: 14px;
line-height: 30px;
text-align: center;
vertical-align: middle;
display: block;
transform: translateX(-50%);
}
input[type=range]:hover+output {
display: block;
transform: translateX(-50%);
}
input[type=range]:active+output {
display: block;
transform: translateX(-50%);
}
input[type=range] {
background-image: -webkit-gradient(linear, left top, right top, color-stop(0.2857, #4BD1A0), color-stop(0.2857, #F5F4EF))
}
output:after {
content: "";
position: absolute;
width: 0;
height: 0;
border-top: 10px solid #4BD1A0;
border-left: 10px solid transparent;
border-right: 10px solid transparent;
top: 100%;
left: 40%;
margin-top: -1px;
}
JavaScript
$(function() {
var element = document.getElementById('dude'),
style = window.getComputedStyle(element),
width = style.getPropertyValue('width'),
height = style.getPropertyValue('height');
var slicedwidth = width.slice(0, -2);
var slicedheight = height.slice(0, -2);
var widthmargarin = ((Number(slicedwidth) * 0.55) + 20).toString() + "px";
var heightmargarin = (Number(slicedheight) * 0.488).toString() + "px";
var whiteboxwidthmargarin = ((Number(slicedwidth) * 0.55) + 25).toString() + "px";
document.getElementById("flag").style.marginLeft = widthmargarin;
document.getElementById("flag").style.marginBottom = heightmargarin;
document.getElementById("value").innerHTML = "5 points";
document.getElementById("whiteboxID").style.marginLeft = whiteboxwidthmargarin;
});
function setIcon(x, y) {
var element = document.getElementById('dude'),
style = window.getComputedStyle(element),
width = style.getPropertyValue('width'),
left = style.getPropertyValue('left'),
height = style.getPropertyValue('height');
var slicedwidth = width.slice(0, -2);
var slicedheight = height.slice(0, -2);
var widthmargarin = ((Number(slicedwidth) * 0.55) + (((x - 5) / 100 * 4.6) * Number(slicedwidth)) + 20).toString() + "px";
var heightmargarin = ((Number(slicedheight) * 0.485) + (((y - 5) / 100 * 0.5) * Number(slicedheight))).toString() + "px";
document.getElementById("flag").style.marginLeft = widthmargarin;
document.getElementById("flag").style.marginBottom = heightmargarin;
document.getElementById("flag").style.transform = "rotate(" + (7 - (x * 1.3)) + "deg)";
document.getElementById("whiteboxID").style.marginLeft = (Number(widthmargarin.slice(0, -2)) + 5).toString() + "px";
document.getElementById("whiteboxID").style.transform = "rotate(" + (7 - (x * 1.5)) + "deg)";
}
var slider = document.getElementById("inchslider");
var output = document.getElementById("value");
output.innerHTML = slider.value;
slider.oninput = function() {
output.innerHTML = this.value;
var positionXslider = 0;
var positionYslider = 0;
if (this.value >= 5) {
positionXslider = output.innerHTML;
positionYslider = output.innerHTML;
document.getElementById("flag").src = "https://upload.wikimedia.org/wikipedia/commons/0/0a/Candy-clipart.svg";
} else if (this.value >= 4 && this.value < 5) {
positionXslider = 5;
positionYslider = 5;
document.getElementById("flag").src = "https://openclipart.org/download/284444/1502025489.svg";
} else if (this.value < 4) {
positionXslider = 5;
positionYslider = 5;
document.getElementById("flag").src = "https://image.shutterstock.com/image-vector/slice-pizza-on-white-background-260nw-597727904.jpg";
} else {
positionXslider = output.innerHTML;
positionYslider = output.innerHTML;
}
setIcon(positionXslider, positionYslider);
};
$('input[type="range"]').on('input', function() {
var val = ($(this).val() - $(this).attr('min')) / ($(this).attr('max') - $(this).attr('min'));
$(this).css('background-image',
'-webkit-gradient(linear, left top, right top, ' +
'color-stop(' + val + ', #4BD1A0), ' +
'color-stop(' + val + ', #F5F4EF)' +
')'
);
});
$('input[type="range"]').on('input', function() {
var control = $(this),
controlMin = control.attr('min'),
controlMax = control.attr('max'),
controlVal = control.val(),
controlThumbWidth = 25;
var range = controlMax - controlMin;
var position = ((controlVal - controlMin) / range) * 100;
var positionOffset = Math.round(controlThumbWidth * position / 100) - (controlThumbWidth / 2) + 2.25;
var output = control.next('output');
var controlValNumber = Number(controlVal)
var controlValLabel = 0;
if (controlValNumber >= 5) {
controlValLabel = controlVal.slice(0, 3);
} else if (controlValNumber >= 4 && controlValNumber < 5) {
controlValLabel = 4;
} else if (controlValNumber < 4) {
controlValLabel = 3;
}
if (controlValNumber >= 10) {
document.getElementById("gorillaID").style.display = "block";
} else {
document.getElementById("gorillaID").style.display = "none";
}
output
.css('left', 'calc(' + position + '% - ' + positionOffset + 'px)')
.text(controlValLabel + " points")
});

Why is there a random space when you click on this button?

I have been trying to replicate some material design buttons but have run into an issue with the div that is generated to create the "ripple" effect. If you go to my codepen at https://codepen.io/AlexStiles/pen/oPomzX you will see the issue.
This is caused by the div (I tried deleting it and it fixed the problem). I have tried adding a variety of properties such as font-size and line-height to no avail. Interestingly, depending on your browser the issue seems to have a different effect. On safari the width increases hugely then it decreases to the chrome width.
"use strict";
const buttons = document.getElementsByTagName("button");
const overlay = document.getElementsByClassName("overlay");
const animationTime = 600;
for (let i = 0; i < buttons.length; i++) {
buttons[i].addEventListener("click", createRipple);
};
let circle = document.createElement("div");
function createRipple(e) {
this.appendChild(circle);
var d = Math.max(this.scrollWidth, this.scrollHeight);
circle.style.width = circle.style.height = d + "px";
circle.style.left = e.clientX - this.offsetLeft - d / 2 + "px";
circle.style.top = e.clientY - this.offsetTop - d / 2 + "px";
circle.classList.add("ripple");
// setTimeout(function(){
// for (let i = 0; i < circle.length; i++)
// document.getElementsByClassName("ripple")[i].remove();
// }, animationTime);
}
button {
background-color: #4888f1;
border-radius: 24px;
display: flex;
align-items: center;
outline: 0;
border: 0;
padding: 10px 22px;
cursor: pointer;
overflow: hidden;
position: relative;
}
button .ripple {
position: absolute;
border-radius: 50%;
background-color: rgba(255, 255, 255, 0.5);
transform: scale(0);
animation: ripple 0.5s linear;
font-size: 0;
line-height: 0;
}
#keyframes ripple {
to {
transform: scale(2.5);
opacity: 0;
}
}
button img {
width: 20px;
height: 20px;
}
button *:not(:last-child) {
margin: 0 8px 0 0;
}
button span {
color: #fff;
font-family: Futura;
}
#media screen and (min-width: 1280px) {
button {
padding: 0.8vw 1.75vw;
border-radius: 1.9vw;
} button img {
width: 1.55vw;
height: auto;
} button span {
font-size: 0.8vw;
}
}
<html>
<head>
<title>Material Design Components</title>
<link rel="stylesheet" href="style.css">
</head>
<button>
<span>Add to Cart</span>
</button>
<script src="js.js"></script>
</html>
Change
button *:not(:last-child) {
margin: 0 8px 0 0;
}
To,
button *:not(:last-child) {
margin: 0 0 0 0;
}
Checked in firefox.
When you add the ripple element you make it the last-child thus the rule of margin button *:not(:last-child) will apply to span since this one is no more the last child.
To fix this remove margin from the span:
"use strict";
const buttons = document.getElementsByTagName("button");
const overlay = document.getElementsByClassName("overlay");
const animationTime = 600;
for (let i = 0; i < buttons.length; i++) {
buttons[i].addEventListener("click", createRipple);
};
let circle = document.createElement("div");
function createRipple(e) {
this.appendChild(circle);
var d = Math.max(this.scrollWidth, this.scrollHeight);
circle.style.width = circle.style.height = d + "px";
circle.style.left = e.clientX - this.offsetLeft - d / 2 + "px";
circle.style.top = e.clientY - this.offsetTop - d / 2 + "px";
circle.classList.add("ripple");
// setTimeout(function(){
// for (let i = 0; i < circle.length; i++)
// document.getElementsByClassName("ripple")[i].remove();
// }, animationTime);
}
button {
background-color: #4888f1;
border-radius: 24px;
display: flex;
align-items: center;
outline: 0;
border: 0;
padding: 10px 22px;
cursor: pointer;
overflow: hidden;
position: relative;
}
button .ripple {
position: absolute;
border-radius: 50%;
background-color: rgba(255, 255, 255, 0.5);
transform: scale(0);
animation: ripple 0.5s linear;
font-size: 0;
line-height: 0;
}
#keyframes ripple {
to {
transform: scale(2.5);
opacity: 0;
}
}
button img {
width: 20px;
height: 20px;
}
button *:not(:last-child) {
margin: 0 8px 0 0;
}
button span:first-child {
color: #fff;
font-family: Futura;
margin:0;
}
#media screen and (min-width: 1280px) {
button {
padding: 0.8vw 1.75vw;
border-radius: 1.9vw;
} button img {
width: 1.55vw;
height: auto;
} button span {
font-size: 0.8vw;
}
}
<html>
<head>
<title>Material Design Components</title>
<link rel="stylesheet" href="style.css">
</head>
<button>
<span>Add to Cart</span>
</button>
<script src="js.js"></script>
</html>

Fit colliding elements in the container dynamically

I have absolutely positioned elements with different position.top and height generated from database.
All I'm trying to do is to un-collide these elements by shifting them to the right while adjusting width to fit inside the <body> container.
I'm having an issue applying 'left' position to the collided elements.
I use https://sourceforge.net/projects/jquerycollision/ to detect collision.
Here is how the final picture should look:
$('div').each(function() {
var name = $(this).text();
var hits = $(this).collision('div').not(this); // Find colliding elements
console.log(name + ' collides with: ' + hits.length + ' others');
if (hits.length > 0) {
var widthAll = 100 / (hits.length + 1);
// Shift colliding elements to the right with equal width
$(hits).add(this).each(function(i) {
var name = $(this).text();
$(this).css({ 'left': widthAll * i + '%', 'width': widthAll + '%' });
});
}
});
div {
position: absolute;
width: 10em;
font-size: 0.75em;
color: white;
}
.blue {
top: 0;
height: 80%;
background-color: blue;
}
.red {
top: 15%;
height: 5%;
background-color: red;
}
.yellow {
top: 17%;
height: 10%;
background-color: yellow;
color: black;
}
.green {
top: 30%;
height: 5%;
background-color: green;
}
.magenta {
top: 36%;
height: 3%;
background-color: magenta;
}
.cyan {
top: 50%;
height: 5%;
background-color: cyan;
color: black;
}
.brown {
top: 81%;
height: 5%;
background-color: brown;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://rawgit.com/dsbaars/jquery-collision/master/js/jquery-collision.min.js"></script>
<div class='blue'>blue</div>
<div class='red'>red</div>
<div class='yellow'>yellow</div>
<div class='green'>green</div>
<div class='magenta'>magenta</div>
<div class='cyan'>cyan</div>
<div class='brown'>brown</div>
I think I have completed your code as you have requested. The idea is,
First block of code shifts the divs to the right so that they don't overlap.
Second block makes the width of the divs evenly distributed according to size of the body.
Last block increases the width of rest of the divs to take remaining space.
"use strict";
var divs = $('div'),
mx = 0,
mxs = [0],
bw = $("body").outerWidth(),
steps = 1;
divs.each(function(i) {
for (var j = i + 1; j < divs.length; j++) {
if (!$(this).data("x")) $(this).data("x", 0);
if (j < divs.length) {
var hit = $(this).collision(divs[j]);
if (hit.length) {
hit = $(divs[j]);
hit.css("left", "+=" + Math.ceil($(this).outerWidth()));
hit.data("x", hit.position().left);
if (mx < hit.data("x")) {
mxs.push(mx = hit.data("x"));
steps++;
}
}
}
}
});
divs.each(function(i) {
let iw = $(this).outerWidth(),
fw = bw / steps;
$(this).outerWidth(fw);
for (var j = i + 1; j < divs.length; j++) {
$(this).collision(divs[j]).css("left", "+=" + Math.ceil((fw - iw) * mxs.indexOf($(divs[j]).data("x"))));
}
});
divs.each(function() {
var os = $(this).outerWidth(),
ts = bw - $(this).position().left;
$(this).outerWidth(ts);
if ($(this).collision(divs).not(this).length) {
$(this).outerWidth(os);
}
});
body {
margin: 0;
}
div {
position: absolute;
width: 10em;
font-size: 0.75em;
color: white;
left: 0;
}
.blue {
top: 0;
height: 80%;
background-color: blue;
}
.red {
top: 15%;
height: 5%;
background-color: red;
}
.yellow {
top: 17%;
height: 10%;
background-color: yellow;
color: black;
}
.green {
top: 20%;
height: 50%;
background-color: green;
}
.magenta {
top: 36%;
height: 3%;
background-color: magenta;
}
.cyan {
top: 50%;
height: 5%;
background-color: cyan;
color: black;
}
.brown {
top: 81%;
height: 5%;
background-color: brown;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://rawgit.com/dsbaars/jquery-collision/master/js/jquery-collision.min.js"></script>
<div class='blue'>blue</div>
<div class='red'>red</div>
<div class='yellow'>yellow</div>
<div class='green'>green</div>
<div class='magenta'>magenta</div>
<div class='cyan'>cyan</div>
<div class='brown'>brown</div>
Above snippet is non-responsive. If you wish it to be responsive, then simply listen to resize event, change the value of bw and repeat code blocks 2 and 3.
As mentioned in the comments: jquery-collision.min.js had some unressolved bugs so, as suggested by Alex G, https://www.48design.de/de/news/2009/11/20/kollisionsabfrage-per-jquery-plugin-update-v11/ may be an alternative.

Positioning this element to the center of the page - CSS

I've been battling this for quite some time and I'm not having much luck, it always gets repositioned all over the place!
I essentially want my control to center this component in the middle of the page. I also want to rotate flip it(3d) around it's center axis(Y or X, doesn't matter) but I'm having no luck with the first step which is just getting it to the center.
<div className="note-container">
<div className="note"
style={Object.assign({}, note.position) }>
<p>{note.text}</p>
<span>
<button onClick={() => onExpand(note.id) }
className="btn btn-warning glyphicon glyphicon-resize-full"/>
<button onClick={() => onEdit(note.id) }
className="btn btn-primary glyphicon glyphicon-pencil"/>
<button onClick={onRemove}
className="btn btn-danger glyphicon glyphicon-trash"/>
</span>
</div>
</div>
The function I'm calling to reposition it to the center is function onExpand(noteId){...}
Here is the CSS for .note-container and .note
div.note-container {
position: fixed;
top: 5%;
left: 90%;
}
div.note {
height: 150px;
width: 150px;
background-color: yellow;
margin: 2px 0;
position: relative;
cursor: -webkit-grab;
-webkit-box-shadow: 5px 5px 15px 0 rgba(0, 0, 0, .2);
box-shadow: 5px 5px 15px 0 rgba(0, 0, 0, .2);
}
div.note:active {
cursor: -webkit-grabbing;
}
div.note p {
font-size: 22px;
padding: 5px;
font-family: "Shadows Into Light", Arial;
}
div.note div.back p {
font-size: 30px;
padding: 5px;
font-family: "Shadows Into Light", Arial;
}
div.note:hover> span {
opacity: 1;
}
div.note> span {
position: absolute;
bottom: 2px;
right: 2px;
opacity: 0;
transition: opacity .25s linear;
}
div.note button {
margin: 2px;
}
div.note> textarea {
height: 75%;
background: rgba(255, 255, 255, .5);
}
And here is the onExpand function
onExpand(noteId) {
//This needs a lot of work....
event.preventDefault();
let flippedNote = this.props.notes
.filter(note => note.id === noteId)[0];
flippedNote.position.transition = "1.0s";
flippedNote.position.transformStyle = "preserve-3d";
flippedNote.position.backgroundColor = "#3498db";
flippedNote.position.color = "white";
flippedNote.position.width = "300px";
flippedNote.position.height = "300px";
flippedNote.position.position = "absolute";
flippedNote.position.right = `50% -${flippedNote.position.width / 2}px`;
flippedNote.position.top = `50% -${flippedNote.position.height / 2}px`;
// flippedNote.position.transform = "translate(-50%, -50%) rotateY(180deg)";
this.setState({/*Stuff later... */});
}
Also when I render the note on the page I assign it a random location on the page based on this logic(this is what is initially passed into the style attribute in the div.note element:
position: {
right: randomBetween(0, window.innerWidth - 150) + "px",
top: randomBetween(0, window.innerHeight - 150) + "px",
transform: "rotate(" + randomBetween(-15, 15) + "deg)"
}
Here is what the html on the page looks like(note I am also dragging the sticky note across the page using transform: translate(...).
try this:
div.note
{
position: relative;
width: 150px;
left: 0;
right: 0;
margin: 2px auto;
}
To control the position, you can set position: relative; or position: absolute; on your div.note.
Alternatively, this can be done by manipulating margins, but it's not really a good way.
You can test your code manually by opening the page in browser and manipulating CSS values through Chrome's developer tools.
Here is the final solution after working on it this weekend:
onExpand(noteId, currentNotePosition) {
event.preventDefault();
let note = this.props.notes
.filter(specificNote => specificNote.id === noteId)[0];
const centerOfWindow = {
left: window.innerWidth / 2,
top: window.innerHeight / 2
};
if (!note.centered) {
note.position.transition = "all 1s";
note.position.transformStyle = "preserve-3d";
note.position.backgroundColor = "#3498db";
note.position.color = "white";
note.position.width = "300px";
note.position.height = "300px";
note.position.zIndex = "100";
note.position.position = "relative";
const offset = {
x: 150,
y: 150
};
const translatedCoordinates = this.getCoordinateTarget(centerOfWindow, offset, currentNotePosition);
note.position.transform = `translate(${translatedCoordinates.x}px, ${translatedCoordinates.y}px) rotateY(180deg)`;
note.originalPosition = {
left: currentNotePosition.left,
top: currentNotePosition.top,
width: currentNotePosition.width,
movement: translatedCoordinates
};
note.centered = true;
} else {
note.position.backgroundColor = "yellow";
note.position.color = "black";
note.position.width = "150px";
note.position.height = "150px";
note.position.transform = "";
note.centered = false;
}
this.props.stickyNoteActions.repositionedNoteSuccess(Object.assign({}, note));
}

Javascript animation is not running

I'm trying to create an animated menu that slides up and down. Unfortunately it's not working. I've checked the error console and there are no syntax errors. Here's my Javascript:
function showLayer() {
var hiddenLayer = document.getElementById("mainmenu");
var layerPosition = parseInt(hiddenLayer.style.bottom);
if (layerPosition > 700) {
hiddenLayer.style.bottom = (layerPosition + 5) + "px";
setTimeout("showLayer()", 20);
}
}
function hideLayer() {
var hiddenLayer = document.getElementByID("mainmenu");
hiddenLayer.style.bottom = "700px";
}
Here's the whole context:
<script type="text/javascript">
function showLayer() {
var hiddenLayer = document.getElementById("mainmenu");
var layerPosition = parseInt(hiddenLayer.style.bottom);
if (layerPosition > 700) {
hiddenLayer.style.bottom = (layerPosition + 5) + "px";
setTimeout("showLayer()", 20);
}
}
function hideLayer() {
var hiddenLayer = document.getElementByID("mainmenu");
hiddenLayer.style.bottom = "700px";
}
</script>
<style type="text/css">
div#mainmenu { position: absolute; bottom: 700px; left: 9px; width: 600px;
height: 350px; border-style: solid; background-color: rgb(0, 0, 0) ; border-
width: 3px; border-top-right-radius: 7px; border-top-left-radius: 7px; }
div#mainbutton { position: absolute; top: 674px; left: 12px; width: 28px;
height: 28px; border-style: solid; border-color: rgb(255, 255, 255); border-width:
1px; border-radius: 4px; }
div#mainbuttontext { position: absolute; top: 679px; left: 22px; color: rgb(255, 255,
255); font-style: normal; font-size: 18px; font-family:"Arial"; }
</style>
<div id="mainbutton"></div>
<div id="mainmenu" onClick="showLayer('mainmenu')"> </div>
<div id="mainbuttontext">F</div>
</body>
I think I found your problem! It's something very strange and I can't explain it, but to get style in javascript, the css must be inline (to set a style it's not necessary).
So I modified your code by placing the css inline.
HTML :
<div id="mainmenu" style="position:absolute;bottom:100px;" onclick="showLayer('mainmenu');">Click me!</div>
<!--I wrote 100px just for the test, you can change it and modify the js-->
JS :
function showLayer()
{
var hiddenLayer=document.getElementById("mainmenu");
var layerPosition=parseInt(hiddenLayer.style.bottom);
if(layerPosition>50)
{
hiddenLayer.style.bottom=(layerPosition+5)+"px";
setTimeout("showLayer()",20);
}
}
function hideLayer()
{
var hiddenLayer=document.getElementById("mainmenu");
hiddenLayer.style.bottom="700px";
}
Fiddle : http://jsfiddle.net/8MWfV/
And here is a fiddle that shows that a not inline css doesn't works : http://jsfiddle.net/kfUrP/

Categories

Resources