Hello I don't really understand javascript well because I only use python typically. and I'm doing this javascript project and I want to make it where the input is not dragging and instead it is left and right.
So like when you move the lock all your have to do is press the arrow keys. Any help would greatly be very very nice.
JS
// make dial draggable
Draggable.create(".dial", {
type:"rotation",
throwProps:true
});
// values 40 or above will be set to 0
const combo = [20, 5, 30],
findCombo = function(comboArr){
let dial = $(".dial"),
dialTrans = dial.css("transform"),
ticks = 40,
tickAngle = 360 / ticks,
numOffset = 0.5, // how far red arrow can be from number
// break down matrix value of dial transform and get angle
matrixVal = dialTrans.split('(')[1].split(')')[0].split(','),
cos1 = matrixVal[0],
sin = matrixVal[1],
negSin = matrixVal[2],
cos2 = matrixVal[3],
angle = Math.round(Math.atan2(sin, cos1) * (180 / Math.PI)) * -1;
// convert negative angles to positive
if (angle < 0) {
angle += 360;
}
// check numbers found, stop loop if at first number not found
for (let i = 0; i < comboArr.length; ++i) {
if (!$(".num" + (i + 1)).hasClass("found")) {
if (angle > (comboArr[i] - numOffset) * tickAngle &&
angle < (comboArr[i] + numOffset) * tickAngle) {
// make numbers green when found
$(".num" + (i + 1)).addClass("found");
// on unlock
if (i == comboArr.length - 1) {
$(".shackle").addClass("unlocked");
$(".top").addClass("pivot1");
$(".inner").addClass("pivot2");
$(".left").addClass("moveRight");
$(".dentL, .dentR").addClass("moveLeft");
// then lock again
setTimeout(function() {
$(".shackle").removeClass("unlocked");
$(".top").removeClass("pivot1");
$(".inner").removeClass("pivot2");
$(".left").removeClass("moveRight");
$(".dentL, .dentR").removeClass("moveLeft");
$("body").attr("style","background: black;");
$(".sitelocker").attr("style","display:none;");
$(".mainsitebody").removeAttr("style");
for (let j = 0; j < combo.length; ++j) {
$(".num" + (j + 1)).removeClass("found");
}
}, 2400);
}
}
break;
}
}
};
// dial interaction (mouse)
$(".dial").on("click",function(){
findCombo(combo);
});
// dial interaction (touch)
$(".dial").on("touchend",function(){
findCombo(combo);
});
CSS
.sitelocker {
counter-reset: inc -5;
font-family: Open Sans, sans-serif;
display: flex;
display: -webkit-flex;
flex-direction: column;
-webkit-flex-direction: column;
justify-content: center;
-webkit-justify-content: center;
align-items: center;
-webkit-align-items: center;
height: 100vh;
overflow: hidden;
}
.container {
margin-bottom: 18px;
position: relative;
height: 270px;
width: 180px;
}
.lock, .dial {
border-radius: 50%;
}
.arrow, .dial {
margin: auto;
}
.shackle, .dial, .tick {
position: absolute;
}
.lock {
background: #aaa;
position: absolute;
bottom: 0;
height: 180px;
width: 180px;
}
.shackle {
bottom: 108px;
right: 22.5px;
width: 135px;
height: 168.75px;
will-change: transform;
z-index: -1;
}
.shackle div {
background: #999999;
position: absolute;
will-change: transform;
}
.shackle .top {
border-radius: 135px 135px 0 0;
height: 67.5px;
width: 135px;
transform-origin: 100% 0;
}
.shackle .inner {
background: #fff;
border-radius: 50%;
top: 33.75px;
left: 33.75px;
height: 67.5px;
width: 67.5px;
}
.shackle .left, .shackle .right {
top: 66.5px;
width: 33.75px;
}
.shackle .left {
border-radius: 0 0 6.75px 6.75px;
height: 94.5px;
overflow: hidden;
position: relative;
}
.shackle .left .dentL, .shackle .left .dentR {
position: absolute;
bottom: 16.875px;
z-index: 2;
}
.shackle .left .dentL {
border-top: 15px solid transparent;
border-bottom: 5px solid transparent;
border-left: 15px solid #fff;
left: -30px;
}
.shackle .left .dentR {
border-top: 15px solid transparent;
border-bottom: 5px solid transparent;
border-right: 15px solid #fff;
right: 0;
}
.shackle .right {
right: 0;
height: 135px;
}
.arrow {
border: 7.5px solid transparent;
border-color: #a00 transparent transparent transparent;
margin-top: 11.25px;
margin-bottom: 3px;
transform: translateY(7.5px);
height: 0;
width: 0;
}
.dial {
background: #333 radial-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, 0) 30px, #1a1a1a 30px, #1a1a1a 32.25px, rgba(0, 0, 0, 0) 32.25px, rgba(0, 0, 0, 0));
font-family: Helvetica, sans-serif;
left: 0;
right: 0;
bottom: 7.2px;
position: absolute;
height: 144px;
width: 144px;
transform: rotate(0deg);
will-change: transform;
z-index: 1;
}
.tick {
background: #fff;
color: #fff;
font-size: 15px;
top: 72px;
left: 70.5px;
width: 3px;
height: 9px;
transform-origin: 50% -63px;
}
.tick::before {
display: block;
margin: -18px -18px 0 -18px;
text-align: center;
transform: rotate(180deg);
}
.tick:nth-of-type(1) {
transform: translateY(63px) rotate(180deg);
height: 18px;
transform-origin: 50% -54px;
transform: translateY(54px) rotate(180deg);
}
.tick:nth-of-type(1)::before {
counter-increment: inc 5;
content: counter(inc);
}
.tick:nth-of-type(2) {
transform: translateY(63px) rotate(189deg);
}
.tick:nth-of-type(3) {
transform: translateY(63px) rotate(198deg);
}
.tick:nth-of-type(4) {
transform: translateY(63px) rotate(207deg);
}
.tick:nth-of-type(5) {
transform: translateY(63px) rotate(216deg);
}
.tick:nth-of-type(6) {
transform: translateY(63px) rotate(225deg);
height: 18px;
transform-origin: 50% -54px;
transform: translateY(54px) rotate(225deg);
}
.tick:nth-of-type(6)::before {
counter-increment: inc 5;
content: counter(inc);
}
.tick:nth-of-type(7) {
transform: translateY(63px) rotate(234deg);
}
.tick:nth-of-type(8) {
transform: translateY(63px) rotate(243deg);
}
.tick:nth-of-type(9) {
transform: translateY(63px) rotate(252deg);
}
.tick:nth-of-type(10) {
transform: translateY(63px) rotate(261deg);
}
.tick:nth-of-type(11) {
transform: translateY(63px) rotate(270deg);
height: 18px;
transform-origin: 50% -54px;
transform: translateY(54px) rotate(270deg);
}
.tick:nth-of-type(11)::before {
counter-increment: inc 5;
content: counter(inc);
}
.tick:nth-of-type(12) {
transform: translateY(63px) rotate(279deg);
}
.tick:nth-of-type(13) {
transform: translateY(63px) rotate(288deg);
}
.tick:nth-of-type(14) {
transform: translateY(63px) rotate(297deg);
}
.tick:nth-of-type(15) {
transform: translateY(63px) rotate(306deg);
}
.tick:nth-of-type(16) {
transform: translateY(63px) rotate(315deg);
height: 18px;
transform-origin: 50% -54px;
transform: translateY(54px) rotate(315deg);
}
.tick:nth-of-type(16)::before {
counter-increment: inc 5;
content: counter(inc);
}
.tick:nth-of-type(17) {
transform: translateY(63px) rotate(324deg);
}
.tick:nth-of-type(18) {
transform: translateY(63px) rotate(333deg);
}
.tick:nth-of-type(19) {
transform: translateY(63px) rotate(342deg);
}
.tick:nth-of-type(20) {
transform: translateY(63px) rotate(351deg);
}
.tick:nth-of-type(21) {
transform: translateY(63px) rotate(360deg);
height: 18px;
transform-origin: 50% -54px;
transform: translateY(54px) rotate(360deg);
}
.tick:nth-of-type(21)::before {
counter-increment: inc 5;
content: counter(inc);
}
.tick:nth-of-type(22) {
transform: translateY(63px) rotate(369deg);
}
.tick:nth-of-type(23) {
transform: translateY(63px) rotate(378deg);
}
.tick:nth-of-type(24) {
transform: translateY(63px) rotate(387deg);
}
.tick:nth-of-type(25) {
transform: translateY(63px) rotate(396deg);
}
.tick:nth-of-type(26) {
transform: translateY(63px) rotate(405deg);
height: 18px;
transform-origin: 50% -54px;
transform: translateY(54px) rotate(405deg);
}
.tick:nth-of-type(26)::before {
counter-increment: inc 5;
content: counter(inc);
}
.tick:nth-of-type(27) {
transform: translateY(63px) rotate(414deg);
}
.tick:nth-of-type(28) {
transform: translateY(63px) rotate(423deg);
}
.tick:nth-of-type(29) {
transform: translateY(63px) rotate(432deg);
}
.tick:nth-of-type(30) {
transform: translateY(63px) rotate(441deg);
}
.tick:nth-of-type(31) {
transform: translateY(63px) rotate(450deg);
height: 18px;
transform-origin: 50% -54px;
transform: translateY(54px) rotate(450deg);
}
.tick:nth-of-type(31)::before {
counter-increment: inc 5;
content: counter(inc);
}
.tick:nth-of-type(32) {
transform: translateY(63px) rotate(459deg);
}
.tick:nth-of-type(33) {
transform: translateY(63px) rotate(468deg);
}
.tick:nth-of-type(34) {
transform: translateY(63px) rotate(477deg);
}
.tick:nth-of-type(35) {
transform: translateY(63px) rotate(486deg);
}
.tick:nth-of-type(36) {
transform: translateY(63px) rotate(495deg);
height: 18px;
transform-origin: 50% -54px;
transform: translateY(54px) rotate(495deg);
}
.tick:nth-of-type(36)::before {
counter-increment: inc 5;
content: counter(inc);
}
.tick:nth-of-type(37) {
transform: translateY(63px) rotate(504deg);
}
.tick:nth-of-type(38) {
transform: translateY(63px) rotate(513deg);
}
.tick:nth-of-type(39) {
transform: translateY(63px) rotate(522deg);
}
.tick:nth-of-type(40) {
transform: translateY(63px) rotate(531deg);
}
.combo {
font-size: 22.5px;
text-align: center;
display: none;
}
.combo span {
background: #ccc;
display: inline-block;
line-height: 30px;
padding: 7.5px;
width: 30px;
height: 30px;
vertical-align: middle;
}
.combo span.found {
background: #ccc;
color: #fff;
}
/* Animation classes */
.unlocked {
animation: moveUp 0.2s linear forwards, moveUp 0.2s 2s linear reverse forwards;
}
.moveLeft {
animation: moveLeft 0.5s 0.4s linear forwards, moveLeft 0.5s 1.2s linear reverse forwards;
}
.moveRight {
animation: moveRight 0.5s 0.4s linear forwards, moveRight 0.5s 1.2s linear reverse forwards;
}
.pivot1 {
animation: pivot1 0.5s 0.4s linear forwards, pivot1 0.5s 1.2s linear reverse forwards;
}
.pivot2 {
animation: pivot2-1 0.25s 0.4s cubic-bezier(0.6, 0.3, 0.45, 1) forwards, pivot2-2 0.25s 0.65s cubic-bezier(0.2, 0, 0.63, 0.5) forwards, pivot2-2 0.25s 1.3s cubic-bezier(0.2, 0, 0.63, 0.5) reverse forwards, pivot2-1 0.25s 1.45s cubic-bezier(0.6, 0.3, 0.45, 1) reverse forwards;
}
#keyFrames moveUp {
from {
transform: translateY(0);
}
to {
transform: translateY(-63px);
}
}
#keyframes moveLeft {
from {
transform: translateX(0);
}
to {
transform: translateX(30px);
}
}
#keyframes moveRight {
from {
transform: translateX(0);
}
to {
transform: translateX(202.5px);
}
}
#keyframes pivot1 {
from {
transform: scale(1, 1);
right: 0;
}
50% {
transform: scale(0.25, 1) rotateY(0);
right: 0;
}
50.01% {
transform: scale(0.25, 1) rotateY(180deg);
right: 33.75px;
}
to {
transform: scale(1, 1) rotateY(180deg);
right: 33.75px;
}
}
#keyframes pivot2-1 {
from {
transform: scale(1, 1);
}
to {
transform: scale(0, 1);
}
}
#keyframes pivot2-2 {
from {
transform: scale(0, 1);
}
to {
transform: scale(1, 1);
}
}
:root{
--text-color: #003cff;
--streak-color: #ff0000;
--font-family: "Gidugu";
}
h1, p, span {
color: transparent;
font-weight: 400;
font-size: 6rem;
}
h1 {
display: block;
height: 50vh;
background: #000;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
}
p, span {
display: inline-block;
}
p {
padding-left: 1rem;
font-size: 6rem;
text-shadow: 0 0 221px transparent;
-webkit-animation: showText 1s 1.5s 1 forwards ease-out;
animation: showText 1s 1.5s 1 forwards ease-out;
position: relative;
font-family: var(--fontstyle), cursive;
}
p:after {
content: "";
width: 30px;
background: var(--text-color);
height: 30px;
position: absolute;
top: 0px;
left: 200px;
border-radius: 100%;
-webkit-transform-origin: center center;
transform-origin: center center;
box-shadow: 0 0 0px 103px var(--text-color);
box-sizing: border-box;
-webkit-transform: scale(0);
transform: scale(0);
-webkit-animation: scaleBounce .3s 2s 1 linear forwards;
animation: scaleBounce .3s 2s 1 linear forwards;
}
span {
text-shadow: -48px -203px 150px var(--text-color), 132px -203px 150px var(--text-color);
-webkit-animation: enterFromTop 1s ease-in 1 forwards, moveLetters .6s 2s alternate infinite ease-out;
animation: enterFromTop 1s ease-in 1 forwards, moveLetters .6s 2s alternate infinite ease-out;
font-family: var(--fontstyle), cursive;
}
span:first-child {
-webkit-animation-delay: -.3s;
animation-delay: -.3s;
}
span:nth-child(2) {
-webkit-animation-delay: .4s;
animation-delay: .4s;
}
span:nth-child(3) {
-webkit-animation-delay: .7s;
animation-delay: .7s;
}
h1:after {
content: "";
display: block;
width: 200px;
height: 4px;
position: absolute;
left: 50%;
margin-left: -300px;
margin-top: 60px;
border-radius: 100%;
background: var(--streak-color);
box-shadow: 32px 5px 0 var(--streak-color);
-webkit-animation: moveShadow 1s ease-in-out infinite alternate, moveElement 1s 2.5s ease-in infinite;
animation: moveShadow 1s ease-in-out infinite alternate, moveElement 1s 2.5s ease-in infinite;
opacity: 0;
-webkit-transform: translateX(-50px);
transform: translateX(-50px);
}
#-webkit-keyframes scaleBounce {
100% {
-webkit-transform: scale(1);
transform: scale(1);
opacity: 0.3;
background: transparent;
box-shadow: 0 0 20px 103px transparent;
}
}
#keyframes scaleBounce {
100% {
-webkit-transform: scale(1);
transform: scale(1);
opacity: 0.3;
background: transparent;
box-shadow: 0 0 20px 103px transparent;
}
}
#-webkit-keyframes moveLetters {
0% {
-webkit-transform: translateY(0);
transform: translateY(0);
}
100% {
-webkit-transform: translateY(-40px);
transform: translateY(-40px);
}
}
#keyframes moveLetters {
0% {
-webkit-transform: translateY(0);
transform: translateY(0);
}
100% {
-webkit-transform: translateY(-40px);
transform: translateY(-40px);
}
}
#-webkit-keyframes moveElement {
30%, 50% {
opacity: 1;
}
80% {
opacity: 0;
}
100% {
-webkit-transform: translateX(690px);
transform: translateX(690px);
opacity: 0;
}
}
#keyframes moveElement {
30%, 50% {
opacity: 1;
}
80% {
opacity: 0;
}
100% {
-webkit-transform: translateX(690px);
transform: translateX(690px);
opacity: 0;
}
}
#-webkit-keyframes moveShadow {
100% {
box-shadow: -32px 5px 0 var(--streak-color);
}
}
#keyframes moveShadow {
100% {
box-shadow: -32px 5px 0 var(--streak-color);
}
}
#-webkit-keyframes enterFromTop {
100% {
text-shadow: 0 0 1px var(--text-color), 0 0 1px var(--text-color);
}
}
#keyframes enterFromTop {
100% {
text-shadow: 0 0 1px var(--text-color), 0 0 1px var(--text-color);
}
}
#-webkit-keyframes showText {
80% {
text-shadow: 0 0 1px var(--text-color);
}
100% {
text-shadow: 0 0 1px var(--text-color), 0 0 20px var(--text-color);
}
}
#keyframes showText {
80% {
text-shadow: 0 0 1px var(--text-color);
}
100% {
text-shadow: 0 0 1px var(--text-color), 0 0 20px var(--text-color);
}
}
HTML
<html >
<head>
<meta charset="UTF-8">
<title>Combination Lock</title>
<link href="https://fonts.googleapis.com/css?family=Kaushan+Script|Satisfy" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css">
<link rel="icon" type="image/png" href="https://beam.pro/_latest/assets/favicons/favicon-32x32.png" sizes="32x32">
<link rel="icon" type="image/png" href="https://beam.pro/_latest/assets/favicons/favicon-16x16.png" sizes="16x16">
<link rel="stylesheet" href="css/sitelocker.css">
<link rel="stylesheet" href="css/mainsite.css">
</head>
<body>
<div class="sitelocker">
<div class="container">
<div class="lock">
<div class="shackle">
<div class="top">
<div class="inner"></div>
</div>
<div class="left">
<div class="dentL"></div>
<div class="dentR"></div>
</div>
<div class="right"></div>
</div>
<div class="arrow"></div>
</div>
<div class="dial">
<div class="tick"></div>
<div class="tick"></div>
<div class="tick"></div>
<div class="tick"></div>
<div class="tick"></div>
<div class="tick"></div>
<div class="tick"></div>
<div class="tick"></div>
<div class="tick"></div>
<div class="tick"></div>
<div class="tick"></div>
<div class="tick"></div>
<div class="tick"></div>
<div class="tick"></div>
<div class="tick"></div>
<div class="tick"></div>
<div class="tick"></div>
<div class="tick"></div>
<div class="tick"></div>
<div class="tick"></div>
<div class="tick"></div>
<div class="tick"></div>
<div class="tick"></div>
<div class="tick"></div>
<div class="tick"></div>
<div class="tick"></div>
<div class="tick"></div>
<div class="tick"></div>
<div class="tick"></div>
<div class="tick"></div>
<div class="tick"></div>
<div class="tick"></div>
<div class="tick"></div>
<div class="tick"></div>
<div class="tick"></div>
<div class="tick"></div>
<div class="tick"></div>
<div class="tick"></div>
<div class="tick"></div>
<div class="tick"></div>
</div>
</div>
<div class="combo"><span class="num1"></span> <span class="num2"></span> <span class="num3"></span>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.11.5/TweenMax.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.11.5/utils/Draggable.min.js"></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/gsap/1.11.5/utils/Draggable.min.js'></script>
<script src="js/sitelocker.js"></script>
</div>
<div class="mainsitebody" style="display:none;">
<h1>
<span>MSFT</span><span>.</span>
<p>online</p>
</h1>
</div>
</body>
</html>
I made a HTML cube and animated its rotation after clicking on it. The cube rotates 90 degrees each time you click on it. I have an animation that makes 360 degrees.It pauses after 1/4 of animation total duration and runs again after click. That way we can see each of side faces in turn - 1,2,3,4.
But after about 10 clicks it is clear that angle is more than 90 but and view is not isometric anymore.
How to make this cube turn exactly 90 degrees and look right?
Probably it is not good to rely on duration. It could be easier if browser could watch angle and pause animation-play-state on 90, 180, 270, 360 degrees
var spinner = document.getElementById('spinner');
// get animation duration in ms
var animationDuration = parseFloat(window.getComputedStyle(spinner)['animation-duration'])*1000;
spinner.addEventListener('click', function () {
// run animation
spinner.style['animation-play-state'] = 'running';
// pause animation after animationDuration / 4
setTimeout(function () {
spinner.style['animation-play-state'] = 'paused';
}, animationDuration / 4);
});
body {
-webkit-font-smoothing: antialiased;
margin: 0;
}
* {
box-sizing: border-box;
}
.container {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: 100px;
color: black;
}
.scene {
position: relative;
width: 120px;
height: 120px;
transform-style: preserve-3d;
transform: rotatex(-33.5deg) rotatey(45deg);
}
.face {
position: absolute;
width: 100%;
height: 100%;
text-align: center;
font-size: 100px;
background: rgba(141, 148, 249, 0.5);
line-height: 100px;
border: 2px solid white;
}
.face-front {
transform: rotateY(360deg) translateZ(60px);
}
.face-right {
transform: rotateY(90deg) translatez(60px);
}
.face-back {
transform: rotateY(180deg) translatez(60px);
}
.face-left {
transform: rotateY(270deg) translateZ(60px);
}
.face-top {
transform: rotatex(90deg) translatez(60px);
}
.face-bottom {
transform: rotatex(-90deg) translatez(60px);
}
#spinner {
position: absolute;
display: inline-block;
width: 120px;
height: 120px;
left: 0;
top: 0;
transform-style: preserve-3d;
animation-name: spinner;
animation-timing-function: linear;
animation-iteration-count: infinite;
animation-duration: 4s;
animation-play-state: paused;
transform-style: preserve-3d;
}
#keyframes spinner {
from {
transform: rotateY(0deg);
}
to {
transform: rotateY(-360deg);
}
}
<!DOCTYPE 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.0" />
<title>Document</title>
</head>
<body>
<div class="container">
<div class="scene">
<div id="spinner">
<div class="face face-left">1</div>
<div class="face face-front">2</div>
<div class="face face-right">3</div>
<div class="face face-back">4</div>
<div class="face face-top">5</div>
<div class="face face-bottom">6</div>
</div>
</div>
</div>
</body>
</html>
Using the duration isn't recommended as you stated.
One other way is to use the transform css style, and add 90 degrees to it on each click:
Then we only need one more CSS rule to add some 'animation' to the transform:
transition: transform 1s ease;
var spinner = document.getElementById('spinner');
var scene = document.getElementsByClassName('scene')[0];
let currentRotation = 45;
spinner.addEventListener('click', function () {
currentRotation += 90; // Or change to -= to go clockwise
scene.style['transform'] = `rotatex(-33.5deg) rotatey(${currentRotation}deg)`;
});
body {
-webkit-font-smoothing: antialiased;
margin: 0;
}
* {
box-sizing: border-box;
}
.container {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: 100px;
color: black;
}
.scene {
position: relative;
width: 120px;
height: 120px;
transform-style: preserve-3d;
transform: rotatex(-33.5deg) rotatey(45deg);
transition: transform 1s ease;
}
.face {
position: absolute;
width: 100%;
height: 100%;
text-align: center;
font-size: 100px;
background: rgba(141, 148, 249, 0.5);
line-height: 100px;
border: 2px solid white;
}
.face-front {
transform: rotateY(360deg) translateZ(60px);
}
.face-right {
transform: rotateY(90deg) translatez(60px);
}
.face-back {
transform: rotateY(180deg) translatez(60px);
}
.face-left {
transform: rotateY(270deg) translateZ(60px);
}
.face-top {
transform: rotatex(90deg) translatez(60px);
}
.face-bottom {
transform: rotatex(-90deg) translatez(60px);
}
#spinner {
position: absolute;
display: inline-block;
width: 120px;
height: 120px;
left: 0;
top: 0;
transform-style: preserve-3d;
animation-name: spinner;
animation-timing-function: linear;
animation-iteration-count: infinite;
animation-duration: 4s;
animation-play-state: paused;
transform-style: preserve-3d;
}
#keyframes spinner {
from {
transform: rotateY(0deg);
}
to {
transform: rotateY(-360deg);
}
}
<div class="container">
<div class="scene">
<div id="spinner">
<div class="face face-left">1</div>
<div class="face face-front">2</div>
<div class="face face-right">3</div>
<div class="face face-back">4</div>
<div class="face face-top">5</div>
<div class="face face-bottom">6</div>
</div>
</div>
</div>
I've set up a menu as pictured in the snippet below. I want the user to be able to hover over the central icon and then be able to select one of the buttons on the side. I've had some success by placing another, larger element in front of the icon when the icon is hovered on and then chaining some hovers together but then as soon as they hovered over a button all the other ones disappeared. I've also tried expanding the padding of the #navCont element but the buttons disappear when hovering over any of them (it also pushes all my content up if I expand the bottom area)
body {
background: #000;
flex-direction: column;
justify-content: center;
align-items: center;
}
div.main {
position: absolute;
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-50%);
display: block;
}
#title {
color: white;
width: 40%;
margin-bottom: 3vh;
}
#navCont {
position: relative;
top: 0;
}
#sqlogo {
opacity: .75;
width: 3em;
animation: pulse 1.8s cubic-bezier(.28, 0, .55, 1) 1s infinite alternate;
}
#keyframes pulse {
0% {
transform: scale(1);
}
100% {
transform: scale(1.25);
}
}
#sqlogo:hover {
opacity: 1;
animation-play-state: paused;
}
#navCont .btn {
opacity: .75;
height: 1.5em;
display: none;
position: absolute;
}
#navCont:hover img.btn {
display: block;
}
#navCont .btn:hover {
opacity: 1;
}
#navCont #btnWork {
left: 4em;
top: 50%;
transform: translateY(-50%);
}
#navCont #btnAbout {
right: 4em;
top: 50%;
transform: translateY(-50%);
}
#navCont #btnContact {
top: 4em;
left: 50%;
transform: translateX(-50%);
}
<body>
<div class="main">
<div id="title"> Title </div>
<div id="navCont">
<img id="sqlogo" src="http://drive.google.com/uc?export=view&id=1nybF_-lqMK9k0_X8EfgU8tKbiIzM459U" />
<img id="btnWork" class="btn" src="http://drive.google.com/uc?export=view&id=1o2pds3XK3Wh78pQPfC5cgsqWRHEIHy-Q" />
<img id="btnAbout" class="btn" src="http://drive.google.com/uc?export=view&id=1XGf88jotbT8n4NmBPc979gI1oYbhjgXb" />
<img id="btnContact" class="btn" src="http://drive.google.com/uc?export=view&id=1EjimLtnyIZRsfPbX3yc2wJ_s1Qxpwj45" / />
</div>
</div>
</div>
</body>
https://i.stack.imgur.com/qZDam.jpg
Ideally, I'd like the buttons to remain active while the cursor is in this area (see link above) after they have appeared via the icon, however, a rectangular area of that size would also be ok.
You could create an on hover event on your squid icon using javascript that when triggered keeps the menu content visible until a mouseout event on some larger parent area is triggered
Something like this:
document.getElementById("sqlogo").onmouseover = function(){
// show the buttons
getElementsByClassName("btn").style.display = "block"
};
document.getElementById("navCont").onmouseout = function(){
// hide the buttons
getElementsByClassName("btn").style.display = "none"
};
You might have to undo some of your CSS so that JS controls the visibility instead of CSS :hover
I found a workaround using JQuery. I just toggled the button visibility if the mouse didn't move to them fast enough after leaving the main icon
$("#sqlogo").mouseenter(function() {
$("#sqlogo").addClass("freeze");
$(".btn").addClass("vis");
});
let t;
$("#sqlogo").mouseleave(function() {
t = setTimeout(function() {
$("#sqlogo").removeClass("freeze");
$(".btn").removeClass("vis");
}, 500);
});
$(".btn").mouseenter(function() {
clearTimeout(t);
});
$(".btn").mouseleave(function() {
$("#sqlogo").removeClass("freeze");
$(".btn").removeClass("vis");
});
body {
background: #000;
flex-direction: column;
justify-content: center;
align-items: center;
}
div.main {
position: absolute;
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-50%);
display: block;
}
#title {
color: white;
width: 40%;
margin-bottom: 3vh;
}
#navCont {
position: relative;
top: 0;
}
#sqlogo {
opacity: .75;
width: 3em;
animation: pulse 1.8s cubic-bezier(.28, 0, .55, 1) 1s infinite alternate;
}
#keyframes pulse {
0% {
transform: scale(1);
}
100% {
transform: scale(1.25);
}
}
#sqlogo:hover {
opacity: 1;
}
#sqlogo.freeze {
animation-play-state: paused;
}
#navCont>.btn {
opacity: .75;
visibility: hidden;
height: 1.5em;
position: absolute;
}
#navCont>.vis {
visibility: visible;
}
#navCont>.btn:hover {
opacity: 1;
}
#navCont > #btnWork{
left: 4em;
top: 50%;
transform: translateY(-50%);
}
#navCont #btnAbout {
right: 4em;
top: 50%;
transform: translateY(-50%);
}
#navCont #btnContact {
top: 4em;
left: 50%;
transform: translateX(-50%);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body>
<div class="main">
<div id="title"> Title </div>
<div id="navCont">
<img id="sqlogo" src="http://drive.google.com/uc?export=view&id=1nybF_-lqMK9k0_X8EfgU8tKbiIzM459U" />
<img id="btnWork" class="btn" src="http://drive.google.com/uc?export=view&id=1o2pds3XK3Wh78pQPfC5cgsqWRHEIHy-Q" />
<img id="btnAbout" class="btn" src="http://drive.google.com/uc?export=view&id=1XGf88jotbT8n4NmBPc979gI1oYbhjgXb" />
<img id="btnContact" class="btn" src="http://drive.google.com/uc?export=view&id=1EjimLtnyIZRsfPbX3yc2wJ_s1Qxpwj45" / />
</div>
</div>
</div>
</body>
I found this flip animation on the internet and I was wondering: How can I change the javascript that instead of hovering over the image will cause the flip, a set time wil? So for instance after 3 seconds, the animation will start.
I am not so good with javascript yet and I am hoping someone can help me out
Thank you very much If you know the solution!
$(document).ready(function() {
$(".container").hover(function() {
$(".card").toggleClass('flipped')
}, function() {
$(".card").toggleClass('flipped')
});
})
h1 {
text-align: center;
}
.container {
width: 200px;
height: 260px;
position: relative;
margin: 0 auto 40px;
-webkit-perspective: 800px;
-moz-perspective: 800px;
-o-perspective: 800px;
perspective: 800px;
display: inline-block;
}
#main {
border: 1px solid black;
}
button {
width: 30%;
height: 10%;
margin-top: 100px;
cursor: default;
}
.card {
width: 100%;
height: 100%;
position: absolute;
-webkit-transition: -webkit-transform 1s;
-moz-transition: -moz-transform 1s;
-o-transition: -o-transform 1s;
transition: transform 1s;
-webkit-transform-style: preserve-3d;
-moz-transform-style: preserve-3d;
-o-transform-style: preserve-3d;
transform-style: preserve-3d;
-webkit-transform-origin: right center;
-moz-transform-origin: right center;
-o-transform-origin: right center;
transform-origin: right center;
}
.card.flipped {
-webkit-transform: translateX( -100%) rotateY( -180deg);
-moz-transform: translateX( -100%) rotateY( -180deg);
-o-transform: translateX( -100%) rotateY( -180deg);
transform: translateX( -100%) rotateY( -180deg);
}
.card div {
height: 100%;
width: 100%;
color: white;
text-align: center;
font-weight: bold;
position: absolute;
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
-o-backface-visibility: hidden;
backface-visibility: hidden;
cursor: pointer;
}
.card .front {
background: red;
display: flex;
justify-content: center;
align-items: center;
}
/*
.card .front p {
margin-top: 100px;
}
*/
.card .back p {
margin: auto;
}
.card .back {
background: blue;
-webkit-transform: rotateY( 180deg);
-moz-transform: rotateY( 180deg);
-o-transform: rotateY( 180deg);
transform: rotateY( 180deg);
display: flex;
justify-content: center;
align-items: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container-fluid">
<div id="main"><br>
<section class="container">
<div class="card">
<div class="front">
<p>Test</p>
</div>
<div class="back">
<p>MyBack</p>
</div>
</div>
</section>
</div>
</div>
Why not do it with CSS?
On hover pseudo class with a transition:
h1 {
text-align: center;
}
.container {
--card-transition-duration: 1s;
--card-transition-delay: 4s;
width: 200px;
height: 260px;
position: relative;
margin: 0 auto 40px;
perspective: 800px;
display: inline-block;
}
#main {
border: 1px solid black;
}
button {
width: 30%;
height: 10%;
margin-top: 100px;
cursor: default;
}
.card {
width: 100%;
height: 100%;
position: absolute;
transition: transform var(--card-transition-duration) ease var(--card-transition-delay);
transform-style: preserve-3d;
transform-origin: right center;
}
.container:hover .card {
transform: translateX( -100%) rotateY( -180deg);
}
.card div {
height: 100%;
width: 100%;
color: white;
text-align: center;
font-weight: bold;
position: absolute;
backface-visibility: hidden;
cursor: pointer;
}
.card .front {
background: red;
display: flex;
justify-content: center;
align-items: center;
}
.card .back p {
margin: auto;
}
.card .back {
background: blue;
transform: rotateY( 180deg);
display: flex;
justify-content: center;
align-items: center;
}
<div class="container-fluid">
<div id="main"><br>
<section class="container">
<div class="card">
<div class="front">
<p>Test</p>
</div>
<div class="back">
<p>MyBack</p>
</div>
</div>
</section>
</div>
</div>
Or by itself with #keyframes animation:
h1 {
text-align: center;
}
.container {
--card-transition-duration: 1s;
--card-transition-delay: 4s;
width: 200px;
height: 260px;
position: relative;
margin: 0 auto 40px;
perspective: 800px;
display: inline-block;
}
#main {
border: 1px solid black;
}
button {
width: 30%;
height: 10%;
margin-top: 100px;
cursor: default;
}
.card {
width: 100%;
height: 100%;
position: absolute;
transition: transform var(--card-transition-duration) ease var(--card-transition-delay);
transform-style: preserve-3d;
transform-origin: right center;
animation-name: flip;
animation-duration: 5s;
animation-iteration-count: infinite;
animation-direction: alternate;
}
.card div {
height: 100%;
width: 100%;
color: white;
text-align: center;
font-weight: bold;
position: absolute;
backface-visibility: hidden;
cursor: pointer;
}
.card .front {
background: red;
display: flex;
justify-content: center;
align-items: center;
}
.card .back p {
margin: auto;
}
.card .back {
background: blue;
transform: rotateY( 180deg);
display: flex;
justify-content: center;
align-items: center;
}
#keyframes flip {
0% {
transform: translateX( 0%) rotateY( 0deg);
}
35% {
transform: translateX( 0%) rotateY( 0deg);
}
65% {
transform: translateX( -100%) rotateY( -180deg);
}
100% {
transform: translateX( -100%) rotateY( -180deg);
}
}
<div class="container-fluid">
<div id="main"><br>
<section class="container">
<div class="card">
<div class="front">
<p>Test</p>
</div>
<div class="back">
<p>MyBack</p>
</div>
</div>
</section>
</div>
</div>
First, that's not justjavascript, it's jQuery. If you want the animation to start with a delay using the jquery code, you can add a setTimeout.
And if you use the callback function of the hover method, use add/remove class not toggle.
You could do it in multiple ways, even with just CSS and animations.
$(document).ready(function() {
$(".container").hover(function() {
setTimeout(() => { $(".card").addClass('flipped')},3000)
}, function() {
$(".card").removeClass('flipped')
});
})
h1 {
text-align: center;
}
.container {
width: 200px;
height: 260px;
position: relative;
margin: 0 auto 40px;
-webkit-perspective: 800px;
-moz-perspective: 800px;
-o-perspective: 800px;
perspective: 800px;
display: inline-block;
}
#main {
border: 1px solid black;
}
button {
width: 30%;
height: 10%;
margin-top: 100px;
cursor: default;
}
.card {
width: 100%;
height: 100%;
position: absolute;
-webkit-transition: -webkit-transform 1s;
-moz-transition: -moz-transform 1s;
-o-transition: -o-transform 1s;
transition: transform 1s;
-webkit-transform-style: preserve-3d;
-moz-transform-style: preserve-3d;
-o-transform-style: preserve-3d;
transform-style: preserve-3d;
-webkit-transform-origin: right center;
-moz-transform-origin: right center;
-o-transform-origin: right center;
transform-origin: right center;
}
.card.flipped {
-webkit-transform: translateX( -100%) rotateY( -180deg);
-moz-transform: translateX( -100%) rotateY( -180deg);
-o-transform: translateX( -100%) rotateY( -180deg);
transform: translateX( -100%) rotateY( -180deg);
}
.card div {
height: 100%;
width: 100%;
color: white;
text-align: center;
font-weight: bold;
position: absolute;
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
-o-backface-visibility: hidden;
backface-visibility: hidden;
cursor: pointer;
}
.card .front {
background: red;
display: flex;
justify-content: center;
align-items: center;
}
/*
.card .front p {
margin-top: 100px;
}
*/
.card .back p {
margin: auto;
}
.card .back {
background: blue;
-webkit-transform: rotateY( 180deg);
-moz-transform: rotateY( 180deg);
-o-transform: rotateY( 180deg);
transform: rotateY( 180deg);
display: flex;
justify-content: center;
align-items: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container-fluid">
<div id="main"><br>
<section class="container">
<div class="card">
<div class="front">
<p>Test</p>
</div>
<div class="back">
<p>MyBack</p>
</div>
</div>
</section>
</div>
</div>
Change the ready function to the one below.
$(document).ready(function () {
window.setInterval(function () {
$(".card").toggleClass("flipped");
}, 3000);
});
I'am trying to create an animation with a cube in CSS.
The animation is perfectly working in Chrome, but not in Firefox.
As soon as the cube goes out of the viewport, the animation freezes.
However, the animation runs if I move the mouse during the animation.
Here is the code (Note : the animation launches when face 4 is clicked):
//Retrieve elements
var leftArrow = document.getElementById("leftArrow");
var rightArrow = document.getElementById("rightArrow");
var frontFace = document.getElementById("face4");
var cube = document.getElementById("cube");
function rotateLeft()
{
cube.style.transform = "rotateY(180deg) translateX(-150px)";
cube.style.transition = 'transform 0.5s ease-out';
}
function rotateRight()
{
cube.style.transform = "rotateY(0deg) translateX(-150px)";
cube.style.transition = 'transform 0.5s ease-out';
}
function face4Click()
{
cube.style.animation = "face4Anim 7s ease-out";
document.getElementById('body').style.animation = 'fadeOut 2s linear 6s';
launchpage();
}
function face1Click()
{
console.log("face 1");
}
function launchpage()
{
setTimeout(function () {
document.location.href = 'index.html';
}, 8000);
}
/* Reset margins/paddings */
*
{
margin: 0;
padding: 0;
}
body
{
font-family: 'moon get!';
font-size: 1.4em;
color: white;
background-color: black;
}
header, #content
{
display: flex;
flex-direction: row;
justify-content: center;
}
footer
{
display: flex;
flex-direction: row;
justify-content: center;
margin-top: 8em;
}
h1
{
margin-top: 2em;
}
#content
{
display: flex;
flex-direction: row;
justify-content: space-around;
}
#leftArrow, #rightArrow
{
margin-top: 10em;
width: 0;
height: 0;
border-top: 100px solid transparent;
border-bottom: 100px solid transparent;
}
#leftArrow
{
border-right:100px solid blue;
}
#rightArrow
{
border-left:100px solid blue;
}
#cube
{
transform-style: preserve-3d;
transform-origin: center center;
transform: translateX(-150px);
animation: rotation 2s ease-out;
position: absolute;
margin-top: 8em;
}
#cube div
{
border: 1px solid grey;
position: absolute;
width: 300px;
height: 300px;
background: linear-gradient(red, yellow);
}
#face1
{
transform: rotateY(180deg);
}
#face2
{
z-index: 2;
transform-origin: center left;
transform: translateX(300px) rotateY(-90deg);
}
#face3
{
z-index: 2;
transform-origin: center right;
transform: translateX(-300px) rotateY(90deg);
}
#face4
{
z-index: 3;
transform: translateZ(300px);
}
#face5
{
z-index: 2;
transform-origin: center top;
transform: translateY(300px) rotateX(90deg) rotateY(180deg);
}
#face6
{
z-index: 2;
transform-origin: center bottom;
transform: translateY(-300px) rotateX(-90deg);
}
#keyframes translation
{
from{transform: translateY(-700px) translateX(-150px)}
to{transform: rotate(0) translateX(-150deg) translateY(0)}
}
#keyframes rotation
{
from{transform: rotateX(45deg) rotateY(180deg) translateY(-1300px)translateX(-150px)}
to{transform: rotate(0) translateX(-150deg) translateY(0)}
}
#keyframes fadeOut
{
from{opacity: 1}
to{opacity: 0}
}
#keyframes face4Anim
{
from{transform: rotateY(0deg) translateX(-150px)}
to{transform: rotateX(90deg) rotateY(180deg) translateZ(-800px) translateX(-750px) scaleX(5) scaleY(5) scaleZ(5)}
}
<body id="body">
<header>
<h1>JS Games</h1>
</header>
<div id="content">
<div id="leftArrow" onclick="rotateLeft()"></div>
<div id="cube">
<div id="face1" onclick="face1Click()">1</div>
<div id="face2">2</div>
<div id="face3">3</div>
<div id="face4" onclick="face4Click()">4</div>
<div id="face5"></div>
<div id="face6">6</div>
</div>
<div id="rightArrow" onclick="rotateRight()"></div>
</div>
<footer>
<h5>Developed by Tony Piton</h5>
</footer>
</body>
Does anyone can help me ?