Greeting,
I have been required to make a module for a website I am working where user can drag and drop some image on a previewed pdf. So I found a sample code in codepen:
Demo
This is done using PDFJS. As far as I understand PDFJS is completely viewer. So my question is how can I finally save the modified page after I drag and drop the image over canvas previewed page. Does PDF-Lib with the combination of PDFJS is doable for this? Or TCPDF or other backend PHP based library would needed for this purpose.
Note: Backed is done in CakePHP.
var pdfData = atob($('#pdfBase64').val());
/*
* costanti per i placaholder
*/
var maxPDFx = 595;
var maxPDFy = 842;
var offsetY = 7;
'use strict';
// The workerSrc property shall be specified.
//
pdfjsLib.GlobalWorkerOptions.workerSrc =
'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.0.943/pdf.worker.min.js';
//
// Asynchronous download PDF
//
var loadingTask = pdfjsLib.getDocument({data: pdfData});
loadingTask.promise.then(function(pdf) {
//
// Fetch the first page
//
pdf.getPage(1).then(function(page) {
var scale = 1.0;
var viewport = page.getViewport(scale);
//
// Prepare canvas using PDF page dimensions
//
var canvas = document.getElementById('the-canvas');
var context = canvas.getContext('2d');
canvas.height = viewport.height;
canvas.width = viewport.width;
//
// Render PDF page into canvas context
//
var renderContext = {
canvasContext: context,
viewport: viewport
};
//page.render(renderContext);
page.render(renderContext).then(function() {
$(document).trigger("pagerendered");
}, function() {
console.log("ERROR");
});
});
});
/* The dragging code for '.draggable' from the demo above
* applies to this demo as well so it doesn't have to be repeated. */
// enable draggables to be dropped into this
interact('.dropzone').dropzone({
// only accept elements matching this CSS selector
accept: '.drag-drop',
// Require a 100% element overlap for a drop to be possible
overlap: 1,
// listen for drop related events:
ondropactivate: function (event) {
// add active dropzone feedback
event.target.classList.add('drop-active');
},
ondragenter: function (event) {
var draggableElement = event.relatedTarget,
dropzoneElement = event.target;
// feedback the possibility of a drop
dropzoneElement.classList.add('drop-target');
draggableElement.classList.add('can-drop');
draggableElement.classList.remove('dropped-out');
//draggableElement.textContent = 'Dragged in';
},
ondragleave: function (event) {
// remove the drop feedback style
event.target.classList.remove('drop-target');
event.relatedTarget.classList.remove('can-drop');
event.relatedTarget.classList.add('dropped-out');
//event.relatedTarget.textContent = 'Dragged out';
},
ondrop: function (event) {
//event.relatedTarget.textContent = 'Dropped';
},
ondropdeactivate: function (event) {
// remove active dropzone feedback
event.target.classList.remove('drop-active');
event.target.classList.remove('drop-target');
}
});
interact('.drag-drop')
.draggable({
inertia: true,
restrict: {
restriction: "#selectorContainer",
endOnly: true,
elementRect: { top: 0, left: 0, bottom: 1, right: 1 }
},
autoScroll: true,
// dragMoveListener from the dragging demo above
onmove: dragMoveListener,
});
function dragMoveListener (event) {
var target = event.target,
// keep the dragged position in the data-x/data-y attributes
x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx,
y = (parseFloat(target.getAttribute('data-y')) || 0) + event.dy;
// translate the element
target.style.webkitTransform =
target.style.transform ='translate(' + x + 'px, ' + y + 'px)';
// update the posiion attributes
target.setAttribute('data-x', x);
target.setAttribute('data-y', y);
}
// this is used later in the resizing demo
window.dragMoveListener = dragMoveListener;
$(document).bind('pagerendered', function (e) {
$('#pdfManager').show();
var parametri = JSON.parse($('#parameters').val());
$('#parametriContainer').empty();
renderizzaPlaceholder(0, parametri);
});
function renderizzaPlaceholder(currentPage, parametri){
var maxHTMLx = $('#the-canvas').width();
var maxHTMLy = $('#the-canvas').height();
var paramContainerWidth = $('#parametriContainer').width();
var yCounterOfGenerated = 0;
var numOfMaxItem = 25;
var notValidHeight = 30;
var y = 0;
var x = 6;
var page=0;
var totalPages=Math.ceil(parametri.length/numOfMaxItem);
for (i = 0; i < parametri.length; i++) {
var param = parametri[i];
var page = Math.floor(i/numOfMaxItem);
var display= currentPage == page ? "block" : "none";
if(i > 0 && i%numOfMaxItem == 0){
yCounterOfGenerated = 0;
}
var classStyle = "";
var valore = param.valore;
/*il placeholder non è valido: lo incolonna a sinistra*/
if(i > 0 && i%numOfMaxItem == 0){
yCounterOfGenerated = 0;
}
var classStyle = "";
var valore = param.valore;
/*il placeholder non è valido: lo incolonna a sinistra*/
y = yCounterOfGenerated;
yCounterOfGenerated += notValidHeight;
classStyle = "drag-drop dropped-out";
$("#parametriContainer").append('<div class="'+classStyle+'" data-id="-1" data-page="'+page+'" data-toggle="'+valore+'" data-valore="'+valore+'" data-x="'+x+'" data-y="'+y+'" style="transform: translate('+x+'px, '+y+'px); display:'+display+'"> <span class="circle"></span><span class="descrizione">'+param.descrizione+' </span></div>');
}
y = notValidHeight * (numOfMaxItem+1);
var prevStyle = "";
var nextStyle = "";
var prevDisabled = false;
var nextDisabled = false;
if(currentPage == 0){
prevStyle = "disabled";
prevDisabled = true;
}
if(currentPage >= totalPages-1 || totalPages == 1){
nextDisabled=true;
nextStyle="disabled";
}
//Aggiunge la paginazione
$("#parametriContainer").append('<ul id="pager" class="pager" style="transform: translate('+x+'px, '+y+'px); width:200px;"><li onclick="changePage('+prevDisabled+','+currentPage+',-1)" class="page-item '+prevStyle+'"><span>«</span></li><li onclick="changePage('+nextDisabled+','+currentPage+',1)" class="page-item '+nextStyle+'" style="margin-left:10px;"><span>»</span></li></ul>');
}
function renderizzaInPagina(parametri){
var maxHTMLx = $('#the-canvas').width();
var maxHTMLy = $('#the-canvas').height();
var paramContainerWidth = $('#parametriContainer').width();
var yCounterOfGenerated = 0;
var numOfMaxItem = 26;
var notValidHeight = 30;
var y = 0;
var x = 6;
for (i = 0; i < parametri.length; i++) {
var param = parametri[i];
var classStyle = "drag-drop can-drop";
var valore = param.valore;
/*il placeholder non è valido: lo incolonna a sinistra*/
var pdfY = maxPDFy - param.posizioneY - offsetY;
y = (pdfY * maxHTMLy) / maxPDFy;
x = ((param.posizioneX * maxHTMLx) / maxPDFx) + paramContainerWidth;
$("#parametriContainer").append('<div class="'+classStyle+'" data-id="'+param.idParametroModulo+'" data-toggle="'+valore+'" data-valore="'+valore+'" data-x="'+x+'" data-y="'+y+'" style="transform: translate('+x+'px, '+y+'px);"> <span class="circle"></span><span class="descrizione">'+param.descrizione+' </span></div>');
}
}
function changePage(disabled, currentPage, delta){
if(disabled){
return;
}
/*recupera solo i parametri non posizionati in pagina*/
var parametri = [];
$(".drag-drop.dropped-out").each(function() {
var valore = $(this).data("valore");
var descrizione = $(this).find(".descrizione").text();
parametri.push({valore:valore, descrizione:descrizione, posizioneX:-1000, posizioneY:-1000});
$(this).remove();
});
//svuota il contentitore
$('#pager').remove();
currentPage += delta;
renderizzaPlaceholder(currentPage, parametri);
//aggiorna lo stato dei pulsanti
//aggiorna gli elementi visualizzati
}
function showCoordinates(){
var validi = [];
var nonValidi = [];
var maxHTMLx = $('#the-canvas').width();
var maxHTMLy = $('#the-canvas').height();
var paramContainerWidth = $('#parametriContainer').width();
//recupera tutti i placholder validi
$('.drag-drop.can-drop').each(function( index ) {
var x = parseFloat($(this).data("x"));
var y = parseFloat($(this).data("y"));
var valore = $(this).data("valore");
var descrizione = $(this).find(".descrizione").text();
var pdfY = y * maxPDFy / maxHTMLy;
var posizioneY = maxPDFy - offsetY - pdfY;
var posizioneX = (x * maxPDFx / maxHTMLx) - paramContainerWidth;
var val = {"descrizione": descrizione, "posizioneX":posizioneX, "posizioneY":posizioneY, "valore":valore};
validi.push(val);
});
if(validi.length == 0){
alert('No placeholder dragged into document');
}
else{
alert(JSON.stringify(validi));
}
}
#messageContainer{
display:none;
}
#outer-dropzone {
height: 140px;
touch-action: none;
}
#inner-dropzone {
height: 80px;
}
.dropzone {
background-color: #ccc;
border: dashed 4px transparent;
border-radius: 4px;
margin: 10px auto 30px;
padding: 10px;
width: 100%;
transition: background-color 0.3s;
}
.drop-active {
border-color: #aaa;
}
.drop-target {
background-color: #29e;
border-color: #fff;
border-style: solid;
}
.drag-drop {
display: inline-block;
position:absolute;
z-index:999;
min-width: 40px;
padding: 0em 0.5em;
padding-left:0;
color: #fff;
background-color: #29e;
border: none;
-webkit-transform: translate(0px, 0px);
transform: translate(0px, 0px);
transition: background-color 0.3s;
line-height: 10px;
padding-right: 0 !important;
padding-left: 5px !important;
}
.drag-drop.can-drop {
color: #000;
background-color: transparent;
opacity:0.9;
/* IE 8 */
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=90)";
/* IE 5-7 */
filter: alpha(opacity=90);
/* Netscape */
-moz-opacity: 0.9;
/* Safari 1.x */
-khtml-opacity: 0.9;
}
.nopadding {
padding: 0 !important;
margin: 0 !important;
}
.circle {
width: 10px;
height: 10px;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
background: #323c3c;
float: left;
display: inline-block;
margin-top: 1px;
margin-right: 2px;
}
.dropped-out{
display: block;
padding: .75rem 1.25rem;
margin-bottom: -1px;
background-color: #fff;
border: 1px solid rgba(0,0,0,.125);
width:200px;
color: black;
}
.col-fixed-240{
width:240px;
height:100%;
z-index:1;
}
.col-fixed-605{
margin-left:240px;
width:605px;
height:100%;
z-index:1;
}
.page-item{
cursor:pointer;
}
.pager{
margin-bottom:30px !important;
margin-top:0px !important;
margin-bottom: -31px !important;
}
.drag-drop.dropped-out .descrizione {
font-size: 12px !important;
}
#the-canvas{
height:842px;
width: 595px;
}
<div class="container">
<div class="row">
<div class="col-md-12" style="padding:10px">
<button class="btn btn-primary btn-block" onClick="showCoordinates()">Show PDF Placeholders Coordinates</button>
</div>
</div>
<div class="row">
<div class="col-md-12" id="pdfManager" style="display:none">
<div class="row" id="selectorContainer">
<div class="col-fixed-240" id="parametriContainer">
</div>
<div class="col-fixed-605">
<div id="pageContainer" class="pdfViewer singlePageView dropzone nopadding" style="background-color:transparent">
<canvas id="the-canvas" style="border:1px solid black"></canvas>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- parameters showed on the left sidebar -->
<input id="parameters" type="hidden" value='[{"idParametro":480,"descrizione":"RAPINA","valore":"X","nota":null},{"idParametro":481,"descrizione":"CAUSAL_G00","valore":"X","nota":null},{"idParametro":482,"descrizione":"A","valore":"A","nota":null},{"idParametro":483,"descrizione":"POSTA_REGISTRATA","valore":"X","nota":null},{"idParametro":484,"descrizione":"CD","valore":"CD","nota":null},{"idParametro":485,"descrizione":"DATA_ALERT","valore":"data alert","nota":null},{"idParametro":486,"descrizione":"UP","valore":"UP","nota":null},{"idParametro":488,"descrizione":"DATA_MP","valore":"DATA1","nota":null},{"idParametro":489,"descrizione":"AL_QUALITA","valore":"AL_QUALITA","nota":null},{"idParametro":490,"descrizione":"CAUSAL_G60","valore":"X","nota":null},{"idParametro":491,"descrizione":"DATA","valore":"DATA","nota":null},{"idParametro":492,"descrizione":"DATA_DENUNCIA","valore":"data denuncia","nota":null},{"idParametro":493,"descrizione":"DATA_SPEDIZIONE","valore":"data spedizione","nota":null},{"idParametro":494,"descrizione":"DATA_LAVORAZIONE","valore":"DATA_LAVORAZIONE","nota":null},{"idParametro":495,"descrizione":"NUMERO_FAX","valore":"NUMERO_FAX","nota":null},{"idParametro":496,"descrizione":"SMARRIMENTO","valore":"X","nota":null},{"idParametro":497,"descrizione":"STRUTT_ACCETTAZIONE","valore":"STRUTT_ACCETTAZIONE","nota":null},{"idParametro":498,"descrizione":"FURTO","valore":"X","nota":null},{"idParametro":499,"descrizione":"BARCODE","valore":"BARCODE","nota":null},{"idParametro":502,"descrizione":"CAUSA_MAGGIORE","valore":"X","nota":null},{"idParametro":503,"descrizione":"PACCHI","valore":"X","nota":null},{"idParametro":504,"descrizione":"TIPOLOGIA_EVENTO","valore":"TIPOLOGIA_EVENTO","nota":null},{"idParametro":505,"descrizione":"NOTE","valore":"NOTE","nota":null},{"idParametro":506,"descrizione":"DATA_RITROVAMENTO","valore":"data ritrovamento","nota":null},{"idParametro":507,"descrizione":"DATA_ACCETTAZIONE","valore":"DATA_ACCETTAZIONE","nota":null},{"idParametro":509,"descrizione":"AREA_LOGISTICA","valore":"AREA_LOGISTICA","nota":null},{"idParametro":511,"descrizione":"DA","valore":"DA","nota":null},{"idParametro":512,"descrizione":"DATA_DENUNCIA","valore":"DATA_DENUNCIA","nota":null},{"idParametro":513,"descrizione":"TIPOLOGIA_ALERT","valore":"TIPOLOGIA","nota":null},{"idParametro":515,"descrizione":"STRUTTURA_RILIEVO","valore":"STRUTTURA_RILIEVO","nota":null},{"idParametro":516,"descrizione":"STRUTTURA_DENUNCIA","valore":"STRUTTURA_DENUNCIA","nota":null},{"idParametro":517,"descrizione":"DISPACCIO","valore":"DISPACCIO","nota":null},{"idParametro":518,"descrizione":"CMP_CP","valore":"CMP_CP","nota":null},{"idParametro":520,"descrizione":"FURTO_EFFRAZIONE","valore":"X","nota":null}]' />
<!-- Below the pdf base 64 rapresentation -->
<input id="pdfBase64" type="hidden" value="" />
Thanks
Related
I have got a snake game from Snake Code - Make the face of the snake an image, and I'm wondering how to make the apple into text with the same font as the Score in the upper right corner, and green using the JavaScript recognized color LimeGreen, or its Hex equivalent #32CD32.
Here's the continuous HTML code for your viewing:
<!DOCTYPE html>
<html style="background-color: #000000">
<head>
<title>Snake!</title>
</head>
<body>
<script>
(function() {
/////////////////////////////////////////////////////////////
// Canvas & Context
var canvas;
var ctx;
// Snake
var snake;
var snake_dir;
var snake_next_dir;
var snake_speed;
// Food
var food = {
x: 0,
y: 0
};
// Score
var score;
// Wall
var wall;
// HTML Elements
var screen_snake;
var screen_menu;
var screen_setting;
var screen_gameover;
var button_newgame_menu;
var button_newgame_setting;
var button_newgame_gameover;
var button_setting_menu;
var button_setting_gameover;
var ele_score;
var speed_setting;
var wall_setting;
/////////////////////////////////////////////////////////////
var activeDot = function(x, y) {
ctx.fillStyle = "LimeGreen";
ctx.fillRect(x * 10, y * 10, 10, 10);
}
/////////////////////////////////////////////////////////////
var changeDir = function(key) {
if (key == 38 && snake_dir != 2) {
snake_next_dir = 0;
} else {
if (key == 39 && snake_dir != 3) {
snake_next_dir = 1;
} else {
if (key == 40 && snake_dir != 0) {
snake_next_dir = 2;
} else {
if (key == 37 && snake_dir != 1) {
snake_next_dir = 3;
}
}
}
}
}
/////////////////////////////////////////////////////////////
var addFood = function() {
food.x = Math.floor(Math.random() * ((canvas.width / 10) - 1));
food.y = Math.floor(Math.random() * ((canvas.height / 10) - 1));
for (var i = 0; i < snake.length; i++) {
if (checkBlock(food.x, food.y, snake[i].x, snake[i].y)) {
addFood();
}
}
}
/////////////////////////////////////////////////////////////
var checkBlock = function(x, y, _x, _y) {
return (x == _x && y == _y) ? true : false;
}
/////////////////////////////////////////////////////////////
var altScore = function(score_val) {
ele_score.innerHTML = String(score_val);
}
/////////////////////////////////////////////////////////////
var mainLoop = function() {
var _x = snake[0].x;
var _y = snake[0].y;
snake_dir = snake_next_dir;
// 0 - Up, 1 - Right, 2 - Down, 3 - Left
switch (snake_dir) {
case 0:
_y--;
break;
case 1:
_x++;
break;
case 2:
_y++;
break;
case 3:
_x--;
break;
}
snake.pop();
snake.unshift({
x: _x,
y: _y
});
// --------------------
// Wall
if (wall == 1) {
// On
if (snake[0].x < 0 || snake[0].x == canvas.width / 10 || snake[0].y < 0 || snake[0].y == canvas.height / 10) {
showScreen(3);
return;
}
} else {
// Off
for (var j = 0, x = snake.length; j < x; j++) {
if (snake[j].x < 0) {
snake[j].x = snake[j].x + (canvas.width / 10);
}
if (snake[j].x == canvas.width / 10) {
snake[j].x = snake[j].x - (canvas.width / 10);
}
if (snake[j].y < 0) {
snake[j].y = snake[j].y + (canvas.height / 10);
}
if (snake[j].y == canvas.height / 10) {
snake[j].y = snake[j].y - (canvas.height / 10);
}
}
}
// --------------------
// Autophagy death
for (var i = 1; i < snake.length; i++) {
if (snake[0].x == snake[i].x && snake[0].y == snake[i].y) {
showScreen(3);
return;
}
}
// --------------------
// Eat Food
if (checkBlock(snake[0].x, snake[0].y, food.x, food.y)) {
snake[snake.length] = {
x: snake[0].x,
y: snake[0].y
};
score += 1;
altScore(score);
addFood();
activeDot(food.x, food.y);
}
// --------------------
ctx.beginPath();
ctx.fillStyle = "#000000";
ctx.fillRect(0, 0, canvas.width, canvas.height);
// --------------------
for (var i = 0; i < snake.length; i++) {
activeDot(snake[i].x, snake[i].y);
}
// --------------------
activeDot(food.x, food.y);
// Debug
//document.getElementById("debug").innerHTML = snake_dir + " " + snake_next_dir + " " + snake[0].x + " " + snake[0].y;
setTimeout(mainLoop, snake_speed);
}
/////////////////////////////////////////////////////////////
var newGame = function() {
showScreen(0);
screen_snake.focus();
snake = [];
for (var i = 4; i >= 0; i--) {
snake.push({
x: i,
y: 15
});
}
snake_next_dir = 1;
score = 0;
altScore(score);
addFood();
canvas.onkeydown = function(evt) {
evt = evt || window.event;
changeDir(evt.keyCode);
}
mainLoop();
}
/////////////////////////////////////////////////////////////
// Change the snake speed...
// 150 = slow
// 100 = normal
// 50 = fast
var setSnakeSpeed = function(speed_value) {
snake_speed = speed_value;
}
/////////////////////////////////////////////////////////////
var setWall = function(wall_value) {
wall = wall_value;
if (wall == 0) {
screen_snake.style.borderColor = "#606060";
}
if (wall == 1) {
screen_snake.style.borderColor = "#FFFFFF";
}
}
/////////////////////////////////////////////////////////////
// 0 for the game
// 1 for the main menu
// 2 for the settings screen
// 3 for the game over screen
var showScreen = function(screen_opt) {
switch (screen_opt) {
case 0:
screen_snake.style.display = "block";
screen_menu.style.display = "none";
screen_setting.style.display = "none";
screen_gameover.style.display = "none";
break;
case 1:
screen_snake.style.display = "none";
screen_menu.style.display = "block";
screen_setting.style.display = "none";
screen_gameover.style.display = "none";
break;
case 2:
screen_snake.style.display = "none";
screen_menu.style.display = "none";
screen_setting.style.display = "block";
screen_gameover.style.display = "none";
break;
case 3:
screen_snake.style.display = "none";
screen_menu.style.display = "none";
screen_setting.style.display = "none";
screen_gameover.style.display = "block";
break;
}
}
/////////////////////////////////////////////////////////////
window.onload = function() {
canvas = document.getElementById("snake");
ctx = canvas.getContext("2d");
// Screens
screen_snake = document.getElementById("snake");
screen_menu = document.getElementById("menu");
screen_gameover = document.getElementById("gameover");
screen_setting = document.getElementById("setting");
// Buttons
button_newgame_menu = document.getElementById("newgame_menu");
button_newgame_setting = document.getElementById("newgame_setting");
button_newgame_gameover = document.getElementById("newgame_gameover");
button_setting_menu = document.getElementById("setting_menu");
button_setting_gameover = document.getElementById("setting_gameover");
// etc
ele_score = document.getElementById("score_value");
speed_setting = document.getElementsByName("speed");
wall_setting = document.getElementsByName("wall");
// --------------------
button_newgame_menu.onclick = function() {
newGame();
};
button_newgame_gameover.onclick = function() {
newGame();
};
button_newgame_setting.onclick = function() {
newGame();
};
button_setting_menu.onclick = function() {
showScreen(2);
};
button_setting_gameover.onclick = function() {
showScreen(2)
};
setSnakeSpeed(150);
setWall(1);
showScreen("menu");
// --------------------
// Settings
// speed
for (var i = 0; i < speed_setting.length; i++) {
speed_setting[i].addEventListener("click", function() {
for (var i = 0; i < speed_setting.length; i++) {
if (speed_setting[i].checked) {
setSnakeSpeed(speed_setting[i].value);
}
}
});
}
// wall
for (var i = 0; i < wall_setting.length; i++) {
wall_setting[i].addEventListener("click", function() {
for (var i = 0; i < wall_setting.length; i++) {
if (wall_setting[i].checked) {
setWall(wall_setting[i].value);
}
}
});
}
document.onkeydown = function(evt) {
if (screen_gameover.style.display == "block") {
evt = evt || window.event;
if (evt.keyCode == 32) {
newGame();
}
}
}
}
})();
</script>
<style>
::selection {
color: #FFFFFF;
background: transparent;
}
::-moz-selection {
color: #FFFFFF;
background: transparent;
}
* {
margin: 0;
padding: 0;
font-family: "VT323";
}
body {
background-color: #000000;
}
.wrap {
margin-left: auto;
margin-right: auto;
}
header {
width: 340px;
font-size: 0;
}
canvas {
display: none;
border-style: solid;
border-width: 10px;
border-color: #FFFFFF;
}
canvas:focus {
outline: none;
}
/* Top Styles */
h1 {
display: inline-block;
width: 100px;
font-size: 32px;
color: #FFFFFF;
}
.score {
display: inline-block;
width: 240px;
font-size: 20px;
color: #FFFFFF;
text-align: right;
}
.score_value {
font-size: inherit;
}
/* All screens style */
#gameover a,
#setting a,
#menu a {
display: block;
}
#gameover a,
#setting a:hover,
#menu a:hover {
cursor: pointer;
}
#gameover a:hover::before,
#setting a:hover::before,
#menu a:hover::before {
content: ">";
margin-right: 10px;
}
/* Menu Screen Style */
#menu {
display: block;
width: 340px;
padding-top: 95px;
padding-bottom: 95px;
font-size: 40px;
margin-left: auto;
margin-right: auto;
text-align: center;
color: #FFF;
}
#menu h2 {
-webkit-animation: logo-ani 1000ms linear infinite;
animation: logo-ani 1000ms linear infinite;
margin-bottom: 30px;
}
#menu a {
font-size: 30px;
}
#-webkit-keyframes logo-ani {
50% {
-webkit-transform: scale(1.3, 1.3);
}
100% {
-webkit-transform: scale(1.0, 1.0);
}
}
#keyframes logo-ani {
50% {
transform: scale(1.3, 1.3);
}
100% {
transform: scale(1.0, 1.0);
}
}
/* Game Over Screen Style */
#gameover {
display: none;
width: 340px;
padding-top: 95px;
padding-bottom: 95px;
margin-left: auto;
margin-right: auto;
text-align: center;
font-size: 30px;
color: #FFF;
}
#gameover p {
margin-top: 25px;
font-size: 20px;
}
/* Settings Screen Style */
#setting {
display: none;
width: 340px;
margin-left: auto;
margin-right: auto;
padding-top: 85px;
padding-bottom: 85px;
font-size: 30px;
color: #FFF;
text-align: center;
}
#setting h2 {
margin-bottom: 15px;
}
#setting p {
margin-top: 10px;
}
#setting input {
display: none;
}
#setting label {
cursor: pointer;
}
#setting input:checked+label {
background-color: #FFF;
color: #000;
}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<link href="https://fonts.googleapis.com/css2?family=VT323&display=swap" rel="stylesheet">
<header class="wrap">
<h1>Snake</h1>
<p class="score">Score: <span id="score_value">0</span></p>
</header>
<canvas class="wrap" id="snake" width="600" height="600" tabindex="1"></canvas>
<!-- Game Over Screen -->
<div id="gameover">
<h2>Game Over</h2>
<p>press <span style="background-color: #FFFFFF; color: #000000">space</span> to begin a</p>
<a id="newgame_gameover">new game</a>
<a id="setting_gameover">settings</a>
</div>
<!-- Setting screen -->
<div id="setting">
<h2>Settings</h2>
<a id="newgame_setting">new game</a>
<p>Speed:
<input id="speed1" type="radio" name="speed" value="120" checked/>
<label for="speed1">Slow</label>
<input id="speed2" type="radio" name="speed" value="75" />
<label for="speed2">Normal</label>
<input id="speed3" type="radio" name="speed" value="35" />
<label for="speed3">Fast</label>
</p>
<p>Wall:
<input id="wallon" type="radio" name="wall" value="1" checked/>
<label for="wallon">On</label>
<input id="walloff" type="radio" name="wall" value="0" />
<label for="walloff">Off</label>
</p>
</div>
<!-- Main Menu Screen -->
<div id="menu">
<h2>Snake</h2>
<a id="newgame_menu">new game</a>
<a id="setting_menu">settings</a>
</div>
</body>
</html>
Thanks in advance!
Add a 3rd param to activeDot, pass the colour.
var activeDot = function(x, y, color) {
ctx.fillStyle = color;
ctx.fillRect(x * 10, y * 10, 10, 10);
}
It's used in 3 places, activeDot(food.x, food.y, 'LimeGreen');
On mobile, it's a common UI pattern to have a scrollable element inside a draggable element. When you reach the end of the scrollable element, you start dragging the outer element. E.g. in this GIF (https://media.giphy.com/media/9MJgBkoZfqA7jRdQop/giphy.gif), after scrolling to the top, if you continuing scrolling, it'll drag the subreddits menu.
I want to implement a similar pattern using JS/CSS. To do this, I need to detect if users continue scrolling after reaching the end. Is this possible? If so, is it possible to determine how much they scroll after reaching the end?
window.onscroll = function(element) {
if ((window.innerHeight + window.pageYOffset) >= document.body.offsetHeight) {
alert("you're at the bottom of the page");
}
};
Using element parameter to know the current exact x y where mouse is now at to calculate more and some how much was scrolled
Javascript: How to detect if browser window is scrolled to bottom?
If You need to keep track of the user activity after the bottom (or the top) of the page has been reached, beside the scroll event, You need to track the the wheel event. Moreover, on mobile, You need to track also touchstart and touchmove events.
Not all these events are normalized across browsers, so I did my own normalization function, which is more or less something like this:
var compulsivity = Math.log2(Math.max(scrollAmount, 0.01) * wheelAmount);
Below is a complete playground. You can test it in Chrome using the Mobile View of the Developer Tools, or in other browsers using the TouchEmulator.
function Tracker(page) {
this.page = page;
this.moveUp = 0;
this.moveDown = 0;
this.startTouches = {};
this.moveTouches = {};
this.lastScrollY = 0;
this.monitor = {};
this.startThreshold = 160;
this.moveThreshold = 10;
this.iOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
this.pullToRefresh = window.chrome || navigator.userAgent.match('CriOS');
this.amplitude = 16 / Math.log(2);
this.page.ownerDocument.addEventListener( 'onwheel' in document ? 'wheel' : 'onmousewheel' in document ? 'mousewheel' : 'DOMMouseScroll', this, { passive: true } );
/* The basic scroll event cannot be canceled, so it does not need to be set passive.*/
this.page.ownerDocument.addEventListener('scroll', this);
this.page.addEventListener('touchstart', this, { passive: true });
/* Maybe we need to cancel pullToRefresh */
this.page.addEventListener('touchmove', this, { passive: false });
return this;
}
Tracker.prototype.handleEvent = function (e) { /* handleEvent is built-in */
var winHeight = (this.iOS ? document.documentElement.clientHeight : window.innerHeight) | 0,
currScrollY = window.pageYOffset | 0,
amountScrollY = (this.lastScrollY - currScrollY) | 0,
elHeight = this.page.offsetHeight | 0,
elTop = -currScrollY, elBottom = winHeight - elHeight + currScrollY,
isTop = elTop >= 0, isBottom = elBottom >= 0;
switch (e.type) {
case 'wheel':
case 'onmousewheel':
case 'mousewheel':
case 'DOMMouseScroll':
var wheelDelta = e.wheelDelta ? e.wheelDelta : e.deltaY ? -e.deltaY : -e.detail,
wheelDir = (wheelDelta > 0) - (wheelDelta < 0),
wheelUp = wheelDir < 0, wheelDown = wheelDir > 0,
wheelAmount = 100 * wheelDir;
if (isTop && wheelDown) {
this.moveUp++;
this.moveDown = 0;
} else if (isBottom && wheelUp) {
this.moveUp = 0;
this.moveDown++;
} else {
this.moveUp = 0;
this.moveDown = 0;
}
var compulsivity = this.amplitude * Math.log(Math.max(this.moveUp, this.moveDown, 0.01) * wheelAmount* wheelDir);
this.monitor[e.type].track(wheelAmount, compulsivity);
break;
case 'scroll':
/* end of scroll event for iOS, start/end of scroll event for other browsers */
this.lastScrollY = currScrollY;
this.monitor[e.type].track(amountScrollY, 0);
break;
case 'touchstart':
var touches = [].slice.call(e.touches), i = touches.length;
while (i--) {
var touch = touches[i], id = touch.identifier;
this.startTouches[id] = touch;
this.moveTouches[id] = touch;
}
break;
case 'touchmove':
var touches = [].slice.call(e.touches), i = touches.length,
currTouches = {},
swipeUp = false, swipeDown = false,
currMoveY = 0, totalMoveY = 0;
while (i--) {
var touch = touches[i], id = touch.identifier;
currTouches[id] = touch;
if (id in this.moveTouches) {
currMoveY = this.moveTouches[id].screenY - touch.screenY;
}
if (id in this.startTouches) {
totalMoveY = this.startTouches[id].screenY - touch.screenY;
}
swipeUp = currMoveY > 0 || totalMoveY > 0;
swipeDown = currMoveY < 0 || totalMoveY < 0;
if (this.pullToRefresh && isTop && swipeDown && e.cancelable) {
e.preventDefault();
console.log('Reload prevented');
}
}
this.moveTouches = currTouches;
var moveDir = (totalMoveY > 0) - (totalMoveY < 0),
longSwipe = moveDir * totalMoveY > this.startThreshold,
shortSwipe = moveDir * totalMoveY > this.moveThreshold,
realSwipe = longSwipe || shortSwipe;
if (isTop && swipeDown) {
if (realSwipe) this.moveUp++;
this.moveDown = 0;
} else if (isBottom && swipeUp) {
this.moveUp = 0;
if (realSwipe) this.moveDown++;
} else {
this.moveUp = 0;
this.moveDown = 0;
}
var compulsivity = this.amplitude * Math.log(Math.max(this.moveUp, this.moveDown, 0.01) * moveDir * totalMoveY);
this.monitor[e.type].track(currMoveY, compulsivity);
break;
}
};
function Monitor(events) {
this.ctx = null;
this.cont = null;
this.events = events;
this.values = [];
this.average = 0;
this.lastDrawTime = 0;
this.inertiaDuration = 200;
return this;
}
Monitor.prototype.showOn = function (container) {
var cv = document.createElement('canvas');
this.ctx = cv.getContext('2d');
this.cont = document.getElementById(container);
cv.width = this.cont.offsetWidth;
cv.height = this.cont.offsetHeight;
cv.style.top = 0;
cv.style.left = 0;
cv.style.zIndex = -1;
cv.style.position = 'absolute';
cv.style.backgroundColor = '#000';
this.cont.appendChild(cv);
var self = this;
window.addEventListener('resize', function () {
var cv = self.ctx.canvas, cont = self.cont;
cv.width = cont.offsetWidth;
cv.height = cont.offsetHeight;
});
return this;
};
Monitor.prototype.track = function (value, average) {
this.average = average;
if (this.values.push(value) > this.ctx.canvas.width) this.values.shift();
if (value) this.lastDrawTime = new Date().getTime();
};
Monitor.prototype.draw = function () {
if (this.ctx) {
var cv = this.ctx.canvas, w = cv.width, h = cv.height;
var i = this.values.length, x = w | 0, y = (0.5 * h) | 0;
cv.style.backgroundColor = 'rgb(' + this.average + ', 0, 0)';
this.ctx.clearRect(0, 0, w, h);
this.ctx.strokeStyle = '#00ffff';
this.ctx.lineWidth = 1;
this.ctx.beginPath();
while (i--) {
x -= 4;
if (x < 0) break;
this.ctx.moveTo(x, y);
this.ctx.lineTo(x + 1, y);
this.ctx.lineTo(x + 1, y - this.values[i]);
}
this.ctx.stroke();
var elapsed = new Date().getTime() - this.lastDrawTime;
/* cool down */
this.average = this.average > 0 ? (this.average * 0.9) | 0 : 0;
if (elapsed > this.inertiaDuration) {
this.track(0, this.average);
}
}
var self = this;
setTimeout(function () {
self.draw();
}, 100);
};
Monitor.prototype.connectTo = function (tracker) {
var events = this.events.split(' '), i = events.length;
while (i--) {
tracker.monitor[events[i]] = this;
}
this.draw();
return this;
};
function loadSomeData(target) {
$.ajax({
url: 'https://jsonplaceholder.typicode.com/users',
method: 'GET',
crossDomain: true,
dataType: 'json',
success: function (users) {
var html = '', $ul = $(target).find('ul');
$.each(users, function (i, user) {
var item = '<li><a class="ui-alt-icon ui-nodisc-icon">';
item += '<h2>' + user.name + '</h2>';
item += '<p><strong>' + user.company.name + '</strong></p>';
item += '<p>' + user.address.zipcode + ', ' + user.address.city + '</p>';
item += '<p>' + user.phone + '</p>';
item += '<p>' + user.email + '</p>';
item += '<p class="ui-body-inherit ui-li-aside ui-li-count"><strong>' + user.id + '</strong></p>';
item += '</a></li>';
html += item;
});
$ul.append(html).listview('refresh');
},
});
}
$(document)
.on('pagecreate', '#page-list', function (e) {
$("[data-role='header'], [data-role='footer']").toolbar({ theme: 'a', position: 'fixed', tapToggle: false });
loadSomeData(e.target);
})
.on('pageshow', '#page-list', function (e, ui) {
var tracker = $.data(this, 'mobile-page', new Tracker(this));
new Monitor('touchstart touchmove').connectTo(tracker).showOn('header');
new Monitor('scroll wheel mousewheel DOMMouseScroll').connectTo(tracker).showOn('footer');
});
.ui-page {
touch-action: none;
}
h1, h2, h3, h4, h5, h6, p {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
/* JQM no frills */
.ui-btn,
.ui-title,
.ui-btn:hover,
.ui-btn:focus,
.ui-btn:active,
.ui-btn:visited {
text-shadow: none !important;
}
* {
-webkit-box-shadow: none !important;
-moz-box-shadow: none !important;
box-shadow: none !important;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Compulsivity</title>
<meta name="description" content="Compulsivity" />
<meta name="HandheldFriendly" content="True" />
<meta name="MobileOptimized" content="320" />
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, width=device-width, minimal-ui shrink-to-fit=no" />
<meta http-equiv="cleartype" content="on" />
<!-- Add to homescreen for Chrome on Android -->
<meta name="mobile-web-app-capable" content="yes" />
<!-- For iOS web apps. Delete if not needed. -->
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<meta name="apple-mobile-web-app-title" content="Compulsivity" />
<link rel="stylesheet" href="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css" />
<!--
<script type="application/javascript" src="lib/touch-emulator.js"></script>
<script> TouchEmulator(); </script>
-->
<script type="application/javascript" src="https://cdn.jsdelivr.net/npm/jquery#2.2.4/dist/jquery.min.js"></script>
<script type="application/javascript" src="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>
</head>
<body>
<div id="header" data-role="header"><h4 style="color: #fff">Compulsivity</h4></div>
<div id="page-list" data-role="page">
<div data-role="content" role="main">
<ul data-role="listview" data-filter="true" data-inset="true"></ul>
</div>
</div>
<div id="footer" data-role="footer"><h4 style="color: #fff">Scroll</h4></div>
</body>
</html>
Among others, You need to be aware also of the pull-to-refresh and inertia (or momentum) of the smooth scroll behaviors.
Please, try to scroll or to swipe and look how the events are tracked: either the top bar or bottom bar will change color to display the user activity after reaching the bottom or the top respectively of the page.
JavaScript:
// get the button
var theBtn = document.getElementById('theBtn');
// get the box
var theBox = document.getElementById('theBox');
// add event to the button on click show/hide(toggle) the box
theBtn.addEventListener('click', () => {
theBox.classList.toggle('active');
});
// when scrolling on the box
theBox.onscroll = function(){
// get the top of the div
var theBoxTop = theBox.scrollTop;
if(theBoxTop <= 0){
// when it reaches 0 or less, hide the box. It'll toggle the class, since it's "show" will "hide"
theBox.classList.toggle('active');
}
};
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-size: 10px;
font-family: 'Arial', sans-serif;
height: 1500px;
}
html {
scroll-behavior: smooth;
}
ul {
list-style-type: none;
}
#theBox ul li {
border: 1px solid;
height: 100px;
}
#navbar-bottom {
height: 100px;
width: 100%;
background: rgb(90, 111, 143);
position: fixed;
bottom: 0;
left: 0;
right: 0;
box-shadow: 0 0 2px 2px rgba(90, 111, 143, 0.562);
display: flex;
justify-content: space-around;
align-items: center;
}
#theBox {
background-color: red;
height: 350px;
width: 100%;
position: fixed;
bottom: 0;
transform: translateY(100%);
transition: all 0.3s;
overflow-y: scroll;
}
#theBox.active{
transform: translateY(0);
}
.myBtns {
width: 50px;
height: 50px;
border-radius: 50%;
border: none;
position: relative;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
cursor: pointer;
}
.myBtns span {
height: 3px;
width: 30px;
background-color: black;
margin: 3px 0;
}
<main role="main">
<div id="theBox">
<ul>
<li><p>Text</p></li>
<li><p>Text</p></li>
<li><p>Text</p></li>
<li><p>Text</p></li>
<li><p>Text</p></li>
<li><p>Text</p></li>
<li><p>Text</p></li>
<li><p>Text</p></li>
<li><p>Text</p></li>
</ul>
</div>
<div id="navbar-bottom">
<button class="myBtns"></button>
<button class="myBtns" id="theBtn">
<span></span>
<span></span>
<span></span>
</button>
<button class="myBtns"></button>
</div>
</main>
jQuery:
// add event to the button on click show/hide(toggle) the box
$('#theBtn').click(function(){
$('#theBox').toggleClass('active');
});
// when scrolling on the box
$('#theBox').scroll(function () {
// get the top of the div
var theBoxTop = $('#theBox').scrollTop();
// when it reaches 0 or less, hide the box. It'll toggle the class, since it's "show" will "hide"
if(theBoxTop <= 0){
$('#theBox').toggleClass('active');
}
});
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-size: 10px;
font-family: 'Arial', sans-serif;
height: 1500px;
}
html {
scroll-behavior: smooth;
}
ul {
list-style-type: none;
}
#theBox ul li {
border: 1px solid;
height: 100px;
}
#navbar-bottom {
height: 100px;
width: 100%;
background: rgb(90, 111, 143);
position: fixed;
bottom: 0;
left: 0;
right: 0;
box-shadow: 0 0 2px 2px rgba(90, 111, 143, 0.562);
display: flex;
justify-content: space-around;
align-items: center;
}
#theBox {
background-color: red;
height: 350px;
width: 100%;
position: fixed;
bottom: 0;
transform: translateY(100%);
transition: all 0.3s;
overflow-y: scroll;
}
#theBox.active{
transform: translateY(0);
}
.myBtns {
width: 50px;
height: 50px;
border-radius: 50%;
border: none;
position: relative;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
cursor: pointer;
}
.myBtns span {
height: 3px;
width: 30px;
background-color: black;
margin: 3px 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<main role="main">
<div id="theBox">
<ul>
<li><p>Text</p></li>
<li><p>Text</p></li>
<li><p>Text</p></li>
<li><p>Text</p></li>
<li><p>Text</p></li>
<li><p>Text</p></li>
<li><p>Text</p></li>
<li><p>Text</p></li>
<li><p>Text</p></li>
</ul>
</div>
<div id="navbar-bottom">
<button class="myBtns"></button>
<button class="myBtns" id="theBtn">
<span></span>
<span></span>
<span></span>
</button>
<button class="myBtns"></button>
</div>
</main>
window.onscroll = function(ev) {
if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
alert("you are at the bottom of the page");
}
};
Link to demo: http://jsfiddle.net/5xpoe4yg/
There are two solutions for this. One is for touch devices and second for devices using mouse.
Using Wheel event
If target is a mouse device, then we will use following method:
document.onwheel = event => ScrollAction(event);
For more info on wheel event, please visit this link.
Touch Devices
If target is a touch device then following method will be useful:
document.ontouchcancel = event => TouchInterrupt(event);
document.ontouchend = event => FingerRemoved(event);
document.ontouchmove = event => FingerDragged(event);
document.ontouchstart = event => FingerPlaced(event);
For more info on touch events, please visit this link.
I think your problem fully is solved by this solution.
Your specific question is solveable by listening to the wheel event, although the result is not terribly precise. The wheel event often fires before the scroll event so this example will sometimes log negative scroll value on the first scroll up from the bottom of the page:
const content = document.querySelector('.content');
for (let i = 0; i < 50; i++) {
const p = document.createElement('p');
p.textContent = 'Content';
content.append(p);
};
content.addEventListener('wheel', e => {
const atBottom = content.scrollHeight - content.scrollTop === content.clientHeight;
if (atBottom) console.log(e.deltaY);
});
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
body {
height: 100vh;
width: 100%;
}
.content {
overflow-y: scroll;
height: 100%;
}
<div class="content"></div>
As others have suggested, a better approach for your use case might instead be to have an overlay which you can trigger on click/touch and then scroll into view. One issue you might run into is that deeply nested scroll on web browsers can get real ugly real fast, without resorting to pure JS solutions which also have their own performance issues.
This is a popup that, when clicked on, opens and enables you to scroll. When it gets to the top of the page, it's header sticks.
var navbar = document.querySelector('.navbar'),
navheader = document.querySelector('.navheader');
// Toggle navbar
navheader.addEventListener('click', e => {
navbar.classList.toggle('open');
if (!navbar.classList.contains('open')) {
navbar.style.overflow = 'hidden';
document.body.style.overflow = '';
navbar.scrollTop = 0;
stickTop = false;
navbar.classList.remove('sticky');
navbar.style.top = '';
navbar.style.transition = '.2s';
setTimeout(() => {
navbar.style.transition = '';
}, 200);
}
else {
navbar.style.overflow = 'overlay';
navbar.style.transition = '.2s';
setTimeout(() => {
navbar.style.transition = '';
}, 200);
}
})
var prevtop = 0;
var stickTop = false;
// Add scroll listener
navbar.addEventListener('scroll', e => {
// If navbar is open
if (navbar.classList.contains('open')) {
if (!stickTop) {
navbar.style.top = navbar.getBoundingClientRect().top - navbar.scrollTop + 'px';
}
if ((window.innerHeight - navbar.getBoundingClientRect().bottom) >= 0) {
document.body.style.overflow = 'hidden';
navbar.style.overflow = 'auto';
navbar.style.top = 0;
navbar.classList.add('sticky');
stickTop = true;
}
if (navbar.scrollTop == 0) {
navbar.classList.remove('open');
navbar.style.overflow = 'hidden';
document.body.style.overflow = '';
stickTop = false;
navbar.classList.remove('sticky');
navbar.style.top = '';
navbar.style.transition = '.2s';
setTimeout(() => {
navbar.style.transition = '';
}, 200);
}
}
})
body {
font-family: sans-serif;
}
.navbar {
position: fixed;
top: calc(100vh - 50px);
height: 100vh;
left: 0;
width: 100%;
overflow: hidden;
}
.navbar.open {
top: 50vh;
}
.navcontent {
background: black;
width: 100%;
color: white;
}
.navcontent p {
margin: 0;
}
.navheader {
height: 50px;
width: 100%;
background: lightblue;
cursor: pointer;
top: 0;
position: sticky;
display: flex;
justify-content: center;
z-index: 1;
}
.navheader::before {
width: 50px;
height: 3px;
margin-top: 10px;
background: white;
border-radius: 3px;
content: '';
}
<div class="navbar">
<div class="navheader"></div>
<div class="navcontent"><p>S</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>E</p></div>
</div>
<div class="content">
<p>S</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>A</p><p>E</p>
</div>
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I am new to JavaScript. I am making Snakes and Ladders game. I am facing some problems on the code.
First I can not store the current position of the player so I can count the next destination.
The dice starts with 1 at the beginning of the game and this causes the player to start from the second cell.
The big snake and ladder divs displayed onto the board are not auto fit to the size of the board.
Here is the code I wrote so far Snakes and Ladder Game
var gameBoard = {
createBoard: function(dimension, mount) {
var mount = document.querySelector(mount);
if (!dimension || isNaN(dimension) || !parseInt(dimension, 10)) {
return false;
} else {
dimension = typeof dimension === 'string' ? parseInt(dimension, 10) : dimension;
var table = document.createElement('table'),
row = document.createElement('tr'),
cell = document.createElement('td'),
rowClone,
cellClone;
var output;
for (var r = 0; r < dimension; r++) {
rowClone = row.cloneNode(true);
table.appendChild(rowClone);
for (var c = 0; c < dimension; c++) {
cellClone = cell.cloneNode(true);
rowClone.appendChild(cellClone);
}
}
mount.appendChild(table);
output = gameBoard.enumerateBoard(table);
}
return output;
},
enumerateBoard: function(board) {
var rows = board.getElementsByTagName('tr'),
text = document.createTextNode(''),
rowCounter = 1,
size = rows.length,
cells,
cellsLength,
cellNumber,
odd = false,
control = 0;
for (var r = size - 1; r >= 0; r--) {
cells = rows[r].getElementsByTagName('td');
cellsLength = cells.length;
rows[r].className = r % 2 == 0 ? 'even' : 'odd';
odd = ++control % 2 == 0 ? true : false;
size = rows.length;
for (var i = 0; i < cellsLength; i++) {
if (odd == true) {
cellNumber = --size + rowCounter - i;
} else {
cellNumber = rowCounter;
}
cells[i].className = i % 2 == 0 ? 'even' : 'odd';
cells[i].id = cellNumber;
cells[i].appendChild(text.cloneNode());
cells[i].firstChild.nodeValue = cellNumber;
rowCounter++;
}
}
var lastRow = rows[0].getElementsByTagName('td');
lastRow[0].id = '100';
var firstRow = rows[9].getElementsByTagName('td');
firstRow[0].id = '1';
return gameBoard;
}
};
gameBoard.createBoard(10, "#grid");
function intialPosition() {
$("#1").append($("#player1"));
$("#1").append($("#player2"));
var currentPosition = parseInt($("#1").attr('id'));
return currentPosition;
}
var w = intialPosition();
var face1 = new Image()
face1.src = "http://s19.postimg.org/fa5etrfy7/image.gif"
var face2 = new Image()
face2.src = "http://s19.postimg.org/qb0jys873/image.gif"
var face3 = new Image()
face3.src = "http://s19.postimg.org/fpgoms1vj/image.gif"
var face4 = new Image()
face4.src = "http://s19.postimg.org/xgsb18ha7/image.gif"
var face5 = new Image()
face5.src = "http://s19.postimg.org/lsy96os5b/image.gif"
var face6 = new Image()
face6.src = "http://s19.postimg.org/4gxwl8ynz/image.gif"
function rollDice() {
var randomdice = Math.floor(Math.random() * 6) + 1;
document.images["mydice"].src = eval("face" + randomdice + ".src")
if (randomdice == 6) {
alert('Congratulations! You got 6! Roll the dice again');
}
return randomdice;
}
var random1 = rollDice();
var destination = w + random1;
function move() {
$('#' + destination).append($("#player1"));
var x = parseInt($('#' + destination).attr('id'));
var random = rollDice();
destination = x + random;
//alert(x);
return destination;
}
$(document).ready(function() {
//$('#' + destination).delay(100).fadeOut().fadeIn('slow');
$('#' + destination).fadeIn(100).fadeOut(100).fadeIn(100).fadeOut(100).fadeIn(100);
});
var next = move();
/*body {
background-image: url('snakesandladder2.png');
background-repeat: no-repeat;
background-size: 100%;
background-color: #4f96cb;
}*/
#game {
width: 80%;
margin-left: auto;
margin-right: auto;
display: table;
}
#gameBoardSection {
border: 3px inset #0FF;
border-radius: 10px;
width: 65%;
display: table-cell;
}
table {
width: 100%;
}
td {
border-radius: 10px;
width: 60px;
height: 60px;
line-height: normal;
vertical-align: bottom;
text-align: left;
border: 0px solid #FFFFFF;
position: relative;
}
table tr:nth-child(odd) td:nth-child(even),
table tr:nth-child(even) td:nth-child(odd) {
background-color: PowderBlue;
}
table tr:nth-child(even) td:nth-child(even),
table tr:nth-child(odd) td:nth-child(odd) {
background-color: SkyBlue;
}
#100 {
background-image: url('http://s19.postimg.org/ceioc1g8v/rotstar2_e0.gif');
background-repeat: no-repeat;
background-size: 100%;
}
#ladder {
position: absolute;
top: 300px;
left: 470px;
-webkit-transform: rotate(30deg);
z-index: 1;
opacity: 0.7;
}
#bigSnake {
position: absolute;
top: 20px;
left: 200px;
opacity: 0.7;
z-index: 1;
}
#diceAndPlayerSection {
background-color: lightpink;
border: 1px;
border-style: solid;
display: table-cell;
border-radius: 10px;
border: 3px inset #0FF;
width: 35%;
}
<body>
<div id="game">
<div id="gameBoardSection">
<div id="grid"></div>
<div id="ladder">
<img src="http://s19.postimg.org/otai9he2n/oie_e_RDOY2iqd5o_Q.gif" />
</div>
<div id="bigSnake">
<img src="http://s19.postimg.org/hrcknaagz/oie_485727s_RN4_KKBG.png" />
</div>
<div id="player1" style="position:absolute; top:10px; left:10px;">
<img src="http://s19.postimg.org/t108l496n/human_Piece.png" />
</div>
<div id="player2" style="position:absolute; top:15px; left:5px;">
<img src="http://s19.postimg.org/l6zmzq1dr/computer_Piece.png" />
</div>
</div>
<div id="diceAndPlayerSection">
<div id="reset">
<button type="button" name="newGame" onClick="gameVM.newGame();">New Game</button>
</div>
<div>
<button type="button" name="reset" onClick="gameVM.defaultSetup()">Reset</button>
</div>
<div>
<button type="button" name="addPlayer">Add Player</button>
</div>
<div id="diceSection">
<img src="d1.gif" name="mydice" onclick="rollDice()" style="background-color: white;">
</div>
</div>
</div>
</body>
Can anyone help me on that? Thanks in advance
To store the user current position , maintain the separate variable for storing the destination of diff player.
To start the play from the 1 , remove intialPosition() and make var w=0 , so once you call the rolldice() , it will start from 0.
In order to auto fit based on the change in screen size , use the bootstrap div which can auto fit the size of the div. Here is the link for it http://getbootstrap.com/css/#grid
Im new to this but I've been having some trouble with trying to get my timer and score values back to 0 before a new game of memory starts. The values do reset, but don't show it until that value is affected. For example, the value for the number of matches never goes back to 0, it stays on 10(the max number of pairs) until you find the first match of the next game where it will then turn to 1. Does anybody know how to get the values to show 0 again when a new board is called up instead of just resetting when that value is affected?
I have already set
var turns = 0
var matches = 0
and called in them up as 0 in the function newBoard().
My timer code is:
var c = 0;
var t;
var timer_is_on = 0;
function timedCount() {
document.getElementById('txt').value = c;
c = c+1;
t = setTimeout(timedCount, 1000);
}
function startTimer() {
if (!timer_is_on) {
timer_is_on = 1;
timedCount();
}
}
function stopCount() {
clearTimeout(t);
timer_is_on = 0;
}
function resetTime(){
clearTimeout(t);
timer_is_on = 0;
c = 0
Where I have called up the resetTime() function in the function newBoard().
My full code is:
body{
background:#FFF;
font-family: Cooper Black;
}
h1{
font-family: Cooper Black;
text-align: center;
font-size: 64px;
color: #FF0066;
}
footer{
height: 150px;
background: -webkit-linear-gradient(#99CCFF, #FFF); /* For Safari 5.1 to 6.0 */
background: -o-linear-gradient(#99CCFF, #FFF); /* For Opera 11.1 to 12.0 */
background: -moz-linear-gradient(#99CCFF, #FFF); /* For Firefox 3.6 to 15 */
background: linear-gradient(#99CCFF, #FFF); /* Standard syntax (must be last) */
}
div#memory_board{
background: -webkit-radial-gradient(#FFF, #CC99FF); /* For Safari 5.1 to 6.0 */
background: -o-radial-gradient(#FFF, #CC99FF); /* For Opera 11.1 to 12.0 */
background: -moz-radial-gradient(#FFF, #CC99FF); /* For Firefox 3.6 to 15 */
background: radial-gradient(#FFF, #CC99FF); /* Standard syntax (must be last) */
border:#FF0066 10px ridge;
width:510px;
height:405px;
padding:24px;
}
div#memory_board > div{
background:url(tile_background.png) no-repeat;
border:#000 1px solid;
width:45px;
height:45px;
float:left;
margin:7px;
padding:20px;
cursor:pointer;
}
alert{
background: #FF0066;
}
button{
font-family: Cooper Black;
font-size: 20px;
color: #FF0066;
background: #5CE62E;
border: #C2E0FF 2px outset;
border-radius: 25px;
padding: 10px;
cursor: pointer;
}
input#txt{
background: yellow;
color: #FF0066;
font-family: Times New Roman;
font-size: 84px;
height: 150px;
width: 150px;
border-radius: 100%;
text-align: center;
border: none;
}
input#pause{
font-family: Cooper Black;
font-size: 18px;
color: #FF0066;
background: #C2E0FF;
border: #C2E0FF 2px outset;
border-radius: 25px;
padding: 10px;
cursor: pointer;
margin-top: 10px;
}
div.goes{
text-align: center;
border: #C2E0FF 5px double;
height: 160px;
width: 120px;
margin-top: 48px;
margin-left: 5px;
}
div.matches{
text-align: center;
border: #C2E0FF 5px double;
height: 160px;
width: 120px;
margin-top: 30px;
margin-left: 10px;
}
p{
font-size: 28px;
}
span{
font-family: Times New Roman;
font-size: 84px;
}
.sprite {
width:96px;
height:96px;
position: relative;
margin:15px;
}
.toon{
background: url(explode.png);
}
}
#dialogoverlay{
display: none;
opacity: 0.8;
position: fixed;
top: 0px;
left: 0px;
background: #FFF;
width: 100%;
z-index: 10;
}
#dialogbox{
display: none;
position: fixed;
background: #FF0066;
border-radius:7px;
width:400px;
z-index: 10;
}
#dialogbox > div{ background: #FFF; margin:8px; }
#dialogbox > div > #dialogboxhead{ background: linear-gradient(#99CCFF, #FFF); height: 40px; color: #CCC; }
#dialogbox > div > #dialogboxbody{ background: #FFF; color: #FF0066; font-size: 36px; text-align:center;}
#dialogbox > div > #dialogboxfoot{ background: linear-gradient(#FFF, #99CCFF); padding-bottom: 20px; text-align:center; }
<!DOCTYPE html>
<html>
<head>
<title>Memory Card Game</title>
<meta http-equiv="Content-type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" type="text/css" href="reset.css" />
<link rel="stylesheet" type="text/css" href="text.css" />
<link rel="stylesheet" type="text/css" href="960.css" />
<link rel="stylesheet" type="text/css" href="mystyles.css" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script type='text/javascript' src='jquery.animateSprite.js'></script>
<script>
var memory_array = ['A','A','B','B','C','C','D','D','E','E','F','F','G','G','H','H','I','I','J','J'];
var memory_values = [];
var memory_tile_ids = [];
var tiles_flipped = 0;
var turns = 0
var matches = 0
Array.prototype.memory_tile_shuffle = function(){
var i = this.length, j, temp;
while(--i > 0){
j = Math.floor(Math.random() * (i+1));
temp = this[j];
this[j] = this[i];
this[i] = temp;
}
}
function newBoard(){
tiles_flipped = 0;
var output = '';
memory_array.memory_tile_shuffle();
for(var i = 0; i < memory_array.length; i++){
output += '<div id="tile_'+i+'" onclick="memoryFlipTile(this,\''+memory_array[i]+'\')"></div>';
}
document.getElementById('memory_board').innerHTML = output;
//fade in
$(document).ready(function () {
$('#memory_board > div').hide().fadeIn(1500).delay(6000)
});
resetTime();
turns = 0;
matches = 0;
}
function memoryFlipTile(tile,val){
startTimer();
playClick();
if(tile.innerHTML == "" && memory_values.length < 2){
tile.style.background = '#FFF';
tile.innerHTML = '<img src="' + val + '.png"/>';
if(memory_values.length == 0){
memory_values.push(val);
memory_tile_ids.push(tile.id);
} else if(memory_values.length == 1){
memory_values.push(val);
memory_tile_ids.push(tile.id);
if(memory_values[0] == memory_values[1]){
tiles_flipped += 2;
//sound
playMatch();
//animation
//number of clicks
turns = turns + 1;
document.getElementById("Count").innerHTML = turns;
//number of matches
matches = matches + 1;
document.getElementById("matchNumber").innerHTML = matches;
// Clear both arrays
memory_values = [];
memory_tile_ids = [];
// Check to see if the whole board is cleared
if(tiles_flipped == memory_array.length){
playEnd();
Alert.render("Congratulations! Board Cleared");
//resetTime()
//stopCount();
document.getElementById('memory_board').innerHTML = "";
newBoard();
}
} else {
function flipBack(){
// Flip the 2 tiles back over
var tile_1 = document.getElementById(memory_tile_ids[0]);
var tile_2 = document.getElementById(memory_tile_ids[1]);
tile_1.style.background = 'url(tile_background.png) no-repeat';
tile_1.innerHTML = "";
tile_2.style.background = 'url(tile_background.png) no-repeat';
tile_2.innerHTML = "";
//number of clicks
turns = turns + 1;
document.getElementById("Count").innerHTML = turns;
//clickNumber()
// Clear both arrays
memory_values = [];
memory_tile_ids = [];
}
setTimeout(flipBack, 700);
}
}
}
}
//timer
var c = 0;
var t;
var timer_is_on = 0;
function timedCount() {
document.getElementById('txt').value = c;
c = c+1;
t = setTimeout(timedCount, 1000);
}
function startTimer() {
if (!timer_is_on) {
timer_is_on = 1;
timedCount();
}
}
function stopCount() {
clearTimeout(t);
timer_is_on = 0;
}
function resetTime(){
clearTimeout(t);
timer_is_on = 0;
c = 0
}
//sound effects /*sounds from http://www.freesfx.co.uk*/
function playClick(){
var sound=document.getElementById("click");
sound.play();
}
function playMatch(){
var sound=document.getElementById("match_sound");
sound.play();
}
function playEnd(){
var sound=document.getElementById("finished");
sound.play();
}
//custom alert
function CustomAlert(){
this.render = function(dialog){
var winW = window.innerWidth;
var winH = window.innerHeight;
var dialogoverlay = document.getElementById('dialogoverlay');
var dialogbox = document.getElementById('dialogbox');
dialogoverlay.style.display = "block";
dialogoverlay.style.height = winH+"px";
dialogbox.style.left = (winW/2) - (400 * .5)+"px";
dialogbox.style.top = "200px";
dialogbox.style.display = "block";
document.getElementById('dialogboxhead').innerHTML = "";
document.getElementById('dialogboxbody').innerHTML = dialog;
document.getElementById('dialogboxfoot').innerHTML = '<button onclick="Alert.ok()">New Game</button>';
}
this.ok = function(){
document.getElementById('dialogbox').style.display = "none";
document.getElementById('dialogoverlay').style.display = "none";
}
}
var Alert = new CustomAlert();
</script>
<script>//sparkle effect: http://www.rigzsoft.co.uk/how-to-implement-animated-sprite-sheets-on-a-web-page/
$(document).ready(function(){
$("#memory_board").click(function animation(){
$(".toon").animateSprite({
columns: 10,
totalFrames: 50,
duration: 1000,
});
});
});
</script>
</head>
<body>
<audio id = "click" src = "click.mp3" preload = "auto"></audio>
<audio id = "match_sound" src = "match.mp3" preload = "auto"></audio>
<audio id = "finished" src = "finished.wav" preload = "auto"></audio>
<div id = "dialogoverlay"></div>
<div id = "dialogbox">
<div>
<div id = "dialogboxhead"></div>
<div id = "dialogboxbody"></div>
<div id = "dialogboxfoot"></div>
</div>
</div>
<div class = "container_16">
<div id = "banner" class = "grid_16">
<p><br></p>
<h1>Memory</h1>
</div>
<div class = "grid_3">
<input type="text" id="txt" value="0"/>
<p><br></p>
<p><br></p>
<div class = "goes">
<p>Turns <br><span id = "Count">0</span></p>
</div>
</div>
<div class = "grid_10">
<div id="memory_board"></div>
<script>newBoard();</script>
<div style="position: relative; height: 110px;">
<div class="sprite toon"></div>
</div>
</div>
<div class = "grid_3">
<button id = "new_game" onclick="newBoard()">New Game</button>
<input type="button" id="pause" value="Pause Game" onclick="stopCount()">
<p><br></p>
<p><br></p>
<p><br></p>
<div class = "matches">
<p>Matches <br><span id = "matchNumber">0</span></p>
</div>
</div>
</div>
<footer> </footer>
</body>
</html>
Both of the variables you are settings are displayed in HTML span objects.
What seems to be happening is that when you reset the Javascript variable, the value is being changed, but the span object where it is displayed to the user is being left at its previous value until it needs to be updated again.
As far as I can tell, your objects have the ids: matchNumber and Count for the match and turn variables respectively. If this is the case, try changing your code to reset the values to zero in the HTML when the variables are reset to zero.
For example:
// Reset the Javascript Count
var turns = 0
// Reset the HTML object
document.getElementById('Count').innerHTML = 0;
// Reset the Javascript Match Count
var matches = 0
// Reset the HTML object
document.getElementById('matchNumber').innerHTML = 0;
If I failed to explain this well, please comment and I'll try to clarify further.
I am not 100% sure, but you can try replacing your function with this one:
function timedCount() {
if(c>10){
//flipBack();
resetTime();
return;
}
document.getElementById('txt').value = c;
c = c+1;
t = setTimeout(timedCount, 1000);
}
Some of us might not want to use ready plugins because of their high sizes and possibilty of creating conflicts with current javascript.
I was using light slider plugins before but when customer gives modular revise, it became really hard to manipulate. Then I aim to build mine for customising it easily. I believe sliders shouldn't be that complex to build from beginning.
What is a simple and clean way to build jQuery image slider?
Before inspecting examples, you should know two jQuery functions which i used most.
index() returns value is an integer indicating the position of the first element within the jQuery object relative to its sibling elements.
eq() selects of an element based on its position (index value).
Basicly i take selected trigger element's index value and match this value on images with eq method.
- FadeIn / FadeOut effect.
- Sliding effect.
- alternate Mousewheel response.
html sample:
<ul class="images">
<li>
<img src="images/1.jpg" alt="1" />
</li>
<li>
<img src="images/2.jpg" alt="2" />
</li>
...
</ul>
<ul class="triggers">
<li>1</li>
<li>2</li>
...
</ul>
<span class="control prev">Prev</span>
<span class="control next">Next</span>
OPACITY EFFECT: jsFiddle.
css trick: overlapping images with position:absolute
ul.images { position:relative; }
ul.images li { position:absolute; }
jQuery:
var target;
var triggers = $('ul.triggers li');
var images = $('ul.images li');
var lastElem = triggers.length-1;
triggers.first().addClass('active');
images.hide().first().show();
function sliderResponse(target) {
images.fadeOut(300).eq(target).fadeIn(300);
triggers.removeClass('active').eq(target).addClass('active');
}
SLIDING EFFECT: jsFiddle.
css trick: with double wrapper and use child as mask
.mask { float:left; margin:40px; width:270px; height:266px; overflow:hidden; }
ul.images { position:relative; top:0px;left:0px; }
/* this width must be total of the images, it comes from jquery */
ul.images li { float:left; }
jQuery:
var target;
var triggers = $('ul.triggers li');
var images = $('ul.images li');
var lastElem = triggers.length-1;
var mask = $('.mask ul.images');
var imgWidth = images.width();
triggers.first().addClass('active');
mask.css('width', imgWidth*(lastElem+1) +'px');
function sliderResponse(target) {
mask.stop(true,false).animate({'left':'-'+ imgWidth*target +'px'},300);
triggers.removeClass('active').eq(target).addClass('active');
}
Common jQuery response for both slider:
( triggers + next/prev click and timing )
triggers.click(function() {
if ( !$(this).hasClass('active') ) {
target = $(this).index();
sliderResponse(target);
resetTiming();
}
});
$('.next').click(function() {
target = $('ul.triggers li.active').index();
target === lastElem ? target = 0 : target = target+1;
sliderResponse(target);
resetTiming();
});
$('.prev').click(function() {
target = $('ul.triggers li.active').index();
lastElem = triggers.length-1;
target === 0 ? target = lastElem : target = target-1;
sliderResponse(target);
resetTiming();
});
function sliderTiming() {
target = $('ul.triggers li.active').index();
target === lastElem ? target = 0 : target = target+1;
sliderResponse(target);
}
var timingRun = setInterval(function() { sliderTiming(); },5000);
function resetTiming() {
clearInterval(timingRun);
timingRun = setInterval(function() { sliderTiming(); },5000);
}
Here is a simple and easy to understand code for Creating image slideshow using JavaScript without using Jquery.
<script language="JavaScript">
var i = 0; var path = new Array();
// LIST OF IMAGES
path[0] = "image_1.gif";
path[1] = "image_2.gif";
path[2] = "image_3.gif";
function swapImage() { document.slide.src = path[i];
if(i < path.length - 1) i++;
else i = 0; setTimeout("swapImage()",3000);
} window.onload=swapImage;
</script>
<img height="200" name="slide" src="image_1.gif" width="400" />
I have recently created a solution with a gallery of images and a slider that apears when an image is clicked.
Take a look at the code here: GitHub Code
And a live example here: Code Example
var CreateGallery = function(parameters) {
var self = this;
this.galleryImages = [];
this.galleryImagesSrcs = [];
this.galleryImagesNum = 0;
this.counter;
this.galleryTitle = parameters.galleryTitle != undefined ? parameters.galleryTitle : 'Gallery image';
this.maxMobileWidth = parameters.maxMobileWidth != undefined ? parameters.maxMobileWidth : 768;
this.numMobileImg = parameters.numMobileImg != undefined ? parameters.numMobileImg : 2;
this.maxTabletWidth = parameters.maxTabletWidth != undefined ? parameters.maxTabletWidth : 1024;
this.numTabletImg = parameters.numTabletImg != undefined ? parameters.numTabletImg : 3;
this.addModalGallery = function(gallerySelf = self){
var $div = $(document.createElement('div')).attr({
'id': 'modal-gallery'
}).append($(document.createElement('div')).attr({
'class': 'header'
}).append($(document.createElement('button')).attr({
'class': 'close-button',
'type': 'button'
}).html('×')
).append($(document.createElement('h2')).text(gallerySelf.galleryTitle))
).append($(document.createElement('div')).attr({
'class': 'text-center'
}).append($(document.createElement('img')).attr({
'id': 'gallery-img'
})
).append($(document.createElement('button')).attr({
'class': 'prev-button',
'type': 'button'
}).html('◄')
).append($(document.createElement('button')).attr({
'class': 'next-button',
'type': 'button'
}).html('►')
)
);
parameters.element.after($div);
};
$(document).on('click', 'button.prev-button', {self: self}, function() {
var $currImg = self.counter >= 1 ? self.galleryImages[--self.counter] : self.galleryImages[self.counter];
var $currHash = self.galleryImagesSrcs[self.counter];
var $src = $currImg.src;
window.location.hash = $currHash;
$('img#gallery-img').attr('src', $src);
$('div#modal-gallery h2').text(self.galleryTitle + ' ' + (self.counter + 1));
});
$(document).on('click', 'button.next-button', {self: self}, function() {
var $currImg = self.counter < (self.galleryImagesNum - 1) ? self.galleryImages[++self.counter] : self.galleryImages[self.counter];
var $currHash = self.galleryImagesSrcs[self.counter];
var $src = $currImg.src;
window.location.hash = $currHash;
$('img#gallery-img').attr('src', $src);
$('div#modal-gallery h2').text(self.galleryTitle + ' ' + (self.counter + 1));
});
$(document).on('click', 'div#modal-gallery button.close-button', function() {
$('#modal-gallery').css('position', 'relative');
$('#modal-gallery').hide();
$('body').css('overflow', 'visible');
});
parameters.element.find('a').on('click', {self: self}, function(event) {
event.preventDefault();
$('#modal-gallery').css('position', 'fixed');
$('#modal-gallery').show();
$('body').css('overflow', 'hidden');
var $currHash = this.hash.substr(1);
self.counter = self.galleryImagesSrcs.indexOf($currHash);
var $src = $currHash;
window.location.hash = $currHash;
$('img#gallery-img').attr('src', $src);
$('div#modal-gallery h2').text(self.galleryTitle + ' ' + (self.counter + 1));
});
this.sizeGallery = function(gallerySelf = self) {
var $modalGallery = $(document).find("div#modal-gallery");
if($modalGallery.length <= 0) {
this.addModalGallery();
}
var $windowWidth = $(window).width();
var $parentWidth = parameters.element.width();
var $thumbnailHref = parameters.element.find('img:first').attr('src');
if($windowWidth < gallerySelf.maxMobileWidth) {
var percentMobile = Math.floor(100 / gallerySelf.numMobileImg);
var emMobile = 0;
var pxMobile = 2;
// var emMobile = gallerySelf.numMobileImg * 0.4;
// var pxMobile = gallerySelf.numMobileImg * 2;
parameters.element.find('img').css('width', 'calc('+percentMobile+'% - '+emMobile+'em - '+pxMobile+'px)');
} else if($windowWidth < gallerySelf.maxTabletWidth) {
var percentTablet = Math.floor(100 / gallerySelf.numTabletImg);
var emTablet = 0;
var pxTablet = 2;
// var emTablet = gallerySelf.numMobileImg * 0.4;
// var pxTablet = gallerySelf.numMobileImg * 2;
parameters.element.find('img').css('width', 'calc('+percentTablet+'% - '+emTablet+'em - '+pxTablet+'px)');
} else {
var $thumbImg = new Image();
$thumbImg.src = $thumbnailHref;
$thumbImg.onload = function() {
var $thumbnailWidth = this.width;
if($parentWidth > 0 && $thumbnailWidth > 0) {
parameters.element.find('img').css('width', (Math.ceil($thumbnailWidth * 100 / $parentWidth))+'%');
}
};
}
};
this.startGallery = function(gallerySelf = self) {
parameters.element.find('a').each(function(index, el) {
var $currHash = el.hash.substr(1);
var $img = new Image();
$img.src = $currHash;
gallerySelf.galleryImages.push($img);
gallerySelf.galleryImagesSrcs.push($currHash);
});
this.galleryImagesNum = this.galleryImages.length;
};
this.sizeGallery();
this.startGallery();
};
var myGallery;
$(window).on('load', function() {
myGallery = new CreateGallery({
element: $('#div-gallery'),
maxMobileWidth: 768,
numMobileImg: 2,
maxTabletWidth: 1024,
numTabletImg: 3
});
});
$(window).on('resize', function() {
myGallery.sizeGallery();
});
#div-gallery {
text-align: center;
}
#div-gallery img {
margin-right: auto;
margin-left: auto;
}
div#modal-gallery {
top: 0;
left: 0;
width: 100%;
max-width: none;
height: 100vh;
min-height: 100vh;
margin-left: 0;
border: 0;
border-radius: 0;
z-index: 1006;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
display: none;
background-color: #fefefe;
position: relative;
margin-right: auto;
overflow-y: auto;
padding: 0;
}
div#modal-gallery div.header {
position: relative;
}
div#modal-gallery div.header h2 {
margin-left: 1rem;
}
div#modal-gallery div.header button.close-button {
position: absolute;
top: calc(50% - 1em);
right: 1rem;
}
div#modal-gallery img {
display: block;
max-width: 98%;
max-height: calc(100vh - 5em);
margin-right: auto;
margin-left: auto;
}
div#modal-gallery div.text-center {
position: relative;
}
button.close-button {
display: inline-block;
padding: 6px 12px;
margin-bottom: 0;
font-size: 20px;
font-weight: 400;
line-height: 1.42857143;
text-align: center;
white-space: nowrap;
vertical-align: middle;
-ms-touch-action: manipulation;
touch-action: manipulation;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
background-image: none;
border: 1px solid transparent;
border-radius: 4px;
color: #333;
background-color: #fff;
border-color: #ccc;
}
button.close-button:hover, button.close-button:focus {
background-color: #ddd;
}
button.next-button:hover, button.prev-button:hover, button.next-button:focus, button.prev-button:focus {
color: #fff;
text-decoration: none;
filter: alpha(opacity=90);
outline: 0;
opacity: .9;
}
button.next-button, button.prev-button {
position: absolute;
top: 0;
bottom: 0;
left: 0;
width: 15%;
font-size: 20px;
color: #fff;
text-align: center;
text-shadow: 0 1px 2px rgba(0,0,0,.6);
background-color: rgba(0,0,0,0);
filter: alpha(opacity=50);
opacity: .5;
border: none;
}
button.next-button {
right: 0;
left: auto;
background-image: -webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);
background-image: -o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);
background-image: -webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));
background-image: linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);
background-repeat: repeat-x;
}
button.prev-button {
background-image: -webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);
background-image: -o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);
background-image: -webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));
background-image: linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);
background-repeat: repeat-x;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="div-gallery">
<img src="http://placehold.it/300x300/ff0000/000000?text=Gallery+image+1" alt="">
<img src="http://placehold.it/300x300/ff4000/000000?text=Gallery+image+2" alt="">
<img src="http://placehold.it/300x300/ff8000/000000?text=Gallery+image+3" alt="">
<img src="http://placehold.it/300x300/ffbf00/000000?text=Gallery+image+4" alt="">
<img src="http://placehold.it/300x300/ffff00/000000?text=Gallery+image+5" alt="">
<img src="http://placehold.it/300x300/bfff00/000000?text=Gallery+image+6" alt="">
<img src="http://placehold.it/300x300/80ff00/000000?text=Gallery+image+7" alt="">
<img src="http://placehold.it/300x300/40ff00/000000?text=Gallery+image+8" alt="">
<img src="http://placehold.it/300x300/00ff00/000000?text=Gallery+image+9" alt="">
<img src="http://placehold.it/300x300/00ff40/000000?text=Gallery+image+10" alt="">
<img src="http://placehold.it/300x300/00ff80/000000?text=Gallery+image+11" alt="">
<img src="http://placehold.it/300x300/00ffbf/000000?text=Gallery+image+12" alt="">
<img src="http://placehold.it/300x300/00ffff/000000?text=Gallery+image+13" alt="">
<img src="http://placehold.it/300x300/00bfff/000000?text=Gallery+image+14" alt="">
<img src="http://placehold.it/300x300/0080ff/000000?text=Gallery+image+15" alt="">
<img src="http://placehold.it/300x300/0040ff/000000?text=Gallery+image+16" alt="">
</div>
Checkout this whole bunch of code to build simple jquery image slider. Copy and save this file to local machine and test it. You can modify it according to your requirement.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script>
var current_img = 1;
var i;
$(document).ready(function(){
var imgs = $("#image").find("img");
function show_img(){
for (i = 1; i < imgs.length+1; i++) {
if(i == current_img){
$(imgs[i-1]).show();
}else{
$(imgs[i-1]).hide()
}
}
}
$("#prev").click(function(){
if(current_img == 1){
current_img = imgs.length;
}else{
current_img = current_img - 1
}
show_img();
});
$("#next").click(function(){
if(current_img == imgs.length){
current_img = 1;
}else{
current_img = current_img + 1
}
show_img();
});
});
</script>
</head>
<body>
<div style="margin-top: 100px;"></div>
<div class="container">
<div class="col-sm-3">
<button type="button" id="prev" class="btn">Previous</button>
</div>
<div class="col-sm-6">
<div id="image">
<img src="https://www.w3schools.com/html/pulpitrock.jpg" alt="image1">
<img src="https://www.w3schools.com/cSS/img_forest.jpg" alt="image2" hidden="true" style="max-width: 500px;">
<img src="https://www.w3schools.com/html/img_chania.jpg" alt="image3" hidden="true">
</div>
</div>
<div class="col-sm-3">
<button type="button" id="next" class="btn">Next</button>
</div>
</div>
</body>
</html>
I have written a tutorial on creating a slideshow, The tutorial page
In case the link becomes invalid I have included the code in my answer below.
the html:
<div id="slideShow">
<div id="slideShowWindow">
<div class="slide">
<img src="”img1.png”/">
<div class="slideText">
<h2>The Slide Title</h2>
<p>This is the slide text</p>
</div> <!-- </slideText> -->
</div> <!-- </slide> repeat as many times as needed -->
</div> <!-- </slideShowWindow> -->
</div> <!-- </slideshow> -->
css:
img {
display: block;
width: 100%;
height: auto;
}
p{
background:none;
color:#ffffff;
}
#slideShow #slideShowWindow {
width: 650px;
height: 450px;
margin: 0;
padding: 0;
position: relative;
overflow:hidden;
margin-left: auto;
margin-right:auto;
}
#slideShow #slideShowWindow .slide {
margin: 0;
padding: 0;
width: 650px;
height: 450px;
float: left;
position: relative;
margin-left:auto;
margin-right: auto;
}
#slideshow #slideshowWindow .slide, .slideText {
position:absolute;
bottom:18px;
left:0;
width:100%;
height:auto;
margin:0;
padding:0;
color:#ffffff;
font-family:Myriad Pro, Arial, Helvetica, sans-serif;
}
.slideText {
background: rgba(128, 128, 128, 0.49);
}
#slideshow #slideshowWindow .slide .slideText h2,
#slideshow #slideshowWindow .slide .slideText p {
margin:10px;
padding:15px;
}
.slideNav {
display: block;
text-indent: -10000px;
position: absolute;
cursor: pointer;
}
#leftNav {
left: 0;
bottom: 0;
width: 48px;
height: 48px;
background-image: url("../Images/plus_add_minus.png");
background-repeat: no-repeat;
z-index: 10;
}
#rightNav {
right: 0;
bottom: 0;
width: 48px;
height: 48px;
background-image: url("../Images/plus_add_green.png");
background-repeat: no-repeat;
z-index: 10; }
jQuery:
$(document).ready(function () {
var currentPosition = 0;
var slideWidth = 650;
var slides = $('.slide');
var numberOfSlides = slides.length;
var slideShowInterval;
var speed = 3000;
//Assign a timer, so it will run periodically
slideShowInterval = setInterval(changePosition, speed);
slides.wrapAll('<div id="slidesHolder"></div>');
slides.css({ 'float': 'left' });
//set #slidesHolder width equal to the total width of all the slides
$('#slidesHolder').css('width', slideWidth * numberOfSlides);
$('#slideShowWindow')
.prepend('<span class="slideNav" id="leftNav">Move Left</span>')
.append('<span class="slideNav" id="rightNav">Move Right</span>');
manageNav(currentPosition);
//tell the buttons what to do when clicked
$('.slideNav').bind('click', function () {
//determine new position
currentPosition = ($(this).attr('id') === 'rightNav')
? currentPosition + 1 : currentPosition - 1;
//hide/show controls
manageNav(currentPosition);
clearInterval(slideShowInterval);
slideShowInterval = setInterval(changePosition, speed);
moveSlide();
});
function manageNav(position) {
//hide left arrow if position is first slide
if (position === 0) {
$('#leftNav').hide();
}
else {
$('#leftNav').show();
}
//hide right arrow is slide position is last slide
if (position === numberOfSlides - 1) {
$('#rightNav').hide();
}
else {
$('#rightNav').show();
}
}
//changePosition: this is called when the slide is moved by the timer and NOT when the next or previous buttons are clicked
function changePosition() {
if (currentPosition === numberOfSlides - 1) {
currentPosition = 0;
manageNav(currentPosition);
} else {
currentPosition++;
manageNav(currentPosition);
}
moveSlide();
}
//moveSlide: this function moves the slide
function moveSlide() {
$('#slidesHolder').animate({ 'marginLeft': slideWidth * (-currentPosition) });
}
});