jQuery Countdown Timer is not displaying in browser - javascript

Have create a countdown timer by using jQuery. Hence, the countdown timer will only be activated after the user has navigated from the previous page to the current page. Therefore, in the current page, the blocks that are to be displayed will be
1.) Countdown Timer
2.) Scroll roller
Issue:
the Scroll roller is able to be displayed, however not the countdown Timer. What have I done wrong.
Code:
var count = 5;
function updateTimer() {
if (count > 0) {
$("#content").fadeOut('slow', function() {
$("#content").text(count);
$("#content").fadeIn();
count--;
});
} else if (count == 0) {
$("#content").fadeOut('slow', function() {
$("#content").text("Start!");
$("#content").fadeIn();
count--;
/*To display the canvas and countDown() function in 2 sec interval
after the fadein countdown is completed
*/
setTimeout(function() {
//canvasFunction();
//TEST: Countdown Gauge
(function($) {
var settings;
var timer;
var circleSeconds;
var layerSeconds;
var element;
var callbackFunction;
$.fn.final_countdown = function(options, callback) {
element = $(this);
// Element is not visibile
if (!element.is(':visible')) {
return;
}
var defaults = $.extend({
start: undefined,
end: undefined,
now: undefined,
selectors: {
value_seconds: '.clock-seconds .val',
canvas_seconds: 'canvas-seconds'
},
seconds: {
borderColor: '#654321',
borderWidth: '6'
},
}, options);
settings = $.extend({}, defaults, options);
if (settings.start === undefined) {
settings.start = element.data('start');
}
if (settings.end === undefined) {
settings.end = element.data('end');
}
if (settings.now === undefined) {
settings.now = element.data('now');
}
if (element.data('border-color')) {
settings.seconds.borderColor = element.data('border-color');
}
if (settings.now < settings.start) {
settings.start = settings.now;
settings.end = settings.now;
}
if (settings.now > settings.end) {
settings.start = settings.now;
settings.end = settings.now;
}
if (typeof callback == 'function') { // make sure the callback is a function
callbackFunction = callback;
}
responsive();
dispatchTimer();
prepareCounters();
startCounters();
};
function responsive() {
$(window).load(updateCircles);
$(window).on('redraw', function() {
switched = false;
updateCircles();
});
$(window).on('resize', updateCircles);
}
function updateCircles() {
layerSeconds.draw();
}
function convertToDeg(degree) {
return (Math.PI / 180) * degree - (Math.PI / 180) * 90
}
function dispatchTimer() {
timer = {
total: Math.floor((settings.end - settings.start) / 86400),
seconds: 60 - Math.floor((((settings.end - settings.now) % 86400) % 3600) % 60)
}
}
function prepareCounters() {
// Seconds
var seconds_width = $('#' + settings.selectors.canvas_seconds).width()
var secondsStage = new Kinetic.Stage({
container: settings.selectors.canvas_seconds,
width: seconds_width,
height: seconds_width
});
circleSeconds = new Kinetic.Shape({
drawFunc: function(context) {
var seconds_width = $('#' + settings.selectors.canvas_seconds).width()
var radius = seconds_width / 2 - settings.seconds.borderWidth / 2;
var x = seconds_width / 2;
var y = seconds_width / 2;
context.beginPath();
context.arc(x, y, radius, convertToDeg(0), convertToDeg(timer.seconds * 6));
context.fillStrokeShape(this);
$(settings.selectors.value_seconds).html(10 - timer.seconds);
},
stroke: settings.seconds.borderColor,
strokeWidth: settings.seconds.borderWidth
});
layerSeconds = new Kinetic.Layer();
layerSeconds.add(circleSeconds);
secondsStage.add(layerSeconds);
}
function startCounters() {
//var timer.seconds = 10;
var interval = setInterval(function() {
if (timer.seconds > 11) {
if (10 - timer.minutes == 0) {
clearInterval(interval);
if (callbackFunction !== undefined) {
callbackFunction.call(this); // brings the scope to the callback
}
return;
}
timer.seconds = 0;
} else {
timer.seconds++;
}
layerSeconds.draw();
}, 1000);
}
})(jQuery);
//TEST
$("#UserInteraction").show();
//countDown();
}, 2000)
});
$("#content").fadeOut();
} else {
$("#content").fadeOut();
clearInterval(interval);
}
}
setInterval(function() {
updateTimer()
}, 2000);
.countdown-container {
position: relative;
top: 50%;
-webkit-transform: translateY(-50%);
-moz-transform: translateY(-50%);
transform: translateY(-50%);
}
.clock-item .inner {
height: 0px;
padding-bottom: 100%;
position: relative;
width: 100%;
}
.clock-canvas {
background-color: rgba(255, 255, 255, .1);
border-radius: 50%;
height: 0px;
padding-bottom: 100%;
}
.text {
color: #fff;
font-size: 30px;
font-weight: bold;
margin-top: -50px;
position: absolute;
top: 50%;
text-align: center;
text-shadow: 1px 1px 1px rgba(0, 0, 0, 1);
width: 100%;
}
.text .val {
font-size: 50px;
}
.text .type-time {
font-size: 20px;
}
#media (min-width: 768px) and (max-width: 991px) {
.clock-item {
margin-bottom: 30px;
}
}
#media (max-width: 767px) {
.clock-item {
margin: 0px 30px 30px 30px;
}
}
<div id="page2" class="img-wrapper" align="center" style=" position: relative; background-image: url(Image/Page2.png); background-repeat: no-repeat; width: 100%;height: 100%;">
<div id='content'></div>
<!-- <canvas id="canvas" width="300" height="300">
</canvas>
<canvas id="Counter" width="300" height="300">
</canvas>-->
<div id="scroller">
<p id="scrollTopId"></p>
</div>
<div id="UserInteraction" style="display:none" z-index="2">
<img id="roller" style="position: relative; top:1100px; width: 100%" src="image/rolling_pin/Rolling_Pin_Spin000.png" />
<img id="scroll" style="position:absolute; top: 1250px; left: 380px; overflow-y: auto;" src="image/Scroll.png">
</div>
</div>

You have display:none on the root div page2:
<div id="page2" class="img-wrapper" align="center" style=" position: relative; background-image: url(Image/Page2.png); background-repeat: no-repeat; display: none; width: 100%;height: 100%;">
Remove display:none or set it to display:block
https://jsfiddle.net/kebw53ue/1/

Related

Carousel css3 animation acting weird

I've created this 3 item vertical carousel, and need to correct the transition.
My current project can be seen here:
http://hotelfjordgaarden.dk.test.vjm.dk/
I want to create the transition from this pen (the regular swipe/fade carousel transition):
https://codepen.io/marcusmichaels/pen/yGGoLM
If anyone could help me solve this, I would be so greatful!
Thanks in advance!
My HTML:
<div class="container">
<div class="frontpage__content__carousel">
<div class="frontpage__content__carousel__list">
<div class="frontpage__content__carousel__list__item" data-href="//google.com">
<a href="//google.com">
<p class="h1">
Heading
</p>
<p class="sub">
Subheading
</p>
</a>
</div>
<div class="frontpage__content__carousel__list__item" data-href="//google.com">
<a href="//google.com">
<p class="h1">
Heading
</p>
<p class="sub">
Subheading
</p>
</a>
</div>
<div class="frontpage__content__carousel__list__item" data-href="//google.com">
<a href="//google.com">
<p class="h1">
Heading
</p>
<p class="sub">
Subheading
</p>
</a>
</div>
<div class="frontpage__content__carousel__list__item" data-href="//google.com">
<a href="//google.com">
<p class="h1">
Heading
</p>
<p class="sub">
Subheading
</p>
</a>
</div>
<div class="frontpage__content__carousel__list__item" data-href="//google.com">
<a href="//google.com">
<p class="h1">
Heading
</p>
<p class="sub">
Subheading
</p>
</a>
</div>
</div>
<div class="frontpage__content__carousel__navigation">
<div class="prev icon" id="jsGoToPrev"></div>
<div class="next icon" id="jsGoToNext"></div>
</div>
</div>
</div>
My SASS:
.frontpage {
width: 100%;
overscroll-behavior: none;
.header {
background: white;
display: flex;
width: 100%;
justify-content: center;
align-items: center;
height: 138px;
}
.frontpage__content {
width: 100%;
height: 100%;
display: flex;
text-align: center;
align-items: center;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
position: relative;
overflow: hidden;
#media only screen and (max-width: #screen-sm-max) {
> div {
width: 100%;
margin-left: auto;
margin-right: auto;
}
}
&::before {
content: '';
display: block;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-color: #8fa2a6;
z-index: -2;
}
&__video {
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 0;
z-index: -1;
opacity: 0.4;
}
// carousel wrapper
&__carousel {
overflow: hidden;
& * {
box-sizing: border-box;
}
// carousel
&__list {
overflow: hidden;
transform-style: preserve-3d;
&__item {
// disable user selection
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
opacity: 0;
position: absolute;
top: 0;
left: 0;
transition: transform .5s, top .5s, z-index .5s;
width: 100%;
z-index: -100;
margin: auto;
a {
.h1 {
font-size: 18px;
color: white;
text-transform: uppercase;
margin: 0;
}
.sub {
font-size: 14px;
font-weight: 500;
color: white;
margin: 0;
}
}
&.prev {
transform: translateY(-100%);
z-index: 800;
opacity: 0.5;
}
&.next {
transform: translateY(420%);
#media only screen and (min-width: #screen-lg) {
transform: translateY(500%);
}
z-index: 800;
opacity: 0.5;
}
&.active {
opacity: 1;
position: relative;
z-index: 900;
padding: 40px 0;
margin: 20px 0;
border: 1px solid rgba(255, 255, 255, 0.4);
border-left: none;
border-right: none;
a {
.h1 {
font-size: 18px;
}
.sub {
font-size: 16px;
}
}
}
}
}
&__navigation {
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
display: none;
position: relative;
.icon {
display: flex;
align-items: center;
justify-content: center;
width: 40px;
height: 40px;
font-size: 20px;
border-radius: 50%;
border: 2px solid rgba(white, 0.5);
color: rgba(white, 0.5);
font-weight: 400;
font-family: 'Font Awesome 5 Pro';
position: fixed;
left: 60px;
cursor: pointer;
}
.prev {
top: 40%;
&::before {
content: '\f176';
}
}
.next {
top: 70%;
&::before {
content: '\f175';
}
}
}
}
}
// tablet portrait
#media only screen and (min-width: #screen-sm) {
height: 100vh;
.frontpage__content__carousel__list__item {
a {
.h1 {
font-size: 30px;
}
.sub {
font-size: 10px;
}
}
&.active {
a {
.h1 {
font-size: 40px;
}
.sub {
font-size: 24px;
}
}
}
}
}
// tablet landscape
#media only screen and (min-width: #screen-md) {
.frontpage__content__carousel__list__item {
a {
.h1 {
font-size: 30px;
}
.sub {
font-size: 10px;
}
}
&.active {
a {
.h1 {
font-size: 40px;
}
.sub {
font-size: 24px;
}
}
}
}
}
// desktop
#media only screen and (min-width: #screen-lg) {
.frontpage__content__carousel__navigation {
display: block;
}
.frontpage__content__carousel__list__item {
a {
.h1 {
font-size: 30px;
}
.sub {
font-size: 10px;
}
}
&.active {
a {
.h1 {
font-size: 60px;
}
.sub {
font-size: 30px;
}
}
}
}
}
}
My Javascript:
if ($('.frontpage__content').length > 0) {
$(document).ready(function () {
adjustFrontpageContentHeight();
});
$(window).resize(function () {
adjustFrontpageContentHeight();
});
function adjustFrontpageContentHeight() {
var $windowHeight = $(window).height();
var $headerHeight = $('.header').height();
$('.frontpage__content').height($windowHeight - $headerHeight);
}
(function ($) {
var carousel = $('.frontpage__content__carousel');
var list = $('.frontpage__content__carousel__list');
var items = $('.frontpage__content__carousel__list__item');
var totalItems = items.length;
var slide = 0;
var moving = true;
var itemClassName = 'frontpage__content__carousel__list__item';
function getElements() {
var prev = $('.frontpage__content__carousel__list__item.prev');
var active = $('.frontpage__content__carousel__list__item.active');
var next = $('.frontpage__content__carousel__list__item.next');
var beforePrev;
if (prev.prev().length > 0) {
beforePrev = prev.prev();
} else if (prev.data('index') == 0) {
beforePrev = $('[data-index=' + (totalItems - 1) + ']')
} else {
beforePrev = $('[data-index=' + (prev.data('index') - 1) + ']');
}
var afterNext;
if (next.next().length > 0) {
afterNext = next.next();
} else {
afterNext = $('[data-index=' + (next.data('index') + 1) + ']');
}
return {
beforePrev: beforePrev,
prev : prev,
active : active,
next : next,
afterNext : afterNext,
}
}
function setInitialClasses() {
items[totalItems - 1].className = itemClassName + ' prev';
items[0].className = itemClassName + ' active';
items[1].className = itemClassName + ' next';
}
function goToPrev() {
if (!moving) {
// if first slide, set as last slide, else -1
if (slide === 0) {
slide = (totalItems - 1);
} else {
slide--;
}
goToSlide(slide);
//prependPrev();
}
}
function goToNext() {
if (!moving) {
// if last slide, reset to 0, else +1
if (slide === (totalItems - 1)) {
slide = 0;
} else {
slide++;
}
goToSlide(slide);
//appendNext();
}
}
function goToSlide(slide) {
if (!moving) {
disableInteraction();
// Update the "old" adjacent slides with "new" ones
var newPrevious = slide - 1,
newNext = slide + 1,
oldPrevious = slide - 2,
oldNext = slide + 2;
// Checks and updates if the new slides are out of bounds
if (newPrevious <= 0) {
oldPrevious = (totalItems - 1);
} else if (newNext >= (totalItems - 1)) {
oldNext = 0;
}
// Checks and updates if slide is at the beginning/end
if (slide === 0) {
newPrevious = (totalItems - 1);
oldPrevious = (totalItems - 2);
oldNext = (slide + 1);
} else if (slide === (totalItems - 1)) {
newPrevious = (slide - 1);
newNext = 0;
oldNext = 1;
}
items.each(function() {
$(this).removeClass('active prev next');
});
// Add new classes
items[newPrevious].className = itemClassName + " prev";
items[slide].className = itemClassName + " active";
items[newNext].className = itemClassName + " next";
}
}
function disableInteraction() {
moving = true;
// set timeout to same as transition length
setTimeout(function () {
moving = false;
}, 500);
}
function setEventListeners() {
// click listeners
$('body').on('click', '#jsGoToPrev', function () {
goToPrev();
});
$('body').on('click', '#jsGoToNext', function () {
goToNext();
});
$('body').on('click', '.frontpage__content__carousel__list__item.prev', function () {
goToPrev();
});
$('body').on('click', '.frontpage__content__carousel__list__item.next', function () {
goToNext();
});
$('body').on('click', '.frontpage__content__carousel__list__item.active', function () {
if (!moving) {
window.location.href = $(this).data('href');
}
});
// mousewheel scroll listener
$('body').on('wheel', carousel.selector, function (e) {
if (e.originalEvent.deltaY < 0) {
goToPrev();
} else if (e.originalEvent.deltaY > 0) {
goToNext();
}
});
// touch scroll listener
var ts;
var te;
$('body').on('touchstart', function (e) {
ts = e.originalEvent.touches[0].clientY;
});
$('body').on('touchend', function (e) {
te = e.originalEvent.changedTouches[0].clientY;
if (ts > te+5) {
goToNext();
} else if (ts < te-5) {
goToPrev();
}
});
}
function prependPrev() {
list.prepend(getElements().prev);
}
function appendNext() {
list.append(getElements().next);
}
function initCarousel() {
// nullify links href after load - this is due to SEO
items.each(function () {
$(this).find('a').attr('href', 'javascript:void(0)');
});
setInitialClasses();
setEventListeners();
prependPrev();
moving = false;
}
$(document).ready(function () {
initCarousel();
});
})(jQuery);
}
What I eventually wounded up doing is:
Make my carousel DIV/container overflow: hidden, so I can have items inside which are hidden due to overflow.
I then use jQuery to scroll my div when a non-active item is clicked.
The entire script for the page is here:
if ($('.frontpage__content').length > 0) {
$('.frontpage__content__carousel__list__item ').click(function (e) {
if (!$(this).hasClass('active')) {
e.preventDefault();
var direction = 'up';
if ($(this).index() >= $('.frontpage__content__carousel__list__item.active').index()) {
direction = 'down';
}
$('.frontpage__content__carousel__list__item').removeClass('active');
$(this).addClass('active');
var _this = this;
var scrollTop = 0;
var items = $('.frontpage__content__carousel__list__item');
items.each(function (index, item) {
if ($(this).is($(_this).prev()) || $(_this).index() == 0) {
return false;
}
scrollTop += $(this).height();
});
$('.frontpage__content__carousel__list').stop().animate({
'scrollTop': scrollTop
});
}
});
function goToPrev() {
$('.frontpage__content__carousel__list__item.active').prev().trigger('click');
}
function goToNext() {
$('.frontpage__content__carousel__list__item.active').next().trigger('click');
}
$('#jsGoToPrev').click(function () {
goToPrev();
});
$('#jsGoToNext').click(function () {
goToNext();
});
$(window).resize(function () {
adjustFrontpageContentHeight();
});
function adjustFrontpageContentHeight() {
var $windowHeight = $(window).height();
var $headerHeight = $('.header').height();
$('.frontpage__content').height($windowHeight - $headerHeight);
}
var moving = false;
// mousewheel scroll listener
$('body').on('wheel', '.frontpage__content__carousel', function (e) {
if (!moving) {
moving = true;
setTimeout(function () {
moving = false;
}, 250);
if (e.originalEvent.deltaY < 0) {
goToPrev();
} else if (e.originalEvent.deltaY > 0) {
goToNext();
}
}
});
// touch scroll listener
var ts;
var te;
$('body').on('touchstart', '.frontpage__content__carousel', function (e) {
ts = e.originalEvent.touches[0].clientY;
});
$('body').on('touchend', '.frontpage__content__carousel', function (e) {
te = e.originalEvent.changedTouches[0].clientY;
if (ts > te + 5) {
goToNext();
} else if (ts < te - 5) {
goToPrev();
}
});
}

Vue - Convert html audio player into component

I'm converting a player in html into a Vue component.
Half of the component is already created, only the time control slider is missing.
Here is the html player code (Lines with multiple tabs are already implemented in the Vue component):
var audioPlayer = document.querySelector('.green-audio-player');
var playPause = audioPlayer.querySelector('#playPause');
var playpauseBtn = audioPlayer.querySelector('.play-pause-btn');
var loading = audioPlayer.querySelector('.loading');
var progress = audioPlayer.querySelector('.progress');
var sliders = audioPlayer.querySelectorAll('.slider');
var player = audioPlayer.querySelector('audio');
var currentTime = audioPlayer.querySelector('.current-time');
var totalTime = audioPlayer.querySelector('.total-time');
var speaker = audioPlayer.querySelector('#speaker');
var draggableClasses = ['pin'];
var currentlyDragged = null;
window.addEventListener('mousedown', function(event) {
if(!isDraggable(event.target)) return false;
currentlyDragged = event.target;
let handleMethod = currentlyDragged.dataset.method;
this.addEventListener('mousemove', window[handleMethod], false);
window.addEventListener('mouseup', () => {
currentlyDragged = false;
window.removeEventListener('mousemove', window[handleMethod], false);
}, false);
});
playpauseBtn.addEventListener('click', togglePlay);
player.addEventListener('timeupdate', updateProgress);
player.addEventListener('loadedmetadata', () => {
totalTime.textContent = formatTime(player.duration);
});
player.addEventListener('canplay', makePlay);
player.addEventListener('ended', function(){
playPause.attributes.d.value = "M18 12L0 24V0";
player.currentTime = 0;
});
sliders.forEach(slider => {
let pin = slider.querySelector('.pin');
slider.addEventListener('click', window[pin.dataset.method]);
});
function isDraggable(el) {
let canDrag = false;
let classes = Array.from(el.classList);
draggableClasses.forEach(draggable => {
if(classes.indexOf(draggable) !== -1)
canDrag = true;
})
return canDrag;
}
function inRange(event) {
let rangeBox = getRangeBox(event);
let rect = rangeBox.getBoundingClientRect();
let direction = rangeBox.dataset.direction;
if(direction == 'horizontal') {
var min = rangeBox.offsetLeft;
var max = min + rangeBox.offsetWidth;
if(event.clientX < min || event.clientX > max) return false;
} else {
var min = rect.top;
var max = min + rangeBox.offsetHeight;
if(event.clientY < min || event.clientY > max) return false;
}
return true;
}
function updateProgress() {
var current = player.currentTime;
var percent = (current / player.duration) * 100;
progress.style.width = percent + '%';
currentTime.textContent = formatTime(current);
}
function getRangeBox(event) {
let rangeBox = event.target;
let el = currentlyDragged;
if(event.type == 'click' && isDraggable(event.target)) {
rangeBox = event.target.parentElement.parentElement;
}
if(event.type == 'mousemove') {
rangeBox = el.parentElement.parentElement;
}
return rangeBox;
}
function getCoefficient(event) {
let slider = getRangeBox(event);
let rect = slider.getBoundingClientRect();
let K = 0;
if(slider.dataset.direction == 'horizontal') {
let offsetX = event.clientX - slider.offsetLeft;
let width = slider.clientWidth;
K = offsetX / width;
} else if(slider.dataset.direction == 'vertical') {
let height = slider.clientHeight;
var offsetY = event.clientY - rect.top;
K = 1 - offsetY / height;
}
return K;
}
function rewind(event) {
if(inRange(event)) {
player.currentTime = player.duration * getCoefficient(event);
}
}
function formatTime(time) {
var min = Math.floor(time / 60);
var sec = Math.floor(time % 60);
return min + ':' + ((sec<10) ? ('0' + sec) : sec);
}
function togglePlay() {
if(player.paused) {
playPause.attributes.d.value = "M0 0h6v24H0zM12 0h6v24h-6z";
player.play();
} else {
playPause.attributes.d.value = "M18 12L0 24V0";
player.pause();
}
}
function makePlay() {
playpauseBtn.style.display = 'block';
loading.style.display = 'none';
}
.audio.green-audio-player {
width: 400px;
min-width: 300px;
height: 56px;
box-shadow: 0 4px 16px 0 rgba(0, 0, 0, 0.07);
display: flex;
justify-content: space-between;
align-items: center;
padding-left: 24px;
padding-right: 24px;
border-radius: 4px;
user-select: none;
-webkit-user-select: none;
background-color: #fff;
}
.audio.green-audio-player .play-pause-btn {
display: none;
cursor: pointer;
}
.audio.green-audio-player .spinner {
width: 18px;
height: 18px;
background-image: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/355309/loading.png);
background-size: cover;
background-repeat: no-repeat;
animation: spin 0.4s linear infinite;
}
.audio.green-audio-player .slider {
flex-grow: 1;
background-color: #D8D8D8;
cursor: pointer;
position: relative;
}
.audio.green-audio-player .slider .progress {
background-color: #44BFA3;
border-radius: inherit;
position: absolute;
pointer-events: none;
}
.audio.green-audio-player .slider .progress .pin {
height: 16px;
width: 16px;
border-radius: 8px;
background-color: #44BFA3;
position: absolute;
pointer-events: all;
box-shadow: 0px 1px 1px 0px rgba(0, 0, 0, 0.32);
}
.audio.green-audio-player .controls {
font-family: 'Roboto', sans-serif;
font-size: 16px;
line-height: 18px;
color: #55606E;
display: flex;
flex-grow: 1;
justify-content: space-between;
align-items: center;
margin-left: 24px;
}
.audio.green-audio-player .controls .slider {
margin-left: 16px;
margin-right: 16px;
border-radius: 2px;
height: 4px;
}
.audio.green-audio-player .controls .slider .progress {
width: 0;
height: 100%;
}
.audio.green-audio-player .controls .slider .progress .pin {
right: -8px;
top: -6px;
}
.audio.green-audio-player .controls span {
cursor: default;
}
svg, img {
display: block;
}
#keyframes spin {
from {
transform: rotateZ(0);
}
to {
transform: rotateZ(1turn);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div class="audio green-audio-player">
<div class="loading">
<div class="spinner"></div>
</div>
<div class="play-pause-btn">
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="24" viewBox="0 0 18 24">
<path fill="#566574" fill-rule="evenodd" d="M18 12L0 24V0" class="play-pause-icon" id="playPause"/>
</svg>
</div>
<div class="controls">
<span class="current-time">0:00</span>
<div class="slider" data-direction="horizontal">
<div class="progress">
<div class="pin" id="progress-pin" data-method="rewind"></div>
</div>
</div>
<span class="total-time">0:00</span>
</div>
<audio>
<source src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/355309/Swing_Jazz_Drum.mp3" type="audio/mpeg">
</audio>
</div>
Html Codepen: https://codepen.io/caiokawasaki/pen/JwVwry
Here is the Vue component:
Vue.component('audio-player', {
props: ['message'],
data: () => ({
audio: undefined,
loaded: false,
playing: false,
currentTime: '00:00',
totalTime: '00:00',
percent: '0%',
draggableClasses: ['pin'],
currentlyDragged: null
}),
computed: {},
methods: {
formatTime(time) {
var min = Math.floor(time / 60);
var sec = Math.floor(time % 60);
return min + ':' + ((sec < 10) ? ('0' + sec) : sec);
},
loadedMetaData() {
this.totalTime = this.formatTime(this.audio.duration)
},
canPlay() {
this.loaded = true
},
timeUpdate(){
var current = this.audio.currentTime;
var percent = (current / this.audio.duration) * 100;
this.percent = percent + '%';
this.currentTime = this.formatTime(current);
},
ended(){
this.playing = false
this.audio.currentTime = 0
},
isDraggable(el) {
let canDrag = false;
let classes = Array.from(el.classList);
this.draggableClasses.forEach(draggable => {
if (classes.indexOf(draggable) !== -1)
canDrag = true;
})
return canDrag;
},
inRange(event) {
let rangeBox = getRangeBox(event);
let rect = rangeBox.getBoundingClientRect();
let direction = rangeBox.dataset.direction;
if (direction == 'horizontal') {
var min = rangeBox.offsetLeft;
var max = min + rangeBox.offsetWidth;
if (event.clientX < min || event.clientX > max) return false;
} else {
var min = rect.top;
var max = min + rangeBox.offsetHeight;
if (event.clientY < min || event.clientY > max) return false;
}
return true;
},
togglePlay() {
if (this.audio.paused) {
this.audio.play();
this.playing = true;
} else {
this.audio.pause();
this.playing = false;
}
},
makePlay() {
playpauseBtn.style.display = 'block';
loading.style.display = 'none';
},
getRangeBox(event) {
let rangeBox = event.target;
let el = currentlyDragged;
if (event.type == 'click' && isDraggable(event.target)) {
rangeBox = event.target.parentElement.parentElement;
}
if (event.type == 'mousemove') {
rangeBox = el.parentElement.parentElement;
}
return rangeBox;
},
getCoefficient(event) {
let slider = getRangeBox(event);
let rect = slider.getBoundingClientRect();
let K = 0;
if (slider.dataset.direction == 'horizontal') {
let offsetX = event.clientX - slider.offsetLeft;
let width = slider.clientWidth;
K = offsetX / width;
} else if (slider.dataset.direction == 'vertical') {
let height = slider.clientHeight;
var offsetY = event.clientY - rect.top;
K = 1 - offsetY / height;
}
return K;
},
rewind(event) {
if (this.inRange(event)) {
this.audio.currentTime = this.audio.duration * getCoefficient(event);
}
}
},
mounted() {
this.audio = this.$refs.audio
},
template: `<div class="audio-message-content">
<a v-if="loaded" class="play-pause-btn" href="#" :title="playing ? 'Clique aqui para pausar o audio' : 'Clique aqui ouvir o audio'" #click.prevent="togglePlay">
<svg key="pause" v-if="playing" x="0px" y="0px" viewBox="0 0 18 20" style="width: 18px; height: 20px; margin-top: -10px">
<path d="M17.1,20c0.49,0,0.9-0.43,0.9-0.96V0.96C18,0.43,17.6,0,17.1,0h-5.39c-0.49,0-0.9,0.43-0.9,0.96v18.07c0,0.53,0.4,0.96,0.9,0.96H17.1z M17.1,20"/>
<path d="M6.29,20c0.49,0,0.9-0.43,0.9-0.96V0.96C7.19,0.43,6.78,0,6.29,0H0.9C0.4,0,0,0.43,0,0.96v18.07C0,19.57,0.4,20,0.9,20H6.29z M6.29,20"/>
</svg>
<svg key="play" v-else x="0px" y="0px" viewBox="0 0 18 22" style="width: 18px; height: 22px; margin-top: -11px">
<path d="M17.45,10.01L1.61,0.14c-0.65-0.4-1.46,0.11-1.46,0.91V20.8c0,0.81,0.81,1.32,1.46,0.91l15.84-9.87C18.1,11.43,18.1,10.41,17.45,10.01L17.45,10.01z M17.45,10.01"/>
</svg>
</a>
<div v-else class="loading">
<div class="spinner"></div>
</div>
<div class="controls">
<span class="current-time">{{ currentTime }}</span>
<div class="slider" data-direction="horizontal" #click="">
<div class="progress" :style="{width: percent}">
<div class="pin" id="progress-pin" data-method="rewind"></div>
</div>
</div>
<span class="total-time">{{ totalTime }}</span>
</div>
<audio ref="audio" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/355309/Swing_Jazz_Drum.mp3" #loadedmetadata="loadedMetaData" #canplay="canPlay" #timeupdate="timeUpdate" #ended="ended"></audio>
</div>`
})
var app = new Vue({
el: '#app'
})
.audio-message-content {
width: 400px;
min-width: 300px;
height: 56px;
box-shadow: 0 4px 16px 0 rgba(0, 0, 0, 0.07);
display: flex;
justify-content: space-between;
align-items: center;
padding-left: 24px;
padding-right: 24px;
border-radius: 4px;
user-select: none;
-webkit-user-select: none;
background-color: #fff;
}
.audio-message-content .play-pause-btn {
position: relative;
width: 18px;
height: 22px;
cursor: pointer;
}
.audio-message-content .play-pause-btn svg {
display: block;
position: absolute;
top: 50%;
left: 50%;
margin-left: -9px;
}
.audio-message-content .spinner {
width: 18px;
height: 18px;
background-image: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/355309/loading.png);
background-size: cover;
background-repeat: no-repeat;
animation: spin 0.4s linear infinite;
}
.audio-message-content .slider {
flex-grow: 1;
background-color: #D8D8D8;
cursor: pointer;
position: relative;
}
.audio-message-content .slider .progress {
background-color: #44BFA3;
border-radius: inherit;
position: absolute;
pointer-events: none;
}
.audio-message-content .slider .progress .pin {
height: 16px;
width: 16px;
border-radius: 8px;
background-color: #44BFA3;
position: absolute;
pointer-events: all;
box-shadow: 0px 1px 1px 0px rgba(0, 0, 0, 0.32);
}
.audio-message-content .controls {
font-family: 'Roboto', sans-serif;
font-size: 16px;
line-height: 18px;
color: #55606E;
display: flex;
flex-grow: 1;
justify-content: space-between;
align-items: center;
margin-left: 24px;
}
.audio-message-content .controls .slider {
margin-left: 16px;
margin-right: 16px;
border-radius: 2px;
height: 4px;
}
.audio-message-content .controls .slider .progress {
width: 0;
height: 100%;
}
.audio-message-content .controls .slider .progress .pin {
right: -8px;
top: -6px;
}
.audio-message-content .controls span {
cursor: default;
}
svg, img {
display: block;
}
#keyframes spin {
from {
transform: rotateZ(0);
}
to {
transform: rotateZ(1turn);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<audio-player></audio-player>
</div>
Vue Component Codepen: https://codepen.io/caiokawasaki/pen/QzRMwz
Functions like the following I could not understand nor find anything on the internet:
window[handleMethod]
window[pin.dataset.method]
Can anyone help me finalize this component?
Edit
I've converted all of the html and javascript into a Vue component but anyway it still is not working properly.
The only thing that is not working properly is the progress bar. It needs to perform two functions:
Clicking it should go to the desired time.
When clicking on the pin and drag it should go to the desired time.
I use Vue Cli, neither of the above two work in the form of .vue files, but in Codepen normally written only function 2 works.
Codepen: https://codepen.io/caiokawasaki/pen/VqOqBQ
The function: window[handleMethod] is executed by deriving the name of the method off of the data- property from the pin element:
<div class="pin" id="progress-pin" data-method="rewind"></div>
So window[handleMethod] is equivalent to window.rewind()
The same is true for window[pin.dataset.method].
So in your case:
this[handleMethod](event)
and:
this[pin.dataset.method](event)
Should be suitable replacements.

mousedown and touchstart not registering on mobile devices

I have created the following simple image comparison slider - modified from the version on w3schools (I know my mistake to use their code).
This all works fine on a desktop but when I try to use it on a mobile, nothing happens - it doesn't even register the console.log on the mousedown/touchstart (when I press on the slider button with my finger).
I was wondering if anyone could spot anything obvious with why it isn't working on mobile devices
(() => {
$.fn.imageComparisonSlider = function() {
var returnValue = this.each((index, item) => {
var $container = $(this);
var $overlay = $container.find('.image-comparison-slider__bottom-image');
var $slider = $('<span class="image-comparison-slider__slider"></span>');
var $window = $(window);
var touchStarted = false;
var width = $container.outerWidth();
$container.prepend($slider);
$container.on('mousedown touchstart', '.image-comparison-slider__slider', event => {
event.preventDefault();
console.log('touchstart');
touchStarted = true;
});
$window.on("mousemove touchmove", windowEvent => {
if (touchStarted) {
// get the cursor's x position:
let pos = getCursorPos(windowEvent);
// prevent the slider from being positioned outside the image:
if (pos < 0) pos = 0;
if (pos > width) pos = width;
// execute a function that will resize the overlay image according to the cursor:
slide(pos);
}
});
$window.on('mouseup touchend', event => {
event.preventDefault();
touchStarted = false;
});
function getCursorPos(e) {
var thisEvent = e || window.event;
// calculate the cursor's x coordinate, relative to the image
return thisEvent.pageX - $container.offset().left;
}
function slide(x) {
// set the width of the overlay
$overlay.width(width - x);
// position the slider
$slider[0].style.left = x + 'px';
}
function resetSlider() {
$overlay.width('50%');
$slider[0].style.left = $overlay.width() + 'px'
width = $container.outerWidth();
}
});
return returnValue;
};
})($);
$('.image-comparison-slider__container').imageComparisonSlider();
.image {
display: block;
width: 100%;
}
.image-comparison-slider__title {
text-align: center;
}
.image-comparison-slider__container,
.image-comparison-slider__image-holder {
position: relative;
}
.image-comparison-slider__bottom-image {
position: absolute;
overflow: hidden;
top: 0;
right: 0;
bottom: 0;
z-index: 1;
width: 50%;
}
.image-comparison-slider__caption {
position: absolute;
padding: 1rem;
color: white;
background: rgba(0, 0, 0, 0.6);
z-index: 2;
white-space: nowrap;
}
.image-comparison-slider__top-image .image-comparison-slider__caption {
top: 0;
left: 0;
}
.image-comparison-slider__bottom-image .image-comparison-slider__caption {
bottom: 0;
right: 0;
}
.image-comparison-slider__image {
display: block;
z-index: 1;
}
.image-comparison-slider__bottom-image .image {
position: absolute;
right: 0;
top: 0;
height: 100%;
width: auto;
}
.image-comparison-slider__slider {
position: absolute;
z-index: 3;
cursor: ew-resize;
/*set the appearance of the slider:*/
width: 50px;
height: 50px;
background-color: rgba(255, 96, 38, 0.8);
border-radius: 50%;
top: 50%;
left: 50%;
display: flex;
justify-content: center;
align-items: center;
transform: translate(-50%, -50%);
}
.image-comparison-slider__slider:after {
content: "< >";
color: white;
font-weight: bold;
font-size: 25px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="image-comparison-slider__container">
<div class="image-comparison-slider__image-holder image-comparison-slider__top-image">
<img src="https://www.fillmurray.com/g/400/300" alt="A test image 1" class="image">
<div class="image-comparison-slider__caption">Left Image</div>
</div>
<div class="image-comparison-slider__image-holder image-comparison-slider__bottom-image">
<img src="https://www.fillmurray.com/400/300" alt="A test image 2" class="image">
<div class="image-comparison-slider__caption">Right Image</div>
</div>
</div>
Fiddle link for code
Ok have managed to fix this - the touch wasn't registering because of the transform so I changed that and just used negative margin as the button was a fixed size.
I then had to fix the thisEvent.pageX for android - so did a check with isNaN and then set it to e.originalEvent.touches[0].pageX if it was true.
Working version:
(() => {
$.fn.imageComparisonSlider = function() {
var returnValue = this.each((index, item) => {
var $container = $(this);
var $overlay = $container.find('.image-comparison-slider__bottom-image');
var $slider = $('<span class="image-comparison-slider__slider"></span>');
var $window = $(window);
var touchStarted = false;
var width = $container.outerWidth();
$container.prepend($slider);
$container.on('mousedown touchstart', '.image-comparison-slider__slider', event => {
event.preventDefault();
console.log('touchstart');
touchStarted = true;
});
$window.on("mousemove touchmove", windowEvent => {
if (touchStarted) {
// get the cursor's x position:
let pos = getCursorPos(windowEvent);
// prevent the slider from being positioned outside the image:
if (pos < 0) pos = 0;
if (pos > width) pos = width;
// execute a function that will resize the overlay image according to the cursor:
slide(pos);
}
});
$window.on('mouseup touchend', event => {
event.preventDefault();
touchStarted = false;
});
function getCursorPos(e) {
var thisEvent = e || window.event;
let xVal = thisEvent.pageX;
if (isNaN(xVal)) {
xVal = e.originalEvent.touches[0].pageX;
}
// calculate the cursor's x coordinate, relative to the image
return xVal - $container.offset().left;
}
function slide(x) {
// set the width of the overlay
$overlay.width(width - x);
// position the slider
$slider[0].style.left = x + 'px';
}
function resetSlider() {
$overlay.width('50%');
$slider[0].style.left = $overlay.width() + 'px'
width = $container.outerWidth();
}
});
return returnValue;
};
})($);
$('.image-comparison-slider__container').imageComparisonSlider();
.image {
display: block;
width: 100%;
}
.image-comparison-slider__title {
text-align: center;
}
.image-comparison-slider__container,
.image-comparison-slider__image-holder {
position: relative;
}
.image-comparison-slider__bottom-image {
position: absolute;
overflow: hidden;
top: 0;
right: 0;
bottom: 0;
z-index: 1;
width: 50%;
}
.image-comparison-slider__caption {
position: absolute;
padding: 1rem;
color: white;
background: rgba(0, 0, 0, 0.6);
z-index: 2;
white-space: nowrap;
}
.image-comparison-slider__top-image .image-comparison-slider__caption {
top: 0;
left: 0;
}
.image-comparison-slider__bottom-image .image-comparison-slider__caption {
bottom: 0;
right: 0;
}
.image-comparison-slider__image {
display: block;
z-index: 1;
}
.image-comparison-slider__bottom-image .image {
position: absolute;
right: 0;
top: 0;
height: 100%;
width: auto;
}
.image-comparison-slider__slider {
position: absolute;
z-index: 3;
cursor: ew-resize;
width: 50px;
height: 50px;
background-color: rgba(255, 96, 38, 0.8);
border-radius: 50%;
top: 50%;
left: 50%;
display: flex;
justify-content: center;
align-items: center;
margin: -25px 0 0 -25px;
}
.image-comparison-slider__slider:after {
content: "< >";
color: white;
font-weight: bold;
font-size: 25px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="image-comparison-slider__container">
<div class="image-comparison-slider__image-holder image-comparison-slider__top-image">
<img src="https://www.fillmurray.com/g/400/300" alt="A test image 1" class="image">
<div class="image-comparison-slider__caption">Left Image</div>
</div>
<div class="image-comparison-slider__image-holder image-comparison-slider__bottom-image">
<img src="https://www.fillmurray.com/400/300" alt="A test image 2" class="image">
<div class="image-comparison-slider__caption">Right Image</div>
</div>
</div>

Reset JavaScript interval instead of clearing it

I am working on a custom image carousel, using jQuery and CSS. My aim is to make it really lightweight but with enough features.
The script has an auto feature that I want to be stopped if the user clicks a bullet. I am using clearInterval for this purpose.
I would like to reset that interval, instead of clearing it. In other words, when the user clicks a bullet, I want that interval between two slides to be a "full" one (of 4 seconds).
Here is the code:
var $elm = $('.slider'),
$slidesContainer = $elm.find('.slider-container'),
slides = $slidesContainer.children('a'),
slidesCount = slides.length,
slideHeight = $(slides[0]).find('img').outerHeight(false),
animationspeed = 300,
animationInterval = 4000;
// Set (initial) z-index for each slide
var setZindex = function() {
for (var i = 0; i < slidesCount; i++) {
$(slides[i]).css('z-index', slidesCount - i);
}
};
setZindex();
var displayImageBeforeClick = null;
var setActiveSlide = function() {
$(slides).removeClass('active');
$(slides[activeIdx]).addClass('active');
};
var advanceFunc = function() {
if ($('.slider-nav li.activeSlide').index() + 1 != $('.slider-nav li').length) {
$('.slider-nav li.activeSlide').next().find('a').trigger('click');
} else {
$('.slider-nav li:first').find('a').trigger('click');
}
}
var autoAdvance = setInterval(advanceFunc, animationInterval);
//Set slide height
$(slides).css('height', slideHeight);
// Append bullets
for (var i = 0; i < slidesCount; i++) {
var bullets = '<li>' + i + '</li>';
if (i == 0) {
// active bullet
var bullets = '<li class="activeSlide">' + i + '</li>';
// active slide
$(slides[0]).addClass('active');
}
$('.slider-nav').append(bullets);
};
var slideUpDown = function() {
// set top property for all the slides
$(slides).not(displayImageBeforeClick).css('top', slideHeight);
// then animate to the next slide
$(slides[activeIdx]).animate({
'top': 0
}, animationspeed);
$(displayImageBeforeClick).animate({
'top': "-100%"
}, animationspeed);
};
$('.slider-nav a').on('click', function(event) {
event.preventDefault();
displayImageBeforeClick = $(".slider-container .active");
activeIdx = $(this).text();
if ($(slides[activeIdx]).hasClass("active")) {
return false;
}
$('.slider-nav a').closest('li').removeClass('activeSlide');
$(this).closest('li').addClass('activeSlide');
// Stop autoadvance if user clicks bullet
if (event.originalEvent !== undefined) {
clearInterval(autoAdvance);
}
setActiveSlide();
slideUpDown();
});
body * {
box-sizing: border-box;
}
.container {
max-width: 1200px;
margin: 0 auto;
}
.slider {
width: 100%;
height: 300px;
position: relative;
overflow: hidden;
}
.slider .slider-nav {
text-align: center;
position: absolute;
padding: 0;
margin: 0;
left: 10px;
right: 10px;
bottom: 2px;
z-index: 30;
}
.slider .slider-nav li {
display: inline-block;
width: 20px;
height: 3px;
margin: 0 1px;
text-indent: -9999px;
overflow: hidden;
background-color: rgba(255, 255, 255, .5);
}
.slider .slider-nav a {
display: block;
height: 3px;
line-height: 3px;
}
.slider .slider-nav li.activeSlide {
background: #fff;
}
.slider .slider-nav li.activeSlide a {
display: none;
}
.slider .slider-container {
width: 100%;
text-align: center;
}
.slider .slider-container a {
display: block;
position: absolute;
top: 0;
left: 0;
right: 0;
}
.slider .slider-container img {
transform: translateX(-50%);
margin-left: 50%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<div class="container">
<div class="slider slider-homepage">
<ul class="slider-nav"></ul>
<div class="slider-container">
<a href="#">
<img src="https://picsum.photos/1200/300/?gravity=east" alt="">
</a>
<a href="#">
<img src="https://picsum.photos/1200/300/?gravity=south" alt="">
</a>
<a href="#">
<img src="https://picsum.photos/1200/300/?gravity=west" alt="">
</a>
</div>
</div>
</div>
I have not figured out how to do that.
Like #epascarello said in a comment above, just clear & start again:
if (event.originalEvent !== undefined) {
clearInterval(autoAdvance);
autoAdvance = setInterval(advanceFunc, animationInterval);
}
later edit:
If the callback or the interval are not available anymore when restarting, it could help to "save" them in a closure:
function startInterval(func, delay) {
var id = setInterval(func, delay);
return {
stop: function() { clearInterval(id); },
restart: function() { clearInterval(id); id = setInterval(func, delay); }
};
}
var autoAdvance = startInterval(advanceFunc, animationInterval);
//later
autoAdvance.restart();

How do I make my jquery game's gameboard responsive?

I'm trying to create a game using Jquery however I have an issue when trying to make the webpage responsive. The issue is that I'm unable to make my game-board "spelplan" responsive, I know the reason this happens is because parts of my script is connected to the "width" of the game-board so when I remove the "width" and replace it with <div id="spelplan" class="col-6 col-m-6"> these parts get completely messed up. So what I need help with is how I make my game-board "spelplan" responsive, I would really appreciate any help I can get with this.
function updateClock() {
var currentTime = new Date();
var currentHours = currentTime.getHours();
var currentMinutes = currentTime.getMinutes();
var currentSeconds = currentTime.getSeconds();
currentMinutes = (currentMinutes < 10 ? "0" : "") + currentMinutes;
currentSeconds = (currentSeconds < 10 ? "0" : "") + currentSeconds;
var timeOfDay = (currentHours < 12) ? "AM" : "PM";
currentHours = (currentHours > 12) ? currentHours - 12 : currentHours;
currentHours = (currentHours == 0) ? 12 : currentHours;
var currentTimeString = currentHours + ":" + currentMinutes + ":" + currentSeconds + " " + timeOfDay;
document.getElementById("clock").firstChild.nodeValue = currentTimeString;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
background-color: black;
}
header {
position: absolute;
top: 50px;
color: white;
text-align: center;
}
#clock {
font-size: 25px;
position: absolute;
color: white;
}
#rand_pos {
position: absolute;
top: 20%;
left: 30%;
z-index: 10;
}
.player {
background-color: red;
height: 50px;
width: 50px;
position: absolute;
top: 100px;
left: 100px;
z-index: 100;
}
p {
position: relative;
left: 10px;
color: white;
}
#spelplan {
position: relative;
left: 35%;
top: 200px;
height: 600px;
width: 600px;
background-color: blue;
border-style: double;
border-radius: 40px;
}
.rand {
background-color: green;
height: 15px;
width: 15px;
position: absolute;
left: 30%;
top: 150px;
z-index: 3;
}
.new_pos {
background: #ccc;
border: 1px solid #000;
padding: 5px;
box-shadow: 0 0 20px #555;
-webkit-transition: all .2s ease-in;
transition: all .2s ease-in;
}
.new_pos:hover {
background: #bbb;
box-shadow: 0 0 20px #222;
}
.new_pos:active {
box-shadow: 0 0 20px #000;
background: #aaa;
}
*:focus {
outline: none;
}
.new_pos {
position: fixed;
left: 0;
bottom: 0;
cursor: pointer;
}
#footer {
position: absolute;
top: 80vh;
color: white;
text-align: center;
}
/* For mobile phones: */
[class*="col-"] {
width: 100%;
}
#media only screen and (min-width: 600px) {
/* For tablets: */
.col-m-1 {
width: 8.33%;
}
.col-m-2 {
width: 16.66%;
}
.col-m-3 {
width: 25%;
}
.col-m-4 {
width: 33.33%;
}
.col-m-5 {
width: 41.66%;
}
.col-m-6 {
width: 50%;
}
.col-m-7 {
width: 58.33%;
}
.col-m-8 {
width: 66.66%;
}
.col-m-9 {
width: 75%;
}
.col-m-10 {
width: 83.33%;
}
.col-m-11 {
width: 91.66%;
}
.col-m-12 {
width: 100%;
}
img {
width: 80%;
height: auto;
}
}
#media only screen and (min-width: 768px) {
/* For desktop: */
.col-1 {
width: 8.33%;
}
.col-2 {
width: 16.66%;
}
.col-3 {
width: 25%;
}
.col-4 {
width: 33.33%;
}
.col-5 {
width: 41.66%;
}
.col-6 {
width: 50%;
}
.col-7 {
width: 58.33%;
}
.col-8 {
width: 66.66%;
}
.col-9 {
width: 75%;
}
.col-10 {
width: 83.33%;
}
.col-11 {
width: 91.66%;
}
.col-12 {
width: 100%;
}
img {
width: 100%;
height: auto;
}
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="style20.css">
<script type='text/javascript' src='eventjavascript6.js'></script>
<title>Jquery spel</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script>
$(document).ready(function() {
var sprites = [];
var enemies = [];
var game = $("#spelplan");
var score = 0;
var el_score = $("#score")
function SCORE(pts) {
score += pts
el_score.text(score);
}
function RND(min, max) {
return parseInt(Math.random() * (max - min) + min);
}
var sprite = function(id, x, y, w, h, _class, view, collisionDetect, options) {
this.view = view;
this.id = id
this.x = x + "px";
this.y = y + "px";
this.width = w;
this.height = h;
this.options = options;
this.el = $("<div id='" + this.id + "' class='" + _class + "'></div>").css('left', this.x).css('top', this.y);
view.append(this.el);
this.x = function() {
return this.el.position().left;
}
this.y = function() {
return this.el.position().top;
}
this.up = function() {
if (this.y() > 0) {
this.el.animate({
top: '-=25px'
}, 0);
if (collisionDetect) collisionDetect(this);
}
};
this.down = function() {
if (this.y() < this.view.height() - this.height) {
this.el.animate({
top: '+=25px'
}, 0);
if (collisionDetect) collisionDetect(this);
}
};
this.left = function() {
if (this.x() > 0) {
this.el.animate({
left: '-=25px'
}, 0);
if (collisionDetect) collisionDetect(this);
}
};
this.right = function() {
if (this.x() + this.width < this.view.width()) {
this.el.animate({
left: '+=25px'
}, 0);
if (collisionDetect) collisionDetect(this);
}
this.destroy = function() {
this.el.remove();
for (var i = 0; i < sprites.length; i++) {
if (data[i].id == this.id) {
sprites.splice(i, 1);
break;
}
}
}
};
this.getPos = function() {
var pos, width, height;
pos = this.el.position();
width = this.el.width();
height = this.el.height();
return [
[pos.left, pos.left + width],
[pos.top, pos.top + height]
];
};
this.comparePos = function(p1, p2) {
var r1, r2;
r1 = p1[0] < p2[0] ? p1 : p2;
r2 = p1[0] < p2[0] ? p2 : p1;
return r1[1] > r2[0] || r1[0] === r2[0];
};
this.collidesWith = function(sprite) {
if (sprite.destroyed === true) return;
var pos1 = this.getPos(),
pos2 = sprite.getPos();
return this.comparePos(pos1[0], pos2[0]) && this.comparePos(pos1[1], pos2[1]);
};
if (this.options && this.options.init) this.options.init(this);
sprites.push(this);
};
function spawnrand() {
if (sprites.length > 100) return
var points = [50, 100, 200, 300, 400, 500];
var spelplanWidth = game.width();
var spelplanHeight = game.height();
var randPosY = Math.floor((Math.random() * spelplanHeight));
var randPosX = Math.floor((Math.random() * spelplanWidth));
var enemy = new sprite("enemy" + sprites.length + 1, randPosY, randPosX, 15, 15, "rand", game, null, {
PTS: points[RND(0, 5)],
init: function(sprite) {
sprite.selfDestruct = setTimeout(function() {
sprite.el.fadeOut(1000, function() {});
}, 5000);
}
});
enemies.push(enemy);
}
SCORE(0);
var player = new sprite("box1", 200, 200, 50, 50, "player", game,
function(sprite) {
sprites.forEach(function(sprite) {
if (sprite.id !== "box1" && player.collidesWith(sprite)) {
sprite.destroyed = true;
clearTimeout(sprite.selfDestruct);
sprite.el.fadeOut(100, function() {});
SCORE(sprite.options.PTS);
}
})
});
setInterval(spawnrand, 250);
$(document).keydown(function(e) {
if (e.keyCode == 37) {
player.left();
} else if (e.keyCode == 39) {
player.right();
} else if (e.keyCode == 38) {
player.up();
} else if (e.keyCode == 40) {
player.down();
}
});
});
</script>
</head>
<body onload="updateClock(); setInterval('updateClock()', 1000 )">
<span id="clock"> </span>
<header class="col-12 col-m-12">
<h1>Samla så mycket poäng du hinner genom att ta de gröna bollarna innan de försvinner</h1>
</header>
<div id="spelplan" class="col-6 col-m-6">
<div>
<p>Score:<span id="score"></span></p>
</div>
</div>
<section id="footer" class="col-12 col-m-12">
<h1>Använd piltangenterna för att styra den röda kuben </h1>
</section>
</body>
</html>
So again what I need help with is making the game-board "spelplan" responsive, any help is appreciated!

Categories

Resources