I created a custom cursor with JavaScript. – At the end of this question, I will add all the code, there is also a fiddle here: https://jsfiddle.net/8a9f2s0n/ …but what's really important is the following line of CSS: transition: all .1s ease-out;
Basically I'm deleting the actual cursor and then I'm chaining two circles to the mouse position, the second circle ("cursor2") has this CSS-property: transition: all .1s ease-out;, to make it move with some easing.
The Problem:
I tested this code in all the big browsers and it's really smooth everywhere, except for Safari, in Safari the second, larger, circle move REALLY laggy.
What's going on?
var cursor = document.querySelector(".cursor");
var cursor2 = document.querySelector(".cursor_2");
var detectIfCursorStatic = undefined;
window.addEventListener('mousemove', function(e){
// Chain "cursor" and "cursor2" to mouse-position. START
cursor.style.top = e.y + "px";
cursor.style.left = e.x + "px";
cursor2.style.top = e.y + "px";
cursor2.style.left = e.x + "px";
// Chain "cursor" and "cursor2" to mouse-position. END
cursor.style.display = "block";
cursor2.style.display = "block";
cursor2.style.transform = "translate(-50%, -50%) scale(1)";
// Change cursor2, when mouse sits still. START
clearTimeout(detectIfCursorStatic);
detectIfCursorStatic = setTimeout(function(){
cursor2.style.transform = "translate(-50%, -50%) scale(1.3)";
setTimeout(function(){
cursor2.style.transform = "translate(-50%, -50%) scale(0)";
}, 200);
}, 500);
// Change cursor2, when mouse sits still. END
});
// Make it, so that when the cursor leaves the viewport, "cursor" and "cursor2" instantly disappear, but when entering the viewport, they blend in. START
document.addEventListener('mouseout', function(){
cursor.style.opacity = "0";
cursor2.style.opacity = "0";
setTimeout(function(){
cursor.style.transition = "opacity .5s linear"
}, 500);
});
document.addEventListener('mouseover', function(){
cursor.style.opacity = "1";
cursor2.style.opacity = ".3";
setTimeout(function(){
cursor.style.transition = "opacity 0s linear"
}, 500);
});
// … END
// Make it, so that, when the cursor is hovering over an object, with the class: "cursorInteraction", "cursor" and "cursor2" change colour. START
var cursorInteractionObjects = document.querySelectorAll(".cursorInteraction");
cursorInteractionObjects.forEach(function(element){
element.addEventListener('mouseenter', function(){
cursor.style.backgroundColor = "black";
cursor2.style.backgroundColor = "black";
cursor2.style.opacity = ".2";
});
element.addEventListener('mouseleave', function(){
cursor.style.backgroundColor = "white";
cursor2.style.backgroundColor = "white";
cursor2.style.opacity = ".3";
});
});
// … END
// Example: The custom-cursor is white, it is moved over an object, with the class: "cursorInteraction" and a background-color, of: white, the custom-cursor changes to black. – Inside the object, that the cursor is currently in, there is another object, a button, with: "background-color: black", on :hover, so the custom-cursor has to change again, in this case the custom-cursor will change in such a way, that it is no longer visible. – Such buttons, are assigned the following class: "cursorInteraction_Negative".
var cursorInteractionObjects_Negative = document.querySelectorAll(".cursorInteraction_Negative");
cursorInteractionObjects_Negative.forEach(function(element){
element.addEventListener('mouseenter', function(){
cursor.style.opacity = "0";
cursor2.style.zIndex = "-1";
});
element.addEventListener('mouseleave', function(){
cursor.style.opacity = "1";
cursor2.style.zIndex = "0";
});
});
// … END
#charset "UTF-8";
/* CSS Document */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
list-style: none;
cursor: none;
}
a {
text-decoration: none;
color: black;
}
a:hover {
color: white;
}
body {
background-color: black;
}
body, html {
height: 100%; /* <- Firefox needs this. – This might not be necessary in the final website, because there will be objects spanning the whole viewport. */
}
.test_div {
background-color: white;
position: fixed;
width: 400px;
height: 200px;
margin: 15px;
display: flex;
justify-content: center;
align-items: center;
}
.test_button {
border: 1px solid black;
height: 50px;
width: 150px;
line-height: 50px;
text-align: center;
font-family: proxima-nova, sans-serif;
}
.test_button:hover {
background-color: black;
}
/* Custom Cursor START */
.cursor {
z-index: 10;
width: .5rem;
height: .5rem;
border-radius: 50%;
background-color: white;
position: fixed;
transform: translate(-50%, -50%);
pointer-events: none;
display: none;
}
.cursor_2 {
z-index: 9;
width: 2rem;
height: 2rem;
border-radius: 50%;
background-color: white;
opacity: .3;
position: fixed;
transform: translate(-50%, -50%);
pointer-events: none;
display: none;
transition: all .1s ease-out;
}
/* Custom Cursor END */
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Personal-Website Build-5</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="test_div cursorInteraction">
Test Link
</div>
<!-- Custom-Cursor START -->
<div class="cursor"></div>
<div class="cursor_2"></div>
<script src="scripts/customCursor.js"></script>
<!-- Custom-Cursor END -->
</body>
</html>
It seems like in Safari every time the transition property is updated it resets the transition effect. This is causing the lag effect. To get around this you can throttle the code that updates cursor2 position using underscore throttle function or your preferred implementation.
Example is below:
var cursor = document.querySelector(".cursor");
var cursor2 = document.querySelector(".cursor_2");
var detectIfCursorStatic = undefined;
var updateCursor2 = _(function(e) {
cursor2.style.top = e.y + "px";
cursor2.style.left = e.x + "px";
}).throttle(50);
window.addEventListener('mousemove', function(e){
// Chain "cursor" and "cursor2" to mouse-position. START
cursor.style.top = e.y + "px";
cursor.style.left = e.x + "px";
updateCursor2(e);
// Chain "cursor" and "cursor2" to mouse-position. END
cursor.style.display = "block";
cursor2.style.display = "block";
cursor2.style.transform = "translate(-50%, -50%) scale(1)";
// Change cursor2, when mouse sits still. START
clearTimeout(detectIfCursorStatic);
detectIfCursorStatic = setTimeout(function(){
cursor2.style.transform = "translate(-50%, -50%) scale(1.3)";
setTimeout(function(){
cursor2.style.transform = "translate(-50%, -50%) scale(0)";
}, 200);
}, 500);
// Change cursor2, when mouse sits still. END
});
// Make it, so that when the cursor leaves the viewport, "cursor" and "cursor2" instantly disappear, but when entering the viewport, they blend in. START
document.addEventListener('mouseout', function(){
cursor.style.opacity = "0";
cursor2.style.opacity = "0";
setTimeout(function(){
cursor.style.transition = "opacity .5s linear"
}, 500);
});
document.addEventListener('mouseover', function(){
cursor.style.opacity = "1";
cursor2.style.opacity = ".3";
setTimeout(function(){
cursor.style.transition = "opacity 0s linear"
}, 500);
});
// … END
// Make it, so that, when the cursor is hovering over an object, with the class: "cursorInteraction", "cursor" and "cursor2" change colour. START
var cursorInteractionObjects = document.querySelectorAll(".cursorInteraction");
cursorInteractionObjects.forEach(function(element){
element.addEventListener('mouseenter', function(){
cursor.style.backgroundColor = "black";
cursor2.style.backgroundColor = "black";
cursor2.style.opacity = ".2";
});
element.addEventListener('mouseleave', function(){
cursor.style.backgroundColor = "white";
cursor2.style.backgroundColor = "white";
cursor2.style.opacity = ".3";
});
});
// … END
// Example: The custom-cursor is white, it is moved over an object, with the class: "cursorInteraction" and a background-color, of: white, the custom-cursor changes to black. – Inside the object, that the cursor is currently in, there is another object, a button, with: "background-color: black", on :hover, so the custom-cursor has to change again, in this case the custom-cursor will change in such a way, that it is no longer visible. – Such buttons, are assigned the following class: "cursorInteraction_Negative".
var cursorInteractionObjects_Negative = document.querySelectorAll(".cursorInteraction_Negative");
cursorInteractionObjects_Negative.forEach(function(element){
element.addEventListener('mouseenter', function(){
cursor.style.opacity = "0";
cursor2.style.zIndex = "-1";
});
element.addEventListener('mouseleave', function(){
cursor.style.opacity = "1";
cursor2.style.zIndex = "0";
});
});
// … END
#charset "UTF-8";
/* CSS Document */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
list-style: none;
cursor: none;
}
a {
text-decoration: none;
color: black;
}
a:hover {
color: white;
}
body {
background-color: black;
}
body, html {
height: 100%; /* <- Firefox needs this. – This might not be necessary in the final website, because there will be objects spanning the whole viewport. */
}
.test_div {
background-color: white;
position: fixed;
width: 400px;
height: 200px;
margin: 15px;
display: flex;
justify-content: center;
align-items: center;
}
.test_button {
border: 1px solid black;
height: 50px;
width: 150px;
line-height: 50px;
text-align: center;
font-family: proxima-nova, sans-serif;
}
.test_button:hover {
background-color: black;
}
/* Custom Cursor START */
.cursor {
z-index: 10;
width: .5rem;
height: .5rem;
border-radius: 50%;
background-color: white;
position: fixed;
transform: translate(-50%, -50%);
pointer-events: none;
display: none;
}
.cursor_2 {
z-index: 9;
width: 2rem;
height: 2rem;
border-radius: 50%;
background-color: white;
opacity: .3;
position: fixed;
transform: translate(-50%, -50%);
pointer-events: none;
display: none;
transition: all .1s ease-out;
}
/* Custom Cursor END */
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Personal-Website Build-5</title>
<link rel="stylesheet" href="style.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.12.0/underscore-min.js" integrity="sha512-BDXGXSvYeLxaldQeYJZVWXJmkisgMlECofWFXKpWwXnfcp/R708nrs/BtNLH5cb/5TE7aeYRTDBRXu6kRL4VeQ==" crossorigin="anonymous"></script>
</head>
<body>
<div class="test_div cursorInteraction">
Test Link
</div>
<!-- Custom-Cursor START -->
<div class="cursor"></div>
<div class="cursor_2"></div>
<script src="scripts/customCursor.js"></script>
<!-- Custom-Cursor END -->
</body>
</html>
Related
THE WHOLE CODE IN JSFIDDLE
I have been struggling to effectively remove the code and css created in the function Seifenblasen_blasen()
function Seifenblasen_blasen(){
btn1.style.display = 'none';
document.getElementById("text").innerHTML="Bubble"
const section = document.querySelector('section')
const createElement = document.createElement('spawn')
var size = Math.random() * 60;
createElement.style.width = 30 + size + 'px';
createElement.style.height = 30 + size + 'px';
createElement.style.left = Math.random() * innerWidth + "px";
section.appendChild(createElement);
setTimeout(() => {
createElement.remove()
},8000)
}
const Blaseninterval = setInterval(Seifenblasen_blasen, 100)
created CSS:
section {
width: 100%;
height: 100vh;
overflow: hidden;
background: #1F69FA;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
section.text{
font-size: 10em;
color: #333;
margin: 0 auto;
text-align: center;
font-family: consolas;
background-color:#1F69FA;
pointer-events: none;
border: none;
}
section spawn {
position: absolute;
bottom: -80px;
background: transparent;
border-radius: 50%;
pointer-events: none;
box-shadow: inset 0 0 10px rgba(255, 255, 255, 0.5);
animation: animate 4s linear infinite;
}
section spawn:before {
content: '';
position: absolute;
width: 100%;
height: 100%;
transform: scale(0.25) translate(-70%, -70%);
background: radial-gradient(#fff, transparent);
opacity: 0.6;
border-radius: 50%;
}
#keyframes animate {
0% {
transform: translateY(0%);
opacity: 1;
}
99% {
opacity: 1;
}
100% {
transform: translateY(-2000%);
opacity: 0;
}
section span {
margin-top: 700px;
font-size: 1em;
color: #333;
margin: 0 auto;
font-family: consolas;
background-color: #1F69FA;
border: none;
position: absolute;
}
HTML:
<section id="section">
<div class="content">
<button id="btn"></button>
<button id="btn1"></button>
</div>
</section>
to then execute the next function function next(). This removal is needed because when I don't remove the elements from the first function the second wont work. I could just do document.head.innerHTML = "" but that would then also remove the css needed for the button appearing in the next function. So then I tried to make variables with const
const btn = document.getElementById('text');
const btn1 = document.getElementById('text1');
const section = document.querySelector('section')
// in function Seifenblasen_blasen()
btn1.style.display = 'none';
// in function next()
section.style.display = 'none';
btn.style.display = 'none';
btn1.style.display = 'block';
to hide and show only parts of the css without removing the css entirely to keep the styling intact, but now nothing works anymore.(the button on the next Screen doesn't show up at all and the first button does not contain any styling) My endgoal is that I can essentially switch between two screens one showing the bubbles and one the bouncy balls and when I click on the button it goes on. (for example start is bubbles. I click -> Bounce, click again -> back to Bubbles and so on)
I'm trying recoding the https://www.orizon.co/ following dot. The code I've written to asure the dot rising effect when the pointer fly over some elements seems correct, but when the dot's z-index is higher than the flew over element's one, there is a kind of bug than make me crazy.
class CursorFollower {
constructor() {
this.follower = document.getElementById("cursor-follower");
this.topGap = 12;
this.leftGap = 4;
window.addEventListener("mousemove", this.follow.bind(this));
this.eventsSet();
}
// The function doing the dot follows the pointer
follow() {
setTimeout(function () {
cursorFollower.follower.style.left = (this.clientX - cursorFollower.topGap) + "px";
cursorFollower.follower.style.top = (this.clientY - cursorFollower.leftGap) + "px";
}.bind(window.event), 100);
}
eventsSet() {
// Adding events to button
var button = document.querySelector(".follower-over");
button.addEventListener("pointerenter", this.overOn.bind(this));
button.addEventListener("pointerleave", this.overOff.bind(this));
}
overOn() {
// The effects to apply when the pointer flies over the button
this.follower.style.opacity = 0.3;
this.follower.style.width = "50px";
this.follower.style.height = "50px";
this.follower.style.backgroundColor = "black";
this.topGap = 25;
this.leftGap = 25;
}
overOff() {
// The effects to apply when the pointer leave the button
this.follower.style.opacity = 1;
this.follower.style.width = "7px";
this.follower.style.height = "7px";
this.follower.style.backgroundColor = "rgba(42, 0, 212, 1)";
this.topGap = 12;
this.leftGap = 4;
}
}
let cursorFollower = new CursorFollower();
/* Some styling */
.contact-us{
padding: 25px 40px;
width: 200px;
display: flex;
align-items: center;
color: white;
background-color: #2b00d4 ;
height: 60px;
position: relative;
z-index: 1;
}
#cursor-follower{
z-index: 999;
position: fixed;
background-color: #2b00d4;
height: 7px;
width: 7px;
border-radius: 50%;
transition: opacity 0.3s , width 0.3s , height 0.3s, background-color 0.3s;
}
<div id="cursor-follower"></div>
<div class="contact-us follower-over">
<p>CONTACT US</p>
</div>
When the button's z-index is higher than the dot's one, the effects works. Else, it bugs
This is because your follower element is getting under cursor, triggering overOff than when its shrinks it triggers overOn and so on.
The simplest solution is to add pointer-events: none; into the follower so it doesn't trigger overOn/overOff:
class CursorFollower {
constructor() {
this.follower = document.getElementById("cursor-follower");
this.topGap = 12;
this.leftGap = 4;
window.addEventListener("mousemove", this.follow.bind(this));
this.eventsSet();
}
// The function doing the dot follows the pointer
follow() {
setTimeout(function() {
cursorFollower.follower.style.left = (this.clientX - cursorFollower.topGap) + "px";
cursorFollower.follower.style.top = (this.clientY - cursorFollower.leftGap) + "px";
}.bind(window.event), 100);
}
eventsSet() {
// Adding events to button
var button = document.querySelector(".follower-over");
button.addEventListener("pointerenter", this.overOn.bind(this));
button.addEventListener("pointerleave", this.overOff.bind(this));
}
overOn() {
// The effects to apply when the pointer flies over the button
this.follower.style.opacity = 0.3;
this.follower.style.width = "50px";
this.follower.style.height = "50px";
this.follower.style.backgroundColor = "black";
this.topGap = 25;
this.leftGap = 25;
}
overOff() {
// The effects to apply when the pointer leave the button
this.follower.style.opacity = 1;
this.follower.style.width = "7px";
this.follower.style.height = "7px";
this.follower.style.backgroundColor = "rgba(42, 0, 212, 1)";
this.topGap = 12;
this.leftGap = 4;
}
}
let cursorFollower = new CursorFollower();
/* Some styling */
.contact-us {
padding: 25px 40px;
width: 200px;
display: flex;
align-items: center;
color: white;
background-color: #2b00d4;
height: 60px;
position: relative;
z-index: 1;
}
#cursor-follower {
pointer-events: none; /* added */
z-index: 999;
position: fixed;
background-color: #2b00d4;
height: 7px;
width: 7px;
border-radius: 50%;
transition: opacity 0.3s, width 0.3s, height 0.3s, background-color 0.3s;
}
<div id="cursor-follower"></div>
<div class="contact-us follower-over">
<p>CONTACT US</p>
</div>
However there is even simpler solution with much less javascript:
window.addEventListener("mousemove", e => {
setTimeout(s => {
document.documentElement.style.setProperty("--cursorX", e.clientX + "px");
document.documentElement.style.setProperty("--cursorY", e.clientY + "px");
}, 100);
});
/* Some styling */
:root
{
--cursorX: -100px;
--cursorY: -100px;
}
.contact-us {
padding: 25px 40px;
width: 100px;
display: flex;
align-items: center;
color: white;
background-color: #2b00d4;
height: 40px;
position: relative;
z-index: 1;
}
.cursor-follower {
--size: 7px;
--gapLeft: 12px;
--gapTop: 4px;
pointer-events: none;
position: fixed;
background-color: #2b00d4;
width: var(--size);
height: var(--size);
border-radius: 50%;
transition: opacity 0.3s, width 0.3s, height 0.3s, background-color 0.3s;
top: calc(var(--cursorY) - var(--gapTop));
left: calc(var(--cursorX) - var(--gapLeft));
}
.follower-over:hover~.cursor-follower {
--size: 50px;
--gapLeft: 25px;
--gapTop: 25px;
opacity: 0.3;
background-color: black;
z-index: 2;
}
/* extra */
.follower-over.green:hover~.cursor-follower {
background-color: green;
opacity: 0.7;
--size: 80px;
--gapLeft: 40px;
--gapTop: 40px;
}
.contact-us:not(.follower-over) {
background-color: pink;
}
.contact-us {
display: inline-block;
margin: 1em;
}
<div class="contact-us follower-over">
<p>CONTACT US</p>
</div>
<div class="contact-us follower-over">
<p>Another button</p>
</div>
<div class="contact-us">
<p>No follower</p>
</div>
<div class="contact-us follower-over green">
<p>Large green</p>
</div>
<div class="cursor-follower"></div>
The only caveat with this method is the .cursor-follower must be last element and has the same parent as all .follower-over elements
I have a custom cursor on my site that I want to hide on touch devices (mobile/tablet). I have successfully done this but for a split second when you visit the website the cursor appears in the top left corner then is hidden. Is there any way to stop it displaying at all?
This is the code im using to remove the ID of the cursor on touch devices.
jQuery(document).ready(function($) {
{
if(/Android|webOS|iPhone|iPad|iPod|BlackBerry|Windows Phone/i.test(navigator.userAgent)) {
$('#custom-cursor').remove();
}
}
});
jQuery(document).ready(function($) {
let cursor = document.querySelector('#custom-cursor');
document.addEventListener('mousemove', evt => {
let { clientX: x, clientY: y } = evt;
let scale = 1;
if (evt.target.matches('a,span,[onclick],img,video,i')) {
cursor.classList.add('active');
scale = 0.5;
} else {
cursor.classList.remove('active');
}
cursor.style.transform = `translate(${x}px, ${y}px) scale(${scale})`;
});
});
* {
cursor: none;
}
#custom-cursor {
position: fixed;
width: 20px; height: 20px;
top: -10px;
left: -10px;
border: 2px solid black;
border-radius: 50%;
opacity: 1;
background-color: #fb4d98;
pointer-events: none;
z-index: 99999999;
transition:
transform ease-out 0.15s,
border 0.5s,
opacity 0.5s,
background-color 0.5s;
}
#custom-cursor.active {
opacity: 0.5;
background-color: #000;
border: 2px solid #fb4d98;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="custom-cursor"></div>
Without seeing more of your code it's not possible to be absolutely sure, but from the info in the question it looks as though the whole page is loaded before the cursor is removed.
You could tackle this in a variety of ways, for example not having the cursor element in the initial HTML but adding it if required onload.
Alternatively you could leave your initial HTML as it is, but set the cursor to have display: none in your CSS. Then onload the JS adds setting the style.display to block if the cursor is not to be removed.
UPDATE: now having seen more of the code here is a snippet to show how the second method (cursor to have display: none until the page is loaded) might be implemented:
jQuery(document).ready(function($) {
let cursor = document.querySelector('#custom-cursor');
if(/Android|webOS|iPhone|iPad|iPod|BlackBerry|Windows Phone/i.test(navigator.userAgent)) {
$('#custom-cursor').remove();
}
else { cursor.style.display = 'block';}
document.addEventListener('mousemove', evt => {
let { clientX: x, clientY: y } = evt;
let scale = 1;
if (evt.target.matches('a,span,[onclick],img,video,i')) {
cursor.classList.add('active');
scale = 0.5;
} else {
cursor.classList.remove('active');
}
cursor.style.transform = `translate(${x}px, ${y}px) scale(${scale})`;
});
});
* {
cursor: none;
}
#custom-cursor {
position: fixed;
width: 20px; height: 20px;
top: -10px;
left: -10px;
border: 2px solid black;
border-radius: 50%;
opacity: 1;
background-color: #fb4d98;
pointer-events: none;
z-index: 99999999;
transition:
transform ease-out 0.15s,
border 0.5s,
opacity 0.5s,
background-color 0.5s;
display: none;
}
#custom-cursor.active {
opacity: 0.5;
background-color: #000;
border: 2px solid #fb4d98;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="custom-cursor"></div>
I've written the code below to create a custom cursor style on my webpage, but the cursor moves very slow across the webpage. What is causing the slowness?
var cursor = document.getElementById("cursor");
cursor.style.transition = "ease-in-out .2s";
document.onmousedown = () => {
cursor.style.transform = "scale(0.4)";
};
document.onmouseup = () => {
cursor.style.transform = "scale(1)";
};
document.onmousemove = (e) => {
cursor.style.top = ((e.clientY - 15) + "px");
cursor.style.left = ((e.clientX) + "px");
};
body {
cursor: none;
}
#cursor {
position: absolute;
z-index: 9;
background-color: transparent;
text-align: center;
border-radius: 70%;
border: 1px solid #d3d3d3;
position: fixed;
cursor: none;
}
<div id="cursor">o</div>
That is due to the transition animation applied to the cursor. See line 2, and consider that:
0.1s represents the transition duration
ease-in-out or linear represent the transition easing (e.a. what was causing you that annoying and bouncy delay).
If you want to know more about different transition easings, I'd suggest you having a look at it here and here.
var cursor = document.getElementById("cursor");
cursor.style.transition = "linear 0.1s";
document.onmousedown = () => {
cursor.style.transform = "scale(0.4)";
};
document.onmouseup = () => {
cursor.style.transform = "scale(1)";
};
document.onmousemove = (e) => {
cursor.style.top = ((e.clientY - 15) + "px");
cursor.style.left = ((e.clientX) + "px");
};
body {
cursor: none;
}
#cursor {
position: absolute;
z-index: 9;
background-color: transparent;
text-align: center;
border-radius: 70%;
border: 1px solid #d3d3d3;
position: fixed;
cursor: none;
/*Why is the cursor firing when its away from this*/
}
<div id="cursor">o</div>
Little suggestion on a side, is to delete line two and add the transition on css instead: transition: all 0.1s linear; - This change doesn't actually modify any functionality, but it makes your code neattier.
The reason, is that styles should be kept in CSS whenever possible, leaving Javascript to handle styles only if needed (in this case, inside the event listeners such as onmousedown, onmouseup, ecc.)
Can someone please tell me why my fluid box isn't working for my photo. I've followed all of the instructions to create the code for the fluidbox, but my photo doesn't show up on the webpage. But when you click on where it is supposed to be on the webpage, it takes you to another page that has my photo in it. Here is my codes:
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Bootswatch: Cosmo</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="./bootstrap.css" media="screen">
<link rel="stylesheet" href="bootstrap-lightbox.css">
<link rel="stylesheet" href="portfoliostyle.css">
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="../bower_components/html5shiv/dist/html5shiv.js"></script>
<script src="../bower_components/respond/dest/respond.min.js"></script>
<![endif]-->
<script>
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-23019901-1']);
_gaq.push(['_setDomainName', "bootswatch.com"]);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
<script src="jquery.js"></script>
<script src="imagelightbox.js"></script>
<script>
$( function()
{
$( 'a' ).imageLightbox();
});
</script>
</head>
<body>
<ul class="navigation">
<li class="nav-item">Home</li>
<li class="nav-item">Portfolio</li>
<li class="nav-item">About</li>
<li class="nav-item">Blog</li>
<li class="nav-item">Contact</li>
</ul>
<input type="checkbox" id="nav-trigger" class="nav-trigger" />
<label for="nav-trigger"></label>
<div class="site-wrap">
<div class="gallery">
<a class="space" href="images/spacetime.jpg" title="A Space in Time" data-fluidbox>
<img src="images/spacetime.jpg" />
</a>
<a href="images/spacetime.jpg" data-fluidbox>
<div class="fluidbox-wrap">
<img src="images/spacetime.jpg" />
<div class="fluidbox-ghost"></div>
</div>
</a>
</div>
</div>
<script src="https://code.jquery.com/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js">
$(function () {
// Global variables
var $fb = $('a[data-fluidbox');
vpRatio; // To store viewport aspect ratio
// Add class to all Fluidboxes
$fb.addClass('fluidbox');
// Create fluidbox modal background
$('body').append('<div id="fluidbox-overlay"></div>');
// Functions:
// 1. to close any opened Fluidbox
// 2. to position Fluidbox dynamically
var closeFb = function (){
$('a[data-fluidbox].fluidbox-opened').trigger('click');
},
positionFb = function ($activeFb){
// Get elements
var $img = $activeFb.find('img'),
$ghost = $activeFb.find('.fluidbox-ghost');
// Calculate offset and scale
var offsetY = $(window).scrollTop()-$img.offset().top+0.5*($img.data('imgHeight')*($img.data('imgScale')-1))+0.5*($(window).height()-$img.data('imgHeight')*$img.data('imgScale')),
offsetX = 0.5*($img.data('imgWidth')*($img.data('imgScale')-1))+0.5*($(window).width()- $img.data('imgWidth')*$img.data('imgScale')) - $img.offset().left,
scale = $img.data('imgScale');
// Animate wrapped elements
// Parse integers:
// 1. Offsets can be integers
// 2. Scale is rounded to nearest 2 decimal places
$ghost.css({ 'transform': 'translate('+parseInt(offsetX*10)/10+'px,'+parseInt(offsetY*10)/10+'px) scale('+parseInt(scale*1000)/1000+')' });
}
// The following events will force FB to close
// ... when the opqaue overlay is clicked upon
$('#fluidbox-bg').click(closeFb);
})();
$fb.imagesLoaded().done(function (){
$fb
.wrapInner('<div class="fluidbox-wrap" />')
.find('img')
.css({ opacity: 1 })
.after('<div class="fluidbox-ghost" />');
// Listen to resize event for calculations
$(window).resize(function (){
// Get viewport aspect ratio (#1)
vpRatio = $(window).width() / $(window).height();
// Get dimensions and aspect ratios
$fb.each(function (){
var $img = $(this).find('img'),
$ghost = $(this).find('.fluidbox-ghost'),
$wrap = $(this).find('.fluidbox-wrap'),
data = $img.data();
// Save image dimensions as jQuery object (#2)
data.imgWidth = $img.width();
data.imgHeight = $img.height();
data.imgRatio = $img.width() / $img.height();
// Resize ghost element (#3)
$ghost.css({
width: $img.width(),
height: $img.height(),
top: $img.offset().top - $wrap.offset().top,
left: $img.offset().left - $wrap.offset().left
});
// Calculate scale based on orientation (#4)
if(vpRatio > data.imgRatio) {
data.imgScale = $(window).height()*.95 / $img.height();
} else {
data.imgScale = $(window).width()*.95 / $img.width();
}
});
}).resize();
// Bind click event
$fb.click(function (e){
// Variables
var $img = $(this).find('img'),
$ghost = $(this).find('.fluidbox-ghost'),
$wrap = $(this).find('.fluidbox-wrap');
if($(this).data('fluidbox-state') == 0 || !$(this).data('fluidbox-state')) {
// State: Closed
// Action: Open Fluidbox
$(this)
.data('fluidbox-state', 1)
.removeClass('fluidbox-closed')
.addClass('fluidbox-opened');
// Show overlay
$('#fluidbox-overlay').fadeIn();
// Set thumbnail image source as background image first.
// We also show the ghost element
$ghost.css({
'background-image': 'url('+$img.attr('src')+')',
opacity: 1
});
// Hide original image
$img.css({ opacity: 0 });
// Preload ghost image
var ghostImg = new Image();
ghostImg.onload = function (){ $ghost.css({ 'background-image': 'url('+$activeFb.attr('href')+')' } ); };
ghostImg.src = $(this).attr('href');
// Position Fluidbox
positionFb($(this));
} else {
// State: Opened
// Action: Close Fluidbox
/// Switch state
$(this)
.data('fluidbox-state', 0)
.removeClass('fluidbox-opened')
.addClass('fluidbox-closed');
// Hide overlay
$('#fluidbox-overlay').fadeOut();
// Show original image
$img.css({ opacity: 1 });
// Hide ghost image
$ghost.css({ opacity: 0 });
// Reverse animation on wrapped elements
$ghost
.css({ 'transform': 'translate(0,0) scale(1)' })
.one('webkitTransitionEnd MSTransitionEnd oTransitionEnd transitionend', function (){
// Wait for transntion to run its course first
$ghost.css({ opacity: 0 });
});
}
});
</script>
CSS:
/* Navigation Menu - Background */
.navigation {
/* critical sizing and position styles */
width: 100%;
height: 100%;
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 0;
/* non-critical appearance styles */
list-style: none;
background: #111;
}
/* Navigation Menu - List items */
.nav-item {
/* non-critical appearance styles */
width: 200px;
border-top: 1px solid #111;
border-bottom: 1px solid #000;
}
.nav-item a {
/* non-critical appearance styles */
display: block;
padding: 1em;
background: linear-gradient(135deg, rgba(0,0,0,0) 0%,rgba(0,0,0,0.65) 100%);
color: white;
font-size: 1.2em;
text-decoration: none;
transition: color 0.2s, background 0.5s;
}
.nav-item a:hover {
color: #c74438;
background: linear-gradient(135deg, rgba(0,0,0,0) 0%,rgba(75,20,20,0.65) 100%);
}
.site-wrap {
min-width: 100%;
min-height: 100%;
background-color: #fff;
position: absolute;
top: 0;
bottom: 100%;
left: 0;
z-index: 1;
padding: 4em;
background-image: linear-gradient(135deg,
rgb(254,255,255) 0%,
rgb(221,241,249) 35%,
rgb(160,216,239) 100%);
background-size: 200%;
}
.name {
position: absolute;
top: 60%;
right:40%;
}
h3{
text-align: center;
top: 65%;
}
/* Nav Trigger */
.nav-trigger {
/* critical styles - hide the checkbox input */
position: absolute;
clip: rect(0, 0, 0, 0);
}
label[for="nav-trigger"] {
/* critical positioning styles */
position: fixed;
left: 15px; top: 15px;
z-index: 2;
/* non-critical apperance styles */
height: 30px;
width: 30px;
cursor: pointer;
background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' version='1.1' x='0px' y='0px' width='30px' height='30px' viewBox='0 0 30 30' enable-background='new 0 0 30 30' xml:space='preserve'><rect width='30' height='6'/> <rect y='24' width='30' height='6'/><rect y='12' width='30' height='6'/></svg>");
background-size: contain;
}
/* Make the Magic Happen */
.nav-trigger + label, .site-wrap {
transition: left 0.2s;
}
.nav-trigger:checked + label {
left: 215px;
}
.nav-trigger:checked ~ .site-wrap {
left: 200px;
box-shadow: 0 0 5px 5px rgba(0,0,0,0.5);
}
body {
/* Without this, the body has excess horizontal scroll when the menu is open */
overflow-x: hidden;
}
/* Additional non-critical styles */
h1, h3, p {
max-width: 600px;
margin: 0 auto 1em;
}
code {
padding: 2px;
background: #ddd;
}
/* Micro reset */
*,*:before,*:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border- box;margin:0;padding:0;}
html, body { height: 100%; width: 100%; font-family: Helvetica, Arial, sans-serif; }
/* Image Lightbox Galley */
a[data-fluidbox] {
background-color: #eee;
border: none;
cursor: -webkit-zoom-in;
cursor: -moz-zoom-in;
margin-bottom: 1.5rem;
}
a[data-fluidbox].fluidbox-opened {
cursor: -webkit-zoom-out;
cursor: -moz-zoom-out;
}
a[class^='float'] {
margin: 1rem;
margin-top: 0;
width: 33.33333%;
}
a.float-left {
float: left;
margin-left: 0;
}
a.float-right {
float: right;
margin-right: 0;
}
a[data-fluidbox] img {
display: block;
margin: 0 auto;
opacity: 0;
max-width: 100%;
transition: all .25s ease-in-out;
}
#fluidbox-overlay {
background-color: rgba(255,255,255,.85);
cursor: pointer;
cursor: -webkit-zoom-out;
cursor: -moz-zoom-out;
display: none;
position: fixed;
top: 0;
left: 0;
bottom: 0;
right: 0;
z-index: 500;
}
.fluidbox-wrap {
background-position: center center;
background-size: cover;
margin: 0 auto;
position: relative;
z-index: 400;
transition: all .25s ease-in-out;
}
.fluidbox-opened .fluidbox-wrap {
z-index: 600;
}
.fluidbox-ghost {
background-size: cover;
background-position: center center;
position: absolute;
transition: all .25s ease-in-out;
}
.space img{
height: 25%;
width: 50%
}