I have an image. I have written some code that will rotate it over en over,
but the setInterval() function is not working.
Please can you tell me why?
var star = document.getElementById('star');
setInterval(function() {star.style.transform = "rotate(10deg)"; },10);
You need to increment the degree value on each function call, simply do it using a variable. In your case it will always stay on 10degree rotate.
DEMO:
var star = document.getElementById('star'),
deg = 10;
setInterval(function() {
star.style.transform = "rotate(" + deg + "deg)";
deg = (deg + 10) % 360
}, 10);
#star {
width: 100px;
height: 100px;
background: red;
}
<div id="star"></div>
You can use css animation here
#keyframes anim {
0% {
transform: rotate(0deg);
}25% {
transform: rotate(90deg);
}50% {
transform: rotate(180deg);
}75% {
transform: rotate(270deg);
}100% {
transform: rotate(360deg);
}
}
#star {
width: 100px;
height: 100px;
background: red;
animation: anim .36s infinite;
}
<div id="star"></div>
Small sample:
var ready = function() {
var
star = document.getElementById('star'),
degree = 0;
setInterval(function() {
/* Every 10ms degree variable increase its value by 1 */
star.style.transform = "rotate(" + ++degree +"deg)"; }, 10
);
};
#star {
margin-left: 100px;
margin-top: 40px;
width: 60px;
border: 1px solid;
padding: 20px;
}
<body onload="ready()">
<div id="star">
<h1>Yay!</h1>
</div>
</body>
Related
Well, I am trying to get an image to change from one size to a smaller size and then back to the other size with just one click. (you are clicking the image.) I have tried a good amount of options, but I haven't gotten it to change to a different size on click.
Here is the HTML part of the code (that is in question):
<p>Money: $<a id="clicks">0.00</a></p>
<img src="Money.png" alt="Increase Money" title="Click Me to increase the Money." type="button" onclick="moneyOne()" class="clicked">
Here is the Javascript part of the code (that is in question):
var clicks = 0.00;
function moneyOne() {
clicks += 0.01;
document.getElementById("clicks").innerHTML = clicks;
};
Here is the CSS part of the code (that is in question):
.clicked {
width: 410px;
height: 200px;
transition-property: width, height;
transition-duration: 1s;
}
.clicked: {
width: 400px;
height: 190px;
}
var clickActive = false;
var waitTime = 150;
document.querySelector("img").onclick = function() {
if(!clickActive) {
clickActive = true;
this.style.animation = "getSmaller "+waitTime+"ms";
setTimeout(()=>{
this.style.animation = "";
clickActive = false;
}, waitTime);
}
}
#keyframes getSmaller {
0%{
transform: scale(1);
}
50%{
transform: scale(0.8);
}
100%{
transform: scale(1);
}
}
/* for testing */
img {
background: blue;
width: 200px;
height: 200px;
}
body {
margin: 60px;
}
<img src="">
You need to use the pseudo-class :active like that:
.clicked:active {
width: 400px;
height: 190px;
}
I would use trandsform, transition, and a timeout to remove the class.
var clicks = 0.00;
var timer;
var img = document.querySelector(".clicked");
function moneyOne() {
clicks += 0.01;
document.getElementById("clicks").innerHTML = clicks.toFixed(2);
img.classList.add("active");
if (timer) window.clearTimeout(timer);
timer = window.setTimeout(function() {
img.classList.remove("active");
}, 200);
};
.clicked {
width: 410px;
height: 200px;
transition: all .2s ease-in-out;
transform: scale(1);
}
.clicked.active {
transform: scale(.6);
}
<p>Money: $<a id="clicks">0.00</a></p>
<img src="https://stackoverflow.design/assets/img/logos/se/se-icon.svg" alt="Increase Money" title="Click Me to increase the Money." type="button" onclick="moneyOne()" class="clicked">
Adding the pseudo state :active works how you appear to want it.
var clicks = 0.00;
function moneyOne() {
clicks += 0.01;
document.getElementById("clicks").innerHTML = clicks;
};
.clicked {
width: 410px;
height: 200px;
transition-property: width, height;
transition-duration: 1s;
}
.clicked:active {
width: 400px;
height: 190px;
}
<p>Money: $<a id="clicks">0.00</a></p>
<img src="https://stackoverflow.design/assets/img/logos/se/se-icon.svg" alt="Increase Money" title="Click Me to increase the Money." type="button" onclick="moneyOne()" class="clicked">
I want to make a custom click animation for my website, I want to do something like this:
Here's a capture from that gif
My first aproach was something like this:
It has some problems, for example when I click the animation is triggered but the animation follows the mouse instead of stay in the clicks coords, it lacks of many things like those shiny particles that spread across the click zone and that blurred halo, I dont know how to do this thing, someone know what should I do to accomplish this? like, what should I study or search to get what I want? I lack of expertise so I would really like some little guidance or anything
I dont know if this helps even a little bit but still I'll paste the code of my first approach
const cursor = document.querySelector('.cursor');
document.addEventListener('mousemove', e => {
cursor.setAttribute("style", "top: " + (e.pageY - 10) + "px; left: " + (e.pageX - 10) + "px;");
})
document.addEventListener('click', () => {
cursor.classList.add("expand");
setTimeout(() => {
cursor.classList.remove("expand");
}, 500);
})
body {
margin: 0;
height: 100vh;
background-color: black;
}
.cursor {
width: 20px;
height: 20px;
border-radius: 50%;
position: absolute;
}
#keyframes cursorAnim3 {
0% {
transform: scale(1);
}
50% {
transform: scale(1.5);
opacity: 0.5;
}
100% {
transform: scale(1);
opacity: 0;
}
}
.expand {
animation: cursorAnim3 .3s forwards;
border: 2px solid rgba(255, 255, 255, 0.7);
}
<div class="cursor"></div>
Any suggestion is welcome :c
What I added to your code is an if statement inside of your mousemove event. I don't know how to explain, I just added it and it works... Hope that's what you wanted! :) PS: I also added overflow-x: hidden and overflow-y: hidden since the body size was increasing. It is located inside of
body {
}
const cursor = document.querySelector('.cursor');
document.addEventListener('mousemove', e => {
if (cursor.classList.length === 1) {
cursor.setAttribute("style", "top: " + (e.pageY - 10) + "px; left: " + (e.pageX - 10) + "px;");
}
})
document.addEventListener('click', () => {
cursor.classList.add("expand");
setTimeout(() => {
cursor.classList.remove("expand");
}, 500);
})
body {
margin: 0;
height: 100vh;
overflow-x: hidden;
overflow-y: hidden;
background-color: black;
}
.cursor {
width: 20px;
height: 20px;
border-radius: 50%;
position: absolute;
}
#keyframes cursorAnim3 {
0% {
transform: scale(1);
}
50% {
transform: scale(1.5);
opacity: 0.5;
}
100% {
transform: scale(1);
opacity: 0;
}
}
.expand {
animation: cursorAnim3 .3s forwards;
border: 2px solid rgba(255, 255, 255, 0.7);
}
<div class="cursor"></div>
So the idea of my work is with the 10 slides in my section will have an element append to the slides, which are drinking can products. When the cursor hovers the cans, the cans will increase the size to show the real detail of the can.
Anyway, I have managed to create my carousel active slide, the 3D effect cans that can rotate clockwise and have a list of different colour cans in CSS (different background for each bottle class).
I can only get the first can working on the active slide, but the rest of the slides are blank. I've only create a list of 3 items in the array hoping to fill up the three slides with the drinking can products but no luck? What am I doing wrong?
I'm calling the initApp function, which has the array of cans because I want to append items, but only one at a time...
so in the each.function(index) - I can add the index, and then in initApp(index). and then in the initApp function I can adjust so that bottle[index] gets selected and then added. But nothing seems to work?? What am I doing wrong? I know there is a bunch of ways I can do this.
Like could I skip the initApp() function and add all the code in the .each(function() { my code to append bottle})??
// slider
$("#products>article").on("click", function(){
$("#products>article").removeClass("active");
$(this).addClass("active");
animate();
});
function getActiveArticle(){
var x = 0;
$("#products>article").each(function(e){
if($("#products>article").eq(e).hasClass("active")){
x = e;
return false;
}
});
return x;
}
function gofwd(){
var activeIndex = getActiveArticle();
var minArticles = 0;
var maxArticles = $("#products>article").length - 1;
if(activeIndex >= maxArticles){
activeIndex = minArticles-1;
}
$("#products>article").removeClass("active");
$("#products>article").eq(activeIndex+1).addClass("active");
animate();
}
function gobwd(){
var activeIndex = getActiveArticle();
var minArticles = 1;
var maxArticles = $("#products>article").length;
$("#products>article").removeClass("active");
$("#products>article").eq(activeIndex-1).addClass("active");
animate();
}
$(document).ready(function(){
animate();
});
function animate(){
var articleIndex = getActiveArticle();
var totalMargin = 25 * (articleIndex+1) - (25*(articleIndex));
var articlePosition = Math.floor($("#products>article").eq(articleIndex).offset().left - $("#products").offset().left) - totalMargin;
var productsHalfWidth = $("#products").width()/2;
if(articleIndex == 0){
var halfWidth = 150;
}else{
var halfWidth = 100;
}
var finalPosition = productsHalfWidth - articlePosition - halfWidth;
$("#products").animate({
"left": finalPosition,
}, {
duration: 500,
easing: 'easeOutBack',
});
}
$(window).on("resize", function(){
animate();
});
var autoPlay = setInterval(function(){
gofwd();
}, 3500);
$("#slider").on("mouseenter", function(){
clearInterval(autoPlay);
});
$("#slider").on("mouseleave", function(){
autoPlay = setInterval(function(){
gofwd();
}, 4500);
});
// cans
const getElement = (selector) => document.querySelector(selector);
const createElement = (tag) => document.createElement(tag);
// const addBackground1 = document.style['background'] = 'url ("https://i.postimg.cc/BZ8rj2NM/sleve.png")';
const addSideStyle = ($side, i) => {
let deg = 3.75 * i;
let bgPosition = 972 - (i * 10.125);
$side.style['background-position'] = bgPosition + 'px 0';
$side.style['-webkit-transform'] = 'rotateY(' + deg + 'deg) translateZ(154px)';
$side.style['-moz-transform'] = 'rotateY(' + deg + 'deg) translateZ(154px)';
$side.style['transform'] = 'rotateY(' + deg + 'deg) translateZ(154px)';
};
const createBottle = () => {
const $bottle = createElement('div');
$bottle.classList.add('bottle');
const $bottleLabel = createBottleLabel();
for (let i = 0; i < 96; i = i + 1){
let $bottleSide = createBottleSide(i);
$bottleLabel.append($bottleSide);
}
$bottle.append($bottleLabel);
return $bottle;
};
const createBottleLabel = () => {
const $bottleLabel = createElement('div');
$bottleLabel.classList.add('label');
return $bottleLabel;
}
const createBottleSide = (i) => {
const $bottleSide = createElement('div');
$bottleSide.classList.add('side');
addSideStyle($bottleSide, i);
return $bottleSide;
};
const changeBottleSize = (clickFn) => {
const _bottle = createElement('div');
_bottle.classList.add('bottle');
_bottle.style['transform'] = 'scale(0.9)';
return _bottle;
}
const clickFn = () => {
const $bottleSize = getElement('.container');
// const $bottle1 = changeBottleSize();
// const $bottle2 = changeBottleSize();
// const $bottle3 = changeBottleSize();
$bottleSize.style['transform'] = 'scale(0.9)';
return $bottleSize;
}
$('#products article').each(function(index) {
$(this).append(initApp())
});
const initApp = (index) => {
const $container = getElement('.container');
const $bottle1 = createBottle();
const $bottle2 = createBottle();
const $bottle3 = createBottle();
[$bottle1, $bottle2, $bottle3].forEach(($bottle, i) => {
$bottle.classList.add('bottle' + i);
});
$container.append($bottle1, $bottle2, $bottle3);
};
initApp();
* {
padding: 0;
margin: 0;
font-family: "Arial";
box-sizing: border-box;
}
body {
background-color: #444;
}
#slider {
position: relative;
overflow: hidden;
width: 90vw;
height: 750px;
margin: 50px auto;
background-color: rgba(255, 255, 255, .5);
}
#products {
position: relative;
display: flex;
width: 100%;
height: 100%;
align-items: center;
padding: 0 25px;
}
#products>article:first-child {
margin-left: 0;
}
#products>article {
position: relative;
min-width: 250px;
min-height: 250px;
margin-left: 25px;
font-size: 17px;
cursor: pointer;
/* background-color: rgba(255,0,0,.5); */
transition: all .3s ease-in-out;
}
#products>article.active {
min-width: 300px;
min-height: 300px;
font-size: 20px;
}
#picText {
position: absolute;
color: #fff;
top: 50%;
left: 50%;
transform: translate(-50%, -50%) rotate(-45deg);
}
#id {
color: #fff;
margin: 15px;
}
#gofwd,
#gobwd {
position: absolute;
top: 50%;
padding: 50px 15px;
z-index: 1;
cursor: pointer;
background-color: rgba(255, 255, 255, .6);
transform: translateY(-50%);
transition: all .3s ease-out;
}
#gofwd:hover,
#gobwd:hover {
background-color: #fff;
}
#gobwd {
left: 0;
}
#gofwd {
right: 0;
}
.can {
position: relative;
}
.bottle:hover {
transform: rotateX(0deg) rotateY(0deg) rotateZ(0deg)
/* translate3d(350px, 190px, 40px) */
scale(0.7);
}
.bottle {
transition: all 0.2s;
width: 10.125px;
-webkit-transform: rotateX(0deg) rotateY(0deg) rotateZ(0deg) translate3d(650px, 190px, 40px);
-moz-transform: rotateX(0deg) rotateY(0deg) rotateZ(0deg) translate3d(650px, 190px, 40px);
transform: rotateX(0deg) rotateY(0deg) rotateZ(0deg) translate3d(350px, 190px, 40px);
-webkit-transform-style: preserve-3d;
-moz-transform-style: preserve-3d;
transform-style: preserve-3d;
transform: scale(0.2);
position: absolute;
}
.bottle0 {
top: 40px;
left: 100px;
}
.bottle1 {
top: 100px;
left: 500px;
}
.bottle2 {
top: 100px;
left: 700px;
}
.bottle>img {
position: absolute;
top: -180px;
left: -182px;
width: 374px;
}
.label {
-webkit-animation: spin 10s infinite linear;
-moz-animation: spin 10s infinite linear;
animation: spin 10s infinite linear;
-webkit-transform-style: preserve-3d;
-moz-transform-style: preserve-3d;
}
.side {
position: absolute;
width: 10.55px;
height: 679px;
margin-bottom: 400px;
}
.bottle0 .side {
background: url("https://i.postimg.cc/BZ8rj2NM/sleve.png");
}
.bottle1 .side {
background: url("https://i.postimg.cc/Fs2RgnN6/passion.png");
}
.bottle2 .side {
background: url("https://i.postimg.cc/zGzJjm40/raspberry.png");
}
#-webkit-keyframes spin {
from {
-webkit-transform: rotateY(0deg);
transform: rotateY(0deg);
}
to {
-webkit-transform: rotateY(-360deg);
transform: rotateY(-360deg);
}
}
#-moz-keyframes spin {
from {
-moz-transform: rotateY(0deg);
transform: rotateY(0deg);
}
to {
-moz-transform: rotateY(-360deg);
transform: rotateY(-360deg);
}
}
#keyframes spin {
from {
-webkit-transform: rotateY(0deg);
-moz-transform: rotateY(0deg);
transform: rotateY(0deg);
}
to {
-webkit-transform: rotateY(-360deg);
-moz-transform: rotateY(-360deg);
transform: rotateY(-360deg);
}
}
#mixin makeSide() {}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-easing/1.4.1/jquery.easing.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<div id="slider">
<span id="gofwd" onClick="gofwd();">></span>
<span id="gobwd" onClick="gobwd();"><</span>
<div id="products">
<article class="active">
<div class="container"></div>
</article>
<article>
<div class="container">
<p id="id">2</p>
</div>
</article>
<article>
<div class="picture">
<p id="id">3</p>
</div>
</article>
<article>
<div class="picture">
<p id="id">4</p>
</div>
</article>
<article>
<div class="picture">
<p id="id">5</p>
</div>
</article>
<article>
<div class="picture">
<p id="id">6</p>
</div>
</article>
<article>
<div class="picture">
<p id="id">7</p>
</div>
</article>
<article>
<div class="picture">
<p id="id">8</p>
</div>
</article>
<article>
<div class="picture">
<p id="id">9</p>
</div>
</article>
<article>
<div class="picture">
<p id="id">10</p>
</div>
</article>
</div>
</div>
If you look at your Javascript Console you should the following error:
you crated the initApp function as a const after calling it, that won't work. You have two options:
move the const initApp up, or
declare it a function like this:
function initApp(index){
// …
}
I want to have the following JavaScript function to transition function between from have none display to block when generate_loading_screen() is called to to when it finishes transition between display block to none. How do I do this?
function generate_loading_screen() {
window.setInterval(function(){
if (progress_percent < 75) {
document.getElementById("loading_screen").style.display = "block";
document.getElementById("body_of").style.filter = "grayscale(1)";
}
else {
document.getElementById("loading_screen").style.display = "none";
document.getElementById("body_of").style.filter = "none";
stop_generating_loading();
}
}, 50);
};
function stop_generating_loading() {
clearInterval(generate_loading_screen);
};
.loading {
position: fixed;
border: 16px solid #dbdbdb;
border-radius: 50%;
border-top: 16px solid #53f442;
margin-left: 44%;
margin-top: 10%;
width: 120px;
height: 120px;
animation: spin 2s linear infinite;
}
#keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
<div class="loading" id="loading_screen" style="display: none;"></div>
Just extra info: progress_percent is a variable that determines how much of the rest of the web-app has loaded. The grayscale filter does not affect the whole page, just the ID body_of
Thanks in advance
Probably better to use a opacity transition by adding a class when your percent reaches 100.
Codepen for working example or see below.
HTML:
<div class="loading" id="loading_screen"></div>
CSS:
.loading {
position: fixed;
border: 16px solid #dbdbdb;
border-radius: 50%;
border-top: 16px solid #53f442;
margin-left: 44%;
margin-top: 10%;
width: 120px;
height: 120px;
animation: spin 2s linear infinite;
opacity: 100%;
transition: opacity 1s ease-in-out;
}
.done_loading {
opacity: 0;
}
#keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
Javascript:
var progress_percent = 25;
var interval;
function generate_loading_screen() {
interval = window.setInterval(function(){
progress_percent += 1; //totest
if (progress_percent > 75) {
document.getElementById("loading_screen").className = "loading done_loading";
//stop_generating_loading();
}
//TESTING
if(progress_percent > 100){
console.log("Reached 100%");
document.getElementById("loading_screen").className = 'loading';
progress_percent = 0;
}
//
}, 50);
};
function stop_generating_loading() {
clearInterval(interval);
};
document.addEventListener('DOMContentLoaded', function(){
generate_loading_screen();
});
Remove all the testing code to get this to work once, you might need to add additional code for your body div. Let me know if you need me to add more to this example!
window.setInterval returns an intervalId which you need to cancel in order to stop the interval
let timer;
function generate_loading_screen() {
timer = window.setInterval(function(){
if (progress_percent < 75) {
document.getElementById("loading_screen").style.display = "block";
document.getElementById("body_of").style.filter = "grayscale(1)";
}
else {
document.getElementById("loading_screen").style.display = "none";
document.getElementById("body_of").style.filter = "none";
stop_generating_loading();
}
}, 50);
};
function stop_generating_loading() {
clearInterval(timer);
};
I have made a slider/seeker out of mousedown and mousemove for my <audio> element. My problem is that as soon as the user leaves the element while still holding their mouse button down, it does not register the mousemove. Here's my code:
/** Variables **/
isPlaying = false;
isBuffering = false;
isScrubbing = false;
isScrubberHolding = false;
tempProgress = 0;
time = playerE.currentTime;
dur = playerE.duration;
/** Binds and Properties **/
player.bind("timeupdate", timeUpdate);
scrubber.bind("mousemove", scrubberGrab);
scrubber.bind("mousedown", scrubberClick);
/** Progress and Buffer **/
function progressWidth(progress) {
var calcProgress = ((progress * 100) + "%");
$(".progress").width(calcProgress);
}
/** Time events **/
function timeUpdate(e) {
/** Update Variables **/
time = playerE.currentTime;
dur = playerE.duration;
/** Update Progress and Buffer **/
if (isScrubbing === false) {
var progress = time / dur;
}
var buffered = playerE.buffered.end(0) / dur;
timeConvert(time);
progressWidth(progress);
}
function setPlayerTime(timeset) {
playerE.currentTime = timeset * dur;
}
function timeConvert(s) {
var h = Math.floor(s / 3600);
s -= h * 3600;
var m = Math.floor(s / 60);
s -= m * 60;
var resultSubstring = ((m < 10 ? '0' + m : m) + ":" + (s < 10 ? '0' + s : s)).substring(0, 5);
$('#playerTime').text(resultSubstring);
}
/** Scrubber **/
$(".player-small").mouseenter(function () {
knob.stop().fadeIn(200);
});
setTimeout(function () {
$(".player-small").mouseleave(function () {
knob.stop().fadeOut(200);
});
}, 3000);
function scrubberClick(e) {
isScrubberHolding = true;
isScrubbing = true;
player.trigger('pause');
var $this = $(this);
var x = e.pageX - $this.offset().left;
var percent = x / $this.width();
progressWidth(percent);
tempProgress = percent;
}
$(document).mouseup(function () {
if (isScrubberHolding === true) {
isScrubberHolding = false;
isScrubbing = false;
setPlayerTime(tempProgress)
player.trigger('play');
} else {
isScrubberHolding = false;
}
})
function scrubberGrab(e) {
if (isScrubberHolding === true) {
var $this = $(this);
var x = e.pageX - $this.offset().left;
var percent = x / $this.width();
tempProgress = percent;
progressWidth(percent);
setPlayerTime(percent)
} else {}
}
See it in action:
var player = $('audio');
var playerE = $('audio')[0];
var playerE = $('audio').get(0);
var canvasviz = $('canvas');
var playbutton = $("#playButton");
var buffering = $("#buffering");
var scrubber = $(".scrubber-con");
var progress = $(".progress");
var buffered = $(".buffered");
var knob = $(".knob");
var analyser = $("#analyzer");
var currentAlbum = "";
var countElement = $('#playlistCount');
var titleElement = $('#trackTitle');
/** Variables **/
isPlaying = false;
isBuffering = false;
isScrubbing = false;
isScrubberHolding = false;
tempProgress = 0;
time = playerE.currentTime;
dur = playerE.duration;
/** Binds and Properties **/
player.bind("timeupdate", timeUpdate);
scrubber.bind("mousemove", scrubberGrab);
scrubber.bind("mousedown", scrubberClick);
/** Progress and Buffer **/
function progressWidth(progress) {
var calcProgress = ((progress * 100) + "%");
$(".progress").width(calcProgress);
}
/** Time events **/
function timeUpdate(e) {
/** Update Variables **/
time = playerE.currentTime;
dur = playerE.duration;
/** Update Progress and Buffer **/
if (isScrubbing === false) {
var progress = time / dur;
}
var buffered = playerE.buffered.end(0) / dur;
timeConvert(time);
progressWidth(progress);
}
function setPlayerTime(timeset) {
playerE.currentTime = timeset * dur;
}
function timeConvert(s) {
var h = Math.floor(s / 3600);
s -= h * 3600;
var m = Math.floor(s / 60);
s -= m * 60;
var resultSubstring = ((m < 10 ? '0' + m : m) + ":" + (s < 10 ? '0' + s : s)).substring(0, 5);
$('#playerTime').text(resultSubstring);
}
/** Scrubber **/
$(".player-small").mouseenter(function () {
knob.stop().fadeIn(200);
});
setTimeout(function () {
$(".player-small").mouseleave(function () {
knob.stop().fadeOut(200);
});
}, 3000);
function scrubberClick(e) {
isScrubberHolding = true;
isScrubbing = true;
player.trigger('pause');
var $this = $(this);
var x = e.pageX - $this.offset().left;
var percent = x / $this.width();
progressWidth(percent);
tempProgress = percent;
}
$(document).mouseup(function () {
if (isScrubberHolding === true) {
isScrubberHolding = false;
isScrubbing = false;
setPlayerTime(tempProgress)
player.trigger('play');
} else {
isScrubberHolding = false;
}
})
function scrubberGrab(e) {
if (isScrubberHolding === true) {
var $this = $(this);
var x = e.pageX - $this.offset().left;
var percent = x / $this.width();
tempProgress = percent;
progressWidth(percent);
setPlayerTime(percent)
} else {}
}
.player-small {
height: 55px;
width: 100%;
background: #ff4081;
}
.player-height-anim {}
.player-small .left {
height: 55px;
float: left;
width: 56%;
overflow: hidden;
}
.player-small .right {
height: 40px;
position: relative;
top: 8px;
float: right;
width: calc(44% - 2px);
overflow: hidden;
border-left: solid 2px rgba(0, 0, 0, .05);
}
.transport {
overflow: auto;
}
.play-button-con {
height: 55px;
width: 55px;
float: left;
overflow: hidden;
}
#buffering {
height: 55px;
width: 55px;
animation: rotating 900ms ease infinite;
background-image: url(img/player-buffering.svg);
background-size: contain;
display: none;
}
#-webkit-keyframes rotating {
from {
-ms-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-webkit-transform: rotate(0deg);
-o-transform: rotate(0deg);
transform: rotate(0deg);
}
to {
-ms-transform: rotate(360deg);
-moz-transform: rotate(360deg);
-webkit-transform: rotate(360deg);
-o-transform: rotate(360deg);
transform: rotate(360deg);
}
}
#keyframes rotating {
from {
-ms-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-webkit-transform: rotate(0deg);
-o-transform: rotate(0deg);
transform: rotate(0deg);
}
to {
-ms-transform: rotate(360deg);
-moz-transform: rotate(360deg);
-webkit-transform: rotate(360deg);
-o-transform: rotate(360deg);
transform: rotate(360deg);
}
}
.rotating {
-webkit-animation: rotating 2s linear infinite;
-moz-animation: rotating 2s linear infinite;
-ms-animation: rotating 2s linear infinite;
-o-animation: rotating 2s linear infinite;
animation: rotating 2s linear infinite;
}
#playButton {
width: 55px;
height: 55px;
font-size: 18px;
text-align: center;
background-image: url(img/player-play.svg);
background-size: contain;
image-rendering: crisp-edges;
-webkit-image-rendering: crisp-edges;
}
.playFailed {
pointer-events: none;
}
.next-button-con {
height: 55px;
width: 55px;
float: left;
}
#nextButton {
width: 55px;
height: 55px;
text-align: center;
font-size: 11px;
background-image: url(img/player-next.svg);
background-size: contain;
}
.scrubber-con {
margin: auto;
margin-top: 12px;
height: 30px;
width: calc(100% - 40px);
overflow: visible;
cursor: pointer;
}
.scrubber-container {
float: left;
height: 55px;
width: calc(100% - 154px);
overflow: hidden;
}
.scrubber {
margin: auto;
height: 5px;
background: rgba(0, 0, 0, .04);
position: relative;
top: 13px;
}
.scrubber .knob {
float: right;
height: 13px;
width: 13px;
position: relative;
bottom: 4px;
left: 5px;
background: white;
border-radius: 50px;
display: none;
}
.scrubber .knob:hover {
cursor: grab;
}
.scrubber .knob:active {
cursor: grabbing;
}
.scrubber .progress {
height: 100%;
float: left;
background: white;
width: 0%;
position: relative;
z-index: 1;
}
.scrubber .buffered {
height: 5px;
position: relative;
width: 0%;
background: rgba(0, 0, 0, .2);
transition: ease 1000ms;
}
.time-con {
float: left;
width: 30px;
height: 55px;
}
.time {
position: relative;
top: 20px;
color: white;
font-size: 13px;
}
.player-small .button {
color: white;
float: left;
cursor: pointer;
}
.player-small .button:hover {
background: rgba(0, 0, 0, .12);
}
.analyzer-con {
float: left;
position: relative;
margin-left: 235px;
width: calc(100% - 650px);
height: 60px;
}
#analyzer {
width: 100%;
height: 45px;
margin-top: 8px;
display: none;
}
audio {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="player-small">
<div class="w-ctrl">
<div class="controls">
<div class="left">
<div class="transport">
<div class="play-button-con">
<div class="button playFailed" id="playButton" onclick="togglePlay()">
</div>
<div id="buffering">
</div>
</div>
<div class="next-button-con">
<div class="button" id="nextButton" onclick="next()"></div>
</div>
<div class="scrubber-container" nmousedown="event.preventDefault ? event.preventDefault() : event.returnValue = false">
<div class="scrubber-con" nmousedown="event.preventDefault ? event.preventDefault() : event.returnValue = false">
<div class="scrubber" draggable="false" nmousedown="event.preventDefault ? event.preventDefault() : event.returnValue = false">
<div class="progress" draggable="false" onmousedown="event.preventDefault ? event.preventDefault() : event.returnValue = false">
<div class="knob" draggable="false" onmousedown="event.preventDefault ? event.preventDefault() : event.returnValue = false"></div>
</div>
<div class="buffered"></div>
</div>
</div>
</div>
<div class="time-con">
<div class="time" id="playerTime">0:00</div>
</div>
</div>
</div>
<div class="right">
<audio id="player" src="your track here" controls="controls" preload="none"></audio>
<div class="info">
<div class="count" id="playlistCount">0/0</div>
<div class="title" id="trackTitle">Track title</div>
</div>
</div>
</div>
</div>
</div>
Grab my custom seeker (left) and move your mouse off the pink area. Now do the same for the audio element (right) you need a track for it to play in order to be able to move its seeker. See how you can drag it even if your mouse is not inside it?
So how can I get this behaviour for my custom seeker?
Since you are binding the mousemove to scrubber, scrubberGrab() will only run when the mouse is over the scrubber element.
Change
scrubber.bind("mousemove", scrubberGrab);
To
$(document).bind("mousemove", scrubberGrab);
function scrubberGrab(e) {
if (isScrubberHolding === true) {
var x = e.pageX - scrubber.offset().left;
var percent = Math.min(Math.max(x / scrubber.width(), 0), 1.0);
tempProgress = percent;
progressWidth(percent);
setPlayerTime(percent);
} else {}
}