Related
I have an audio script with play/pause, I want to make the audio stop when I click on the square button at the left, and to add the timing to the right
here is the code: https://codepen.io/Amirafik/pen/YzxQZQw
HTML
<div class="title">
Dina Mohamed
</div>
<div class="stop"></div>
<div id="audioButton">
<div id="playerContainer">
<div class="listen">LISTEN</div>
</div>
</div>
<div class="duration">
00:12
</div>
<br>_____________________________________________________</br>
<div class="note">
<p>All items were more than perfect, we loved the experience and will order ONE OAK services again in the future for sure. <!--<span style="color:#F04E36"><br> Dina sent us an amazing feedback about her experience, tap the play button to listen to her cheerful words.</span></p>-->
</div
CSS
#import url('https://fonts.googleapis.com/css?family=montserrat:100,200,300,400,500,600,700,800,900');
body {
background: #ffffff;
color: #000000;
font-size: 16px ;
font-family: "montserrat" ;
font-weight: 500;
-webkit-tap-highlight-color: transparent;
}
a {
color: #F04E36;
}
.title {
max-width: 700px;
margin: 0 auto;
color: #000000;
font-weight:700;
display:inline-block;
}
.note {
max-width: 380px;
margin: 0 auto;
color: #000000;
display:inline-block;
}
.circle-audio-player {
cursor: pointer;
width:25px;
padding:0px;
margin-top:-67%;
margin-bottom:-50%;
margin-left:-7px;
background-color:#EDEBE7;
border-radius:50%;
vertical-align:middle;
}
#playerContainer {
padding: 0px;
vertical-align:middle;
}
#audioButton {
border-radius: 50px;
border: 2px solid #000000;
padding: 10px;
max-width: 85px;
height: 10px;
display: inline-block;
vertical-align:middle;
margin-left:2px;
}
.listen {
margin-left: 5px;
color: #000000;
font-weight:700;
display:inline-block;
float:right;
vertical-align:middle;
margin-top:-5%;
font-size: 14px ;
}
.stop {
max-width: 500px;
margin-left:10px;
height: 10px;
width: 10px;
background-color: #000000;
font-weight:500;
font-size: 14px ;
display:inline-block;
vertical-align:middle;
}
.duration {
max-width: 500px;
margin-left: 2px;
color: #000000;
font-weight:500;
font-size: 14px ;
display:inline-block;
}
JS
// settings
var DEFAULTS = {
borderColor: "#EDEBE7",
playedColor: "#F04E36",
backgroundColor: "#d3cdc2",
iconColor: "#000000",
borderWidth: 2,
size: 48,
className: 'circle-audio-player'
};
// reused values
var pi = Math.PI;
var doublePi = pi * 2;
var arcOffset = -pi / 2;
var animTime = 200;
var loaderTime = 1800;
var CircleAudioPlayer = function (options) {
options = options || {};
for (var property in DEFAULTS) {
this[property] = options[property] || DEFAULTS[property];
}
// create some things we need
this._canvas = document.createElement('canvas');
this._canvas.setAttribute('class', this.className + ' is-loading');
this._canvas.addEventListener('mousedown', (function () {
if (this.playing) {
this.pause();
}
else {
this.play();
}
}).bind(this));
this._ctx = this._canvas.getContext('2d');
// set up initial stuff
this.setAudio(options.audio);
this.setSize(this.size);
// redraw loop
(function cAPAnimationLoop (now) {
// check if we need to update anything
if (this.animating) {
this._updateAnimations(now);
}
if (this._forceDraw || this.playing || this.animating || this.loading) {
this._draw();
this._forceDraw = false;
}
requestAnimationFrame(cAPAnimationLoop.bind(this));
}).call(this, new Date().getTime());
};
CircleAudioPlayer.prototype = {
// private methods
_animateIcon: function (to, from) {
// define a few things the first time
this._animationProps = {
animStart: null,
from: from,
to: to
};
if (from) {
this.animating = true;
}
else {
this._animationProps.current = this._icons[to].slice();
this.draw();
}
},
_updateAnimations: function (now) {
this._animationProps.animStart = this._animationProps.animStart || now;
var deltaTime = now - this._animationProps.animStart;
var perc = (1 - Math.cos(deltaTime / animTime * pi / 2));
if (deltaTime >= animTime) {
this.animating = false;
perc = 1;
this._animationProps.current = this._icons[this._animationProps.to].slice();
this.draw();
}
else {
var from = this._icons[this._animationProps.from];
var current = [];
for (var i = 0; i < from.length; i++) {
current.push([]);
for (var j = 0; j < from[i].length; j++) {
current[i].push([]);
var to = this._icons[this._animationProps.to][i][j];
current[i][j][0] = from[i][j][0] + (to[0] - from[i][j][0]) * perc;
current[i][j][1] = from[i][j][1] + (to[1] - from[i][j][1]) * perc;
}
}
this._animationProps.current = current;
}
},
_draw: function (progress) {
// common settings
if (isNaN(progress)) {
progress = this.audio.currentTime / this.audio.duration || 0;
}
// clear existing
this._ctx.clearRect(0, 0, this.size, this.size);
// draw bg
this._ctx.beginPath();
this._ctx.arc(this._halfSize, this._halfSize, this._halfSize - (this.borderWidth / 2), 0, doublePi);
this._ctx.closePath();
this._ctx.fillStyle = this.backgroundColor;
this._ctx.fill();
// draw border
// our active path is already the full circle, so just stroke it
this._ctx.lineWidth = this.borderWidth;
this._ctx.strokeStyle = this.borderColor;
this._ctx.stroke();
// play progress
if (progress > 0) {
this._ctx.beginPath();
this._ctx.arc(this._halfSize, this._halfSize, this._halfSize - (this.borderWidth / 2), arcOffset, arcOffset + doublePi * progress);
this._ctx.strokeStyle = this.playedColor;
this._ctx.stroke();
}
// icons
this._ctx.fillStyle = this.iconColor;
if (this.loading) {
var loaderOffset = -Math.cos((new Date().getTime() % (loaderTime)) / (loaderTime) * pi) * doublePi - (pi / 3) - (pi / 2);
this._ctx.beginPath();
this._ctx.arc(this._halfSize, this._halfSize, this._halfSize / 3, loaderOffset, loaderOffset + pi / 3 * 2);
this._ctx.strokeStyle = this.iconColor;
this._ctx.stroke();
}
else {
this._ctx.beginPath();
var icon = (this._animationProps && this._animationProps.current) || this._icons.play;
for (var i = 0; i < icon.length; i++) {
this._ctx.moveTo(icon[i][0][0], icon[i][0][1]);
for (var j = 1; j < icon[i].length; j++) {
this._ctx.lineTo(icon[i][j][0], icon[i][j][1]);
}
}
// this._ctx.closePath();
this._ctx.fill();
// stroke to fill in for retina
this._ctx.strokeStyle = this.iconColor;
this._ctx.lineWidth = 2;
this._ctx.lineJoin = 'miter';
this._ctx.stroke();
}
},
_setState: function (state) {
this.playing = false;
this.loading = false;
if (state === 'playing') {
this.playing = true;
this._animateIcon('pause', 'play');
}
else if (state === 'loading') {
this.loading = true;
}
else if (this.state !== 'loading') {
this._animateIcon('play', 'pause');
}
else {
this._animateIcon('play', null);
}
this.state = state;
this._canvas.setAttribute('class', this.className + ' is-' + state);
this.draw();
},
// public methods
draw: function () {
this._forceDraw = true;
},
setSize: function (size) {
this.size = size;
this._halfSize = size / 2; // we do this a lot. it's not heavy, but why repeat?
this._canvas.width = size;
this._canvas.height = size;
// set icon paths
var iconSize = this.size / 2;
var pauseGap = iconSize / 10;
var playLeft = Math.cos(pi / 3 * 2) * (iconSize / 2) + this._halfSize;
var playRight = iconSize / 2 + this._halfSize;
var playHalf = (playRight - playLeft) / 2 + playLeft;
var top = this._halfSize - Math.sin(pi / 3 * 2) * (iconSize / 2);
var bottom = this.size - top;
var pauseLeft = this._halfSize - iconSize / 3;
var pauseRight = this.size - pauseLeft;
this._icons = {
play: [
[
[playLeft, top],
[playHalf, (this._halfSize - top) / 2 + top],
[playHalf, (this._halfSize - top) / 2 + this._halfSize],
[playLeft, bottom]
],
[
[playHalf, (this._halfSize - top) / 2 + top],
[playRight, this._halfSize],
[playRight, this._halfSize],
[playHalf, (this._halfSize - top) / 2 + this._halfSize]
]
],
pause: [
[
[pauseLeft, top + pauseGap],
[this._halfSize - pauseGap, top + pauseGap],
[this._halfSize - pauseGap, bottom - pauseGap],
[pauseLeft, bottom - pauseGap]
],
[
[this._halfSize + pauseGap, top + pauseGap],
[pauseRight, top + pauseGap],
[pauseRight, bottom - pauseGap],
[this._halfSize + pauseGap, bottom - pauseGap]
]
]
};
if (this._animationProps && this._animationProps.current) {
this._animateIcon(this._animationProps.to);
}
if (!this.playing) {
this.draw();
}
},
setAudio: function (audioUrl) {
this.audio = new Audio(audioUrl);
this._setState('loading');
this.audio.addEventListener('canplaythrough', (function () {
this._setState('paused');
}).bind(this));
this.audio.addEventListener('play', (function () {
this._setState('playing');
}).bind(this));
this.audio.addEventListener('pause', (function () {
// reset when finished
if (this.audio.currentTime === this.audio.duration) {
this.audio.currentTime = 0;
}
this._setState('paused');
}).bind(this));
},
appendTo: function (element) {
element.appendChild(this._canvas);
},
play: function () {
this.audio.play();
},
pause: function () {
this.audio.pause();
}
};
// now init one as an example
var cap = new CircleAudioPlayer({
audio: 'https://www.siriusxm.com/content/dam/sxm-com/audio/test/audio-previews/audio_test03.mp3.png',
size: 120,
borderWidth: 8
});
cap.appendTo(playerContainer);
You can simply use AudioElement.pause() to pause an running element, and the next AudioElement.play() will start from where you left off.
You can essentially set the currentTime property of the audio element to start from the beginning
A simple demonstration of how it works
const pause = document.getElementById('pause');
const stop = document.getElementById('stop');
const play = document.getElementById('play');
const container = document.getElementById('player');
const duration = document.getElementById('duration');
const audio = new Audio('https://www.siriusxm.com/content/dam/sxm-com/audio/test/audio-previews/audio_test03.mp3.png');
let played = 0;
let playing = true;
const wait = (ms) => new Promise(resolve => setTimeout(resolve, ms));
run = async function () {
while(playing) {
if (played == Math.floor(audio.duration)) break;
duration.innerText = `${played} / ${Math.floor(audio.duration)}`;
played++;
await wait(1000);
}
}
container.appendChild(audio);
stop.addEventListener('click', () => {
duration.innerText = `0 / ${Math.floor(audio.duration)}`
audio.pause();
audio.currentTime = 0;
played = 0;
playing = false;
});
pause.addEventListener('click', () => {
audio.pause();
playing = false;
});
play.addEventListener('click', () => {
playing = true
audio.play();
run();
});
<div id="player"></div>
<div id="duration">0.0</div>
<button id="play">play</button>
<button id="stop">stop</button>
<button id="pause">pause</button>
I have implemented the functionality from the snippet below to drag and swap local photos and it works like a charm. However, now I would like to replace my local array with the images from this url https://picsum.photos/v2/list?page=2& whilst still maintaining the drag and drop functionality. How can I achieve this?
Index.html (whole code css and javascript)
<html>
<head>
<title>Drag and Drop</title>
<link href="https://fonts.googleapis.com/css?family=Roboto+Slab" rel="stylesheet">
<style>
body { background: rgb(255, 246, 231); }
* { margin: 0; padding: 0; font-family: 'Roboto Slab', serif; }
.dd-vc { position: relative; top: 50%; transform: translateY(-50%); }
.dd-transition { transition: all 0.3s ease; }
.dd-shadow { box-shadow: 0 0 3px 1px rgba(0,0,0,0.3); }
#dragDrop { width: 1000px; margin: 20px auto 0; position: relative; }
.dd-slot { float: left; outline: 2px dashed rgba(54, 86, 132, 0.75); outline-offset: -15px; position: relative; pointer-events: none; }
.dd-slot-num { text-align: center; color: rgba(0,0,0,0.1); font-size: 40px; position: absolute; width: 100%; }
.dd-item { position: absolute; left: 0; top: 0; box-sizing: border-box; padding: 10px; cursor: pointer; }
.dd-item.dd-disabled { pointer-events: none; opacity: 0; }
.dd-item.dd-selected { z-index: 20; }
.dd-item-inner { background-repeat: no-repeat; background-size: cover; background-position: center; width: 100%; height: 100%; position: relative; }
.dd-item-panel { width: 80%; height: 35px; background: #fff; position: absolute; left: 10%; bottom: -15px; z-index: 5; }
.dd-item-title { font-size: 15px; color: #365684; text-align: center; line-height: 35px; }
</style>
</head>
<body>
<div id="dragDrop"></div>
<script>
(function () {
var _doc = window.document;
var _numOfImageSlots = 12,
_numOfImagesPerRow = 3,
_imageMarginBottom = 30;
var _imageAspectWidth = 1920,
_imageAspectHeight = 1080;
var _imageSlots = [],
_selectedImageElement = null,
_originalImageSlot = null,
_originalClickCoords = null,
_lastTouchedSlotId = null;
var _imageLibrary = [
{ id: 23, image: 'beach.jpg', title: 'Beach' },
{ id: 67, image: 'bridge.jpg', title: 'Bridge' },
{ id: 42, image: 'moon.jpg', title: 'Moon' },
{ id: 28, image: 'ocean.jpg', title: 'Paradise' },
{ id: 5567, image: 'sunrise.jpg', title: 'Sunrise' },
{ id: 879, image: 'tree.jpg', title: 'Tree' },
{ id: 314, image: 'waterfall.jpg', title: 'Waterfall' },
{ id: 57, image: 'winter.jpg', title: 'Winter' }
],
_listedImageIds = [ 23, 42, 5567, 57, 28, 879 ];
function init () {
addImageSlots();
drawImages();
_doc.getElementById('dragDrop').addEventListener('mousemove', imageMousemove);
}
function addImageSlots () {
var i = 0,
len = _numOfImageSlots,
item;
var wrap = _doc.getElementById('dragDrop');
for ( ; i < len; i++ ) {
item = _doc.createElement('div');
item.setAttribute('class', 'dd-slot');
item.setAttribute('style', 'width:' + ( 100 / _numOfImagesPerRow ) + '%;padding-bottom:' + ( ( 100 / _numOfImagesPerRow ) * ( _imageAspectHeight / _imageAspectWidth ) ) + '%;margin-bottom:' + _imageMarginBottom + 'px;');
item.innerHTML = '<p class="dd-slot-num dd-vc">' + ( i + 1 ) + '</p>';
wrap.appendChild(item);
}
}
function drawImages () {
var i = 0,
len = _numOfImageSlots,
item;
var wrap = _doc.getElementById('dragDrop');
var slot = _doc.getElementsByClassName('dd-slot')[0],
bounds = slot.getBoundingClientRect(),
itemWidth = bounds.width,
itemHeight = bounds.height;
var itemX,
itemY;
var imageId,
image;
for ( ; i < len; i++ ) {
imageId = _listedImageIds[i] || -1;
image = getImageById( imageId );
itemX = ( i % _numOfImagesPerRow ) * itemWidth;
itemY = Math.floor( i / _numOfImagesPerRow ) * ( itemHeight + _imageMarginBottom );
item = _doc.createElement('div');
item.setAttribute('class', 'dd-item dd-transition' + ( imageId < 0 ? ' dd-disabled' : '' ));
item.setAttribute('data-image-id', imageId);
item.setAttribute('style', 'width:' + itemWidth + 'px;height:' + itemHeight + 'px;transform:translate3d(' + itemX + 'px,' + itemY + 'px,0);' );
item.innerHTML = '<div class="dd-item-inner dd-shadow" style="' + ( image ? ( 'background-image:url(images/' + image.image + ')' ) : '' ) + '"><div class="dd-item-panel dd-shadow"><h3 class="dd-item-title">' + ( image ? image.title : '' ) + '</h3></div></div>';
wrap.appendChild(item);
item.addEventListener('mousedown', imageMousedown);
item.addEventListener('mouseup', imageMouseup);
_imageSlots[i] = { width: itemWidth, height: itemHeight, x: itemX, y: itemY };
}
}
function arrangeItems () {
var i = 0,
len = _listedImageIds.length,
slot,
ele;
for ( ; i < len; i++ ) {
slot = _imageSlots[i];
ele = _doc.querySelector('[data-image-id="' + _listedImageIds[i] + '"]');
ele.style.transform = 'translate3d(' + slot.x + 'px,' + slot.y + 'px,0)';
}
}
function imageMousedown ( event ) {
if ( !_selectedImageElement ) {
_selectedImageElement = event.currentTarget;
_originalClickCoords = { x: event.pageX, y: event.pageY };
_originalImageSlot = getIndexOfImageId( _selectedImageElement.getAttribute('data-image-id') );
_selectedImageElement.classList.add('dd-selected');
_selectedImageElement.classList.remove('dd-transition');
}
}
function imageMousemove ( event ) {
if ( _selectedImageElement ) {
var wrap = _doc.getElementById('dragDrop'),
bounds = wrap.getBoundingClientRect(),
left = bounds.left,
top = bounds.top;
var pageX = event.pageX,
pageY = event.pageY;
var clickX = pageX - left,
clickY = pageY - top,
hoverSlotId = getSlotIdByCoords( { x: clickX, y: clickY } );
var ele = _selectedImageElement,
imageId = ele.getAttribute('data-image-id'),
index = _originalImageSlot,
newIndex = getIndexOfImageId( imageId ),
x = _imageSlots[index].x,
y = _imageSlots[index].y;
var resultX = x + ( pageX - _originalClickCoords.x ),
resultY = y + ( pageY - _originalClickCoords.y );
if ( hoverSlotId != undefined && _lastTouchedSlotId != hoverSlotId ) {
_lastTouchedSlotId = hoverSlotId;
_listedImageIds.splice( hoverSlotId, 0, _listedImageIds.splice( newIndex, 1 )[0] );
arrangeItems();
}
ele.style.transform = 'translate3d(' + resultX + 'px,' + resultY + 'px,0)';
}
}
function imageMouseup () {
_selectedImageElement.classList.remove('dd-selected');
_selectedImageElement.classList.add('dd-transition');
_selectedImageElement = null;
_originalClickCoords = null;
arrangeItems();
}
function getSlotIdByCoords ( coords ) {
// Get the current slot being hovered over
for ( var id in _imageSlots ) {
var slot = _imageSlots[id];
if ( slot.x <= coords.x && coords.x <= slot.x + slot.width && slot.y <= coords.y && coords.y <= slot.y + slot.height )
return id;
}
}
function getImageById ( id ) {
return _imageLibrary.find(function (image) {
return image.id == id;
});
}
function getIndexOfImageId ( id ) {
var i = 0,
len = _listedImageIds.length;
for ( ; i < len; i++ )
if ( _listedImageIds[i] == id )
return i;
}
init();
})();
</script>
</body>
</html>
(I assume the solution will look something like this )
const url = 'https://picsum.photos/v2/list?page=2&limit=9';
fetch(url)
.then((response) => { return response.json(); })
.then( data => {...}
You need to change the function to async operator so that you can await for images to get from API. map the data according to your needs.
samples:
(async function () {
const url = 'https://picsum.photos/v2/list?page=2&limit=9';
const response = await fetch(url).then((response) => response.json())
const _imageLibrary = response.map(img => {
img.image = img.download_url
img.title = img.author
return img
})
const _listedImageIds = _imageLibrary.map(({
id
}) => id)
})()
Working sample:
<html>
<head>
<title>Drag and Drop</title>
<link href="https://fonts.googleapis.com/css?family=Roboto+Slab" rel="stylesheet">
<style>
body {
background: rgb(255, 246, 231);
}
* {
margin: 0;
padding: 0;
font-family: 'Roboto Slab', serif;
}
.dd-vc {
position: relative;
top: 50%;
transform: translateY(-50%);
}
.dd-transition {
transition: all 0.3s ease;
}
.dd-shadow {
box-shadow: 0 0 3px 1px rgba(0, 0, 0, 0.3);
}
#dragDrop {
width: 1000px;
margin: 20px auto 0;
position: relative;
}
.dd-slot {
float: left;
outline: 2px dashed rgba(54, 86, 132, 0.75);
outline-offset: -15px;
position: relative;
pointer-events: none;
}
.dd-slot-num {
text-align: center;
color: rgba(0, 0, 0, 0.1);
font-size: 40px;
position: absolute;
width: 100%;
}
.dd-item {
position: absolute;
left: 0;
top: 0;
box-sizing: border-box;
padding: 10px;
cursor: pointer;
}
.dd-item.dd-disabled {
pointer-events: none;
opacity: 0;
}
.dd-item.dd-selected {
z-index: 20;
}
.dd-item-inner {
background-repeat: no-repeat;
background-size: cover;
background-position: center;
width: 100%;
height: 100%;
position: relative;
}
.dd-item-panel {
width: 80%;
height: 35px;
background: #fff;
position: absolute;
left: 10%;
bottom: -15px;
z-index: 5;
}
.dd-item-title {
font-size: 15px;
color: #365684;
text-align: center;
line-height: 35px;
}
</style>
</head>
<body>
<div id="dragDrop"></div>
<script>
(async function () {
const url = 'https://picsum.photos/v2/list?page=2&limit=9';
const response = await fetch(url).then((response) => response.json())
const _imageLibrary = response.map(img => {
img.image = img.download_url
img.title = img.author
return img
})
const _listedImageIds = _imageLibrary.map(({
id
}) => id)
var _doc = window.document;
var _numOfImageSlots = 12,
_numOfImagesPerRow = 3,
_imageMarginBottom = 30;
var _imageAspectWidth = 1920,
_imageAspectHeight = 1080;
var _imageSlots = [],
_selectedImageElement = null,
_originalImageSlot = null,
_originalClickCoords = null,
_lastTouchedSlotId = null;
function init() {
addImageSlots();
drawImages();
_doc.getElementById('dragDrop').addEventListener('mousemove', imageMousemove);
}
function addImageSlots() {
var i = 0,
len = _numOfImageSlots,
item;
var wrap = _doc.getElementById('dragDrop');
for (; i < len; i++) {
item = _doc.createElement('div');
item.setAttribute('class', 'dd-slot');
item.setAttribute('style', 'width:' + (100 / _numOfImagesPerRow) + '%;padding-bottom:' + ((100 /
_numOfImagesPerRow) * (_imageAspectHeight / _imageAspectWidth)) + '%;margin-bottom:' +
_imageMarginBottom + 'px;');
item.innerHTML = '<p class="dd-slot-num dd-vc">' + (i + 1) + '</p>';
wrap.appendChild(item);
}
}
function drawImages() {
var i = 0,
len = _numOfImageSlots,
item;
var wrap = _doc.getElementById('dragDrop');
var slot = _doc.getElementsByClassName('dd-slot')[0],
bounds = slot.getBoundingClientRect(),
itemWidth = bounds.width,
itemHeight = bounds.height;
var itemX,
itemY;
var imageId,
image;
for (; i < len; i++) {
imageId = _listedImageIds[i] || -1;
image = getImageById(imageId);
itemX = (i % _numOfImagesPerRow) * itemWidth;
itemY = Math.floor(i / _numOfImagesPerRow) * (itemHeight + _imageMarginBottom);
item = _doc.createElement('div');
item.setAttribute('class', 'dd-item dd-transition' + (imageId < 0 ? ' dd-disabled' : ''));
item.setAttribute('data-image-id', imageId);
item.setAttribute('style', 'width:' + itemWidth + 'px;height:' + itemHeight +
'px;transform:translate3d(' +
itemX + 'px,' + itemY + 'px,0);');
item.innerHTML = '<div class="dd-item-inner dd-shadow" style="' + (image ? (
'background-image:url(' +
image.image + ')') : '') + '"><div class="dd-item-panel dd-shadow"><h3 class="dd-item-title">' + (
image ? image.title : '') + '</h3></div></div>';
wrap.appendChild(item);
item.addEventListener('mousedown', imageMousedown);
item.addEventListener('mouseup', imageMouseup);
_imageSlots[i] = {
width: itemWidth,
height: itemHeight,
x: itemX,
y: itemY
};
}
}
function arrangeItems() {
var i = 0,
len = _listedImageIds.length,
slot,
ele;
for (; i < len; i++) {
slot = _imageSlots[i];
ele = _doc.querySelector('[data-image-id="' + _listedImageIds[i] + '"]');
ele.style.transform = 'translate3d(' + slot.x + 'px,' + slot.y + 'px,0)';
}
}
function imageMousedown(event) {
if (!_selectedImageElement) {
_selectedImageElement = event.currentTarget;
_originalClickCoords = {
x: event.pageX,
y: event.pageY
};
_originalImageSlot = getIndexOfImageId(_selectedImageElement.getAttribute('data-image-id'));
_selectedImageElement.classList.add('dd-selected');
_selectedImageElement.classList.remove('dd-transition');
}
}
function imageMousemove(event) {
if (_selectedImageElement) {
var wrap = _doc.getElementById('dragDrop'),
bounds = wrap.getBoundingClientRect(),
left = bounds.left,
top = bounds.top;
var pageX = event.pageX,
pageY = event.pageY;
var clickX = pageX - left,
clickY = pageY - top,
hoverSlotId = getSlotIdByCoords({
x: clickX,
y: clickY
});
var ele = _selectedImageElement,
imageId = ele.getAttribute('data-image-id'),
index = _originalImageSlot,
newIndex = getIndexOfImageId(imageId),
x = _imageSlots[index].x,
y = _imageSlots[index].y;
var resultX = x + (pageX - _originalClickCoords.x),
resultY = y + (pageY - _originalClickCoords.y);
if (hoverSlotId != undefined && _lastTouchedSlotId != hoverSlotId) {
_lastTouchedSlotId = hoverSlotId;
_listedImageIds.splice(hoverSlotId, 0, _listedImageIds.splice(newIndex, 1)[0]);
arrangeItems();
}
ele.style.transform = 'translate3d(' + resultX + 'px,' + resultY + 'px,0)';
}
}
function imageMouseup() {
_selectedImageElement.classList.remove('dd-selected');
_selectedImageElement.classList.add('dd-transition');
_selectedImageElement = null;
_originalClickCoords = null;
arrangeItems();
}
function getSlotIdByCoords(coords) {
// Get the current slot being hovered over
for (var id in _imageSlots) {
var slot = _imageSlots[id];
if (slot.x <= coords.x && coords.x <= slot.x + slot.width && slot.y <= coords.y && coords.y <= slot.y +
slot
.height)
return id;
}
}
function getImageById(id) {
return _imageLibrary.find(function (image) {
return image.id == id;
});
}
function getIndexOfImageId(id) {
var i = 0,
len = _listedImageIds.length;
for (; i < len; i++)
if (_listedImageIds[i] == id)
return i;
}
init();
})();
</script>
</body>
</html>
I would like to make the face of this snake an image. Currently, it using a fill style with a color but I would like it to be an image. How can I do it with this code?
In addition, I want to find out how to add arrows so that it could work on a mobile phone. Thank you for anyone who can help or provide insight.
(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 = "#FFFFFF";
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 i = 0, x = snake.length; i < x; i++) {
if (snake[i].x < 0) {
snake[i].x = snake[i].x + (canvas.width / 10);
}
if (snake[i].x == canvas.width / 10) {
snake[i].x = snake[i].x - (canvas.width / 10);
}
if (snake[i].y < 0) {
snake[i].y = snake[i].y + (canvas.height / 10);
}
if (snake[i].y == canvas.height / 10) {
snake[i].y = snake[i].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();
}
}
}
}
})();
::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;
}
<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="320" height="320" 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>
Convert your image to a base64 string, then for the first dot/head use the image instead:
var img = new Image(); // Create new img element
img.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAMAAAC67D+PAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAA21BMVEXoTTvqTTzpUD7nTjzmTTvrUkDpTjzmSznUPSrVPCrnTDrSOSfTOizlTDrvoJnoqJ/pVkTmU0P5urH1p53mSTjjPiv7nZF0f4NZaGvpn5b9s6qDl5iira/+nI/jPirkPyz7lop+iYtleHzsnpT7raOTpqqqtbf4lovnSjf0lorylonpSDbnTDj5oZf2mIzlSDXkOyjIY1vrd2rrWEbZZ1zYQDLsTTroTz/lRjPalY7+///////j19fVSz7tTjvmTjntRjPialzZhH3sVkXsSzniRTTYQTDmSTbmTT3qb45jAAAAAWJLR0Q7OQ70bAAAAAd0SU1FB+QEDw4AEYzMSFoAAABvSURBVAjXY2BgZGJiZmFlZWNgYGDn4GTn4ubhBTJZ+PgFBIWERdgYRMXEJSSlpGVk5RjkFRSVlFVU1dTlGRg0NLW0dXT19JkZGNgMDI2MTUzNgNrMLSytrG1s7eyBbGYHRydnFwYwYHN1c/dgYAAAtKsKjnGo4BwAAAAldEVYdGRhdGU6Y3JlYXRlADIwMjAtMDQtMTVUMTQ6MDA6MTctMDQ6MDAVi7z/AAAAJXRFWHRkYXRlOm1vZGlmeQAyMDIwLTA0LTE1VDE0OjAwOjE3LTA0OjAwZNYEQwAAAABJRU5ErkJggg==";
for (var i = 0; i < snake.length; i++) {
if (!i) {
ctx.drawImage(img, snake[i].x * 10, snake[i].y * 10);
} else {
activeDot(snake[i].x, snake[i].y);
}
}
Here is a link to the website so that you can visualize the error im expressing in my title:
https://glassesled.com/aubrey
If you hover over the picture the zoom box doesn't follow the cursor and when you go the lower portions of the image the zoom box reaches a wall. Here are the relevant files (the ones I think are relevant)
The CloudZoom.min.js file
//////////////////////////////////////////////////////////////////////////////////
// Cloud Zoom V1.0.2
// (c) 2010 by R Cecco. <http://www.professorcloud.com>
// MIT License
//
// Please retain this copyright header in all versions of the software
//////////////////////////////////////////////////////////////////////////////////
! function($) {
function format(t) {
for (var o = 1; o < arguments.length; o++) t = t.replace("%" + (o - 1), arguments[o]);
return t
}
function CloudZoom(t, o) {
var e, i, s, a, n, r, l, d, u = $("img", t),
p = null,
c = null,
h = null,
m = null,
f = null,
g = null,
v = 0,
x = 0,
b = 0,
y = 0,
z = 0,
w = 0,
O = this;
setTimeout(function() {
if (null === c) {
var o = t.width();
t.parent().append(format('<div style="width:%0px;position:absolute;top:75%;left:%1px;text-align:center" class="cloud-zoom-loading" >Loading...</div>', o / 3, o / 2 - o / 6)).find(":last").css("opacity", .5)
}
}, 200);
var k = function() {
null !== g && (g.remove(), g = null)
};
this.removeBits = function() {
h && (h.remove(), h = null), m && (m.remove(), m = null), f && (f.remove(), f = null), k(), $(".cloud-zoom-loading", t.parent()).remove()
}, this.destroy = function() {
t.data("zoom", null), c && (c.unbind(), c.remove(), c = null), p && (p.remove(), p = null), this.removeBits()
}, this.fadedOut = function() {
p && (p.remove(), p = null), this.removeBits()
}, this.controlLoop = function() {
if (h) {
var t = r - u.offset().left - .5 * a >> 0,
e = l - u.offset().top - .5 * n >> 0;
0 > t ? t = 0 : t > u.outerWidth() - a && (t = u.outerWidth() - a), 0 > e ? e = 0 : e > u.outerHeight() - n && (e = u.outerHeight() - n), h.css({
left: t,
top: e
}), h.css("background-position", -t + "px " + -e + "px"), x = t / u.outerWidth() * s.width >> 0, b = e / u.outerHeight() * s.height >> 0, z += (x - z) / o.smoothMove, y += (b - y) / o.smoothMove, p.css("background-position", -(z >> 0) + "px " + (-(y >> 0) + "px"))
}
v = setTimeout(function() {
O.controlLoop()
}, 30)
}, this.init2 = function(t, o) {
w++, 1 === o && (s = t), 2 === w && this.init()
}, this.init = function() {
$(".cloud-zoom-loading", t.parent()).remove();
var e = $(".mousetrap");
e && e.remove(), c = $.browser.msie ? t.parent().append(format("<div class='mousetrap' style='background-image:url(\"/Plugins/SevenSpikes.Nop.Plugins.CloudZoom/Scripts/cloud-zoom.1.0.2/DummyPageForIE.htm\");z-index:999;position:absolute;width:%0px;height:%1px;left:%2px;top:%3px;'></div>", u.outerWidth(), u.outerHeight(), 0, 0)).find(":last") : t.parent().append(format("<div class='mousetrap' style='z-index:999;position:absolute;width:%0px;height:%1px;left:%2px;top:%3px;'></div>", u.outerWidth(), u.outerHeight(), 0, 0)).find(":last"), c.bind("mousemove", this, function(t) {
r = t.pageX, l = t.pageY
}), c.bind("mouseleave", this, function(t) {
return clearTimeout(v), h && h.fadeOut(299), m && m.fadeOut(299), f && f.fadeOut(299), p.fadeOut(300, function() {
O.fadedOut()
}), !1
}), c.bind("mouseenter", this, function(e) {
r = e.pageX, l = e.pageY, d = e.data, p && (p.stop(!0, !1), p.remove());
var i = o.adjustX,
v = o.adjustY,
x = u.outerWidth(),
b = u.outerHeight(),
y = o.zoomWidth,
z = o.zoomHeight;
"auto" == o.zoomWidth && (y = x), "auto" == o.zoomHeight && (z = b);
var w = t.parent();
switch (o.position) {
case "top":
v -= z;
break;
case "right":
i += x;
break;
case "bottom":
v += b;
break;
case "left":
i -= y;
break;
case "inside":
y = x, z = b;
break;
default:
w = $("#" + o.position), w.length ? (y = o.zoomWidth, z = o.zoomHeight) : (w = t, i += x, v += b)
}
p = w.append(format('<div id="cloud-zoom-big" class="cloud-zoom-big" style="display:none;position:absolute;left:%0px;top:%1px;width:%2px;height:%3px;background-image:url(\'%4\');z-index:99;"></div>', i, v, y, z, s.src)).find(":last"), u.attr("title") && o.showTitle && p.append(format('<div class="cloud-zoom-title">%0</div>', u.attr("title"))).find(":last").css("opacity", o.titleOpacity), $.browser.msie && $.browser.version < 7 && (g = $('<iframe frameborder="0" src="#"></iframe>').css({
position: "absolute",
left: i,
top: v,
zIndex: 99,
width: y,
height: z
}).insertBefore(p)), p.fadeIn(500), h && (h.remove(), h = null), a = u.outerWidth() / s.width * p.width(), n = u.outerHeight() / s.height * p.height(), h = t.append(format("<div class = 'cloud-zoom-lens' style='display:none;z-index:98;position:absolute;width:%0px;height:%1px;'></div>", a, n)).find(":last"), c.css("cursor", h.css("cursor"));
var O = !1;
o.tint && (h.css("background", 'url("' + u.attr("src") + '")'), m = t.append(format('<div class="cloud-zoom-tint" style="display:none;position:absolute; left:0px; top:0px; width:%0px; height:%1px; background-color:%2;" />', u.outerWidth(), u.outerHeight(), o.tint)).find(":last"), m.css("opacity", o.tintOpacity), O = !0, m.fadeIn(500)), o.softFocus && (h.css("background", 'url("' + u.attr("src") + '")'), f = t.append(format('<div class="cloud-zoom-softfocus" style="position:absolute;display:none;top:2px; left:2px; width:%0px; height:%1px;" />', u.outerWidth() - 2, u.outerHeight() - 2, o.tint)).find(":last"), f.css("background", 'url("' + u.attr("src") + '")'), f.css("opacity", .5), O = !0, f.fadeIn(500)), O || h.css("opacity", o.lensOpacity), "inside" !== o.position && h.fadeIn(500), d.controlLoop()
})
}, e = new Image, $(e).load(function() {
O.init2(this, 0)
}), e.src = u.attr("src"), i = new Image, $(i).load(function() {
O.init2(this, 1)
}), i.src = t.attr("href")
}
$(document).ready(function() {
$(".cloud-zoom, .cloud-zoom-gallery").CloudZoom()
}), $.fn.CloudZoom = function(options) {
try {
document.execCommand("BackgroundImageCache", !1, !0)
} catch (e) {}
return this.each(function() {
var relOpts, opts;
eval("var a = {" + $(this).attr("rel") + "}"), relOpts = a, $(this).is(".cloud-zoom") ? ($(this).css({
position: "relative",
display: "block"
}), $("img", $(this)).css({
display: "block"
}), "wrap" != $(this).parent().attr("id") && $(this).wrap('<div id="wrap" style="top:0px;position:relative;"></div>'), opts = $.extend({}, $.fn.CloudZoom.defaults, options), opts = $.extend({}, opts, relOpts), $(this).data("zoom", new CloudZoom($(this), opts))) : $(this).is(".cloud-zoom-gallery") && (opts = $.extend({}, relOpts, options), $(this).data("relOpts", opts), $(this).bind("click", $(this), function(t) {
var o = t.data.data("relOpts");
return $("#" + o.useZoom).data("zoom").destroy(), $("#" + o.useZoom).attr("href", t.data.attr("href")), $("#" + o.useZoom).attr("rel", t.data.attr("rel")), $("#" + o.useZoom + " img").attr("title", t.data.attr("title")), $("#" + o.useZoom + " img").attr("src", t.data.data("relOpts").smallImage), $("#" + t.data.data("relOpts").useZoom).CloudZoom(), !1
}))
}), this
}, $.fn.CloudZoom.defaults = {
zoomWidth: "auto",
zoomHeight: "auto",
position: "right",
tint: !1,
tintOpacity: .5,
lensOpacity: .5,
softFocus: !1,
smoothMove: 3,
showTitle: !0,
titleOpacity: .5,
adjustX: 0,
adjustY: 0
}
}(jQuery);
CSS file used in cshtml
/*
* Copyright 2014 Seven Spikes Ltd. All rights reserved. (http://www.nop-templates.com)
* http://www.nop-templates.com/t/licensinginfo
*/
#media all and (max-width: 1000px) {
#sevenspikes-cloud-zoom:before {
display: none;
}
#sevenspikes-cloud-zoom img {
position: static;
}
}
#media all and (min-width: 1001px) {
/* theme overwritting styles */
.gallery {
font-size: 0;
}
.gallery .picture-wrapper {
/*** !!! set line-height to the appropriate height !!! ***/
line-height: 320px;
}
.gallery .picture-wrapper .picture:before {
display: none;
}
/* main picture styles */
#sevenspikes-cloud-zoom {
margin: 0;
overflow: visible;
text-align: center;
font-size: 0;
}
#sevenspikes-cloud-zoom:before {
display: none;
}
#wrap {
display: block;
max-width: 100%;
vertical-align: middle;
line-height: 0;
}
#wrap a {
position: relative;
max-width: 100%;
vertical-align: middle;
line-height: 0;
overflow: hidden;
}
#wrap a:before {
content: "";
display: block;
padding-top: 125%;
}
#wrap img {
}
/* This is the overlay element. */
#wrap > .mousetrap {
right: 0;
bottom: 0;
margin: auto;
}
.cloud-zoom-lens {
margin: 0;
border: none;
background-color: #fff;
cursor: crosshair;
}
/* This is the zoom window. */
#cloudZoomWindowElement {
left: 0;
top: 0;
z-index: 1;
}
#cloud-zoom-big {
border: none;
overflow: hidden;
bottom: 0;
margin: auto;
}
.overview #cloud-zoom-big {
position: static !important; /* fix for the zoom window so that its wrapper takes the dimensions */
}
/* This is for the title text. */
.cloud-zoom-title {
background-color: #000;
padding: 5px;
text-align: center;
font-size: 11px;
line-height: normal;
font-weight: bold;
color: #fff;
}
/* This is the loading message. */
.cloud-zoom-loading {
width: 100% !important;
height: 100% !important;
top: 0 !important;
left: 0 !important;
right: 0 !important;
bottom: 0 !important;
font-size: 0;
background: rgba(255,255,255,.5);
opacity: 1 !important;
}
#keyframes spinner {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
.cloud-zoom-loading:after,
.cloud-zoom-loading:before {
content: '';
position: absolute;
border: 2px solid #454545;
width: 30px;
height: 30px;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
outline: 1px solid transparent; /*firefox fix*/
}
.cloud-zoom-loading:after {
animation: spinner 2.5s linear infinite;
}
.cloud-zoom-loading:before {
width: 44px;
height: 44px;
animation: spinner 2.5s linear infinite;
animation-direction: reverse;
}
/* with product ribbons enabled */
.gallery .ribbon-wrapper {
/*never display as inline or inline-block*/
vertical-align: middle;
line-height: 0;
}
.gallery .ribbon-wrapper:hover .ribbon-position {
opacity: 0;
}
}
CSHTML file
#** Copyright 2016 Seven Spikes Ltd. All rights reserved. (http://www.nop-templates.com)
* http://www.nop-templates.com/t/licensinginfo
*#
#using Nop.Core
#using Nop.Core.Infrastructure
#using SevenSpikes.Nop.Plugins.CloudZoom.Models
#model CloudZoomModel
#if (!string.IsNullOrEmpty(Model.DefaultPicture.FullSizeImageUrl))
{
Html.AddCssFileParts("~/Plugins/SevenSpikes.Nop.Plugins.CloudZoom/Themes/" + Model.Theme + "/Content/cloud-zoom.1.0.2/CloudZoom.css");
var supportRtl = EngineContext.Current.Resolve<IWorkContext>().WorkingLanguage.Rtl;
if (supportRtl)
{
Html.AddCssFileParts("~/Plugins/SevenSpikes.Nop.Plugins.CloudZoom/Styles/CloudZoom.common.rtl.css");
}
Html.AddScriptParts("~/Plugins/SevenSpikes.Core/Scripts/SevenSpikesExtensions.min.js");
Html.AddScriptParts("~/Plugins/SevenSpikes.Nop.Plugins.CloudZoom/Scripts/cloud-zoom.1.0.2/cloud-zoom.1.0.2.min.js");
if (Model.IsIntegratedByWidget)
{
Html.AddScriptParts("~/Plugins/SevenSpikes.Nop.Plugins.CloudZoom/Scripts/CloudZoom.min.js");
}
if (Model.EnableClickToZoom)
{
Html.AddCssFileParts("~/Content/magnific-popup/magnific-popup.css");
Html.AddScriptParts("~/Scripts/jquery.magnific-popup.min.js");
<script type="text/javascript">
$(document).ready(function () {
$(".picture").on("click", ".mousetrap", function () {
var mainPictureHref = $('.picture a.cloud-zoom').attr('href');
var cloudZoomThumbs = $('.picture-thumbs a.cloud-zoom-gallery');
var imgSources = new Array();
var imgItem = function(source) {
this.src = source;
};
cloudZoomThumbs.each(function(){
imgSources.push(new imgItem($(this).attr('href')));
});
if(imgSources.length === 0){
imgSources.push(new imgItem(mainPictureHref));
}
$.magnificPopup.open({
items: imgSources,
type: 'image',
removalDelay: 300,
gallery: {
enabled: true
}
}, cloudZoomThumbs.filter('.active').index());
});
});
</script>
}
<script type="text/javascript">
#{
string pictureAdjustmentTableName = string.Format("productAttributeValueAdjustmentTable_{0}", Model.ProductId);
string pictureAdjustmentFuncName = string.Format("adjustProductAttributeValuePicture_CloudZoom_{0}", Model.ProductId);
string pictureFullSizePrefix = "fullsize";
}
function #(pictureAdjustmentFuncName)(controlId) {
var ctrl = $('#' + controlId);
var pictureFullSizeUrl = '';
if((ctrl.is(':radio') && ctrl.is(':checked')) || (ctrl.is(':checkbox') && ctrl.is(':checked'))) {
pictureFullSizeUrl = #(pictureAdjustmentTableName)[controlId + '_#(pictureFullSizePrefix)'];
} else if(ctrl.is('select')) {
var idx = $('#' + controlId + " option").index($('#' + controlId + " option:selected"));
if(idx !== -1) {
pictureFullSizeUrl = #(pictureAdjustmentTableName)[controlId + '_#(pictureFullSizePrefix)'][idx];
}
}
if (typeof pictureFullSizeUrl == 'string' && pictureFullSizeUrl !== '') {
var zoomGallerySelector = ".cloud-zoom-gallery[href='" + pictureFullSizeUrl + "']";
$(zoomGallerySelector).click();
$.event.trigger({
type: 'nopMainProductImageChanged',
target: ctrl,
pictureDefaultSizeUrl: pictureFullSizeUrl,
pictureFullSizeUrl: pictureFullSizeUrl
});
}
}
$(document).ready(function () {
$("[id^='product_attribute_']").on('change', function() {
#(pictureAdjustmentFuncName)($(this).attr('id'));
});
});
</script>
<div class="gallery sevenspikes-cloudzoom-gallery">
<div class="picture-wrapper">
<div class="picture" id="sevenspikes-cloud-zoom" data-zoomwindowelementid="#Model.ElementId"
data-selectoroftheparentelementofthecloudzoomwindow="#Model.SettingsModel.SelectorOfTheParentElementOfTheCloudZoomWindow"
data-defaultimagecontainerselector="#Model.SettingsModel.DefaultImageContainerSelector">
<a href="#Model.DefaultPicture.FullSizeImageUrl" class="cloud-zoom" id="zoom1" rel="#Model.DefaultPicture.DefaultRelation">
<img src="#Model.DefaultPicture.SmallImageUrl" alt="#Model.DefaultPicture.AlternateText" title="#Model.DefaultPicture.Title" id="cloudZoomImage" itemprop="image" />
</a>
#if (Model.Pictures.Count > 1)
{
<div class="picture-thumbs-navigation-arrow picture-thumbs-prev-arrow">
<span>#T("SevenSpikes.Themes.Uptown.Product.ImageThumbs.Prev")</span>
<img src="#Model.DefaultPicture.TinyImageUrl" data-fullSizeImageUrl="#Model.DefaultPicture.FullSizeImageUrl" alt="Previous" />
</div>
<div class="picture-thumbs-navigation-arrow picture-thumbs-next-arrow">
<span>#T("SevenSpikes.Themes.Uptown.Product.ImageThumbs.Next")</span>
<img src="#Model.DefaultPicture.TinyImageUrl" data-fullSizeImageUrl="#Model.DefaultPicture.FullSizeImageUrl" alt="Next" />
</div>
<div class="picture-thumbs">
#foreach (var picture in Model.Pictures)
{
<a class="cloud-zoom-gallery" href="#picture.FullSizeImageUrl" title="#picture.Title" rel="#picture.GalleryRelation">
<img class="cloud-zoom-gallery-img" src="#picture.TinyImageUrl" alt="#picture.AlternateText" title="#picture.Title" />
</a>
}
</div>
}
</div>
</div>
</div>
}
Any ideas? More files needed to resolve this issue? LMK!
I'm currently developing a platform little game in only js/jQuery. I have two scripts, one i currently detecting platforms and let the character go on it instead of falling. And one with a nice smooth jump. I'd like to merge them, but for some reason i just can't. When i try to do it, my character do not move anymore...
So if you have any ideas on how i could do that, it would be awesome, really.
Here are my scripts, hope you guys will find out what i can't..
//------------------ VIE -------------------------------
function CLife(iPlayerNum) {
// iPlayerNum est egal a 1 ou 2
this.propNumPlayer = iPlayerNum;
// Image pour la vie
this.ImgHeight = 30;
this.ImgWidth = 30;
this.ImgName = 'heart.png';
// Nb de vie
this.NbLife = 3;
}
CLife.prototype.Creer = function()
{
// Créer la ligne d'etoiles
var parent = document.getElementById("vie");
var child = document.createElement('div'+this.propNumPlayer);
child.setAttribute('id','div_life'+this.propNumPlayer);
if(this.propNumPlayer == 1)
{
// Joueur 1 a gauche
child.setAttribute('style','float:left; height:'+this.ImgHeight+'px; width: '+this.NbLife*this.ImgWidth+'px;');
}
else
{
// Joueur 2 a droite
child.setAttribute('style','float:right; height:'+this.ImgHeight+'px; width: '+this.NbLife*this.ImgWidth+'px;');
}
parent.appendChild(child);
// Ajouter les coeurs
parent = document.getElementById('div_life'+this.propNumPlayer);
for(var i=0; i < this.NbLife; i++)
{
child = document.createElement('img');
child.setAttribute('id','img_'+(i+1)+'_'+this.propNumPlayer);
child.setAttribute('src','img/'+this.ImgName);
child.setAttribute('width','30 px');
child.setAttribute('height','30 px');
parent.appendChild(child);
}
}
// YJoueur : ordonnée du joueur + la hauteur de l'image associee au joueur
CLife.prototype.TestFinVie = function(iYJoueur)
{
var valret = false;
console.log('Joueur : ' + iYJoueur);
console.log('Fenetre : ' + $(window).height());
//if(iYJoueur <= 10/*>= $(window).height()*/)
if(iYJoueur >= $(window).height())
{
star = document.getElementById('img_'+this.NbLife+'_'+this.propNumPlayer);
if (star != null)
{
star.style.display = 'none';
this.NbLife = this.NbLife - 1;
valret = true;
}
}
return valret;
}
//------------------ VIE -------------------------------
setInterval(bougerPersonnages, 9); //Vitesse de déplacement.
var touche = {}
var jumping = false;
var jumpingChomel = false;
var browserHeight = parseInt(document.documentElement.clientHeight);
var batmanHurt = 0;
var batmanPosX = $("#batman").offset().left;
var chomelPosX = $("#chomel").offset().left;
var tombe = false;
var life1 = new CLife(2);
var life2 = new CLife(1);
life1.Creer();
life2.Creer();
$(document).keydown(function(e) { //Fonctionne
touche[e.keyCode] = true;
});
$(document).keyup(function(e) { //Fonctionne
delete touche[e.keyCode];
});
//------INTEGRATION COLLISION DE PLATEFORME----------
//
var platforms = [];
var currentPlatform = null;
var $batman = $('#batman');
function bougerPersonnages() {
if(tombe == true)
{
// tester la fin de vie des personnages
var YPos = parseInt($("#batman").offset().top) + parseInt($("#batman").height()) + 10; // car le personnage tombe au plus bas à 10 px du bas de l'écran
if (life1.TestFinVie(YPos) == true)
{
//reinitialiser le personnage
document.getElementById('batman').setAttribute('class','dirGauche');
document.getElementById('batman').setAttribute('style','left: 1100px; bottom: 580px;');
}
YPos = parseInt($("#chomel").offset().top) + parseInt($("#chomel").height()) + 10; // car le personnage tombe au plus bas à 10 px du bas de l'écran
if (life2.TestFinVie(YPos) == true)
{
//reinitialiser le personnage
document.getElementById('chomel').setAttribute('class','dirGauche');
document.getElementById('chomel').setAttribute('style','left: 900px; bottom: 580px;');
}
tombe = false;
}
var top = $batman.offset().top;
var left = $batman.offset().left;
var newTop = top;
var newLeft = left;
for (var direction in touche) {
if (direction == 37) { //Fonctionne
batman.className = 'dirGauche';
$("#batman").css('left', '-=5px');
} else if (direction == 81) { //Fonctionne
chomel.className = 'dirGauche';
$("#chomel").css('left', '-=5px');
} else if (direction == 39) { //Fonctionne
batman.className = 'dirDroite';
$("#batman").css('left', '+=5px');
} else if (direction == 68) { //Fonctionne
chomel.className = 'dirDroite';
$("#chomel").css('left', '+=5px');
} else if (direction == 38) { //Fonctionne
if (!jumping) {
jumping = true;
$("#batman").animate({bottom: 300 + "px"}, 300);
$("#batman").animate({bottom: 10 + "px"}, 300);
setTimeout(land, 650);
}
}
else if (direction == 90) { //Fonctionne
if (!jumpingChomel) {
jumpingChomel = true;
$("#chomel").animate({bottom: 300 + "px"}, 300);
setTimeout(function() {$("#chomel").animate({bottom: 10 + "px"}, 300) }, 350);
setTimeout(landChomel, 650);
}
}
}
var batmanRect = getRectangle($("#batman"));
var chomelRect = getRectangle($("#chomel"));
$(".arrow1").each(function () {
var rect = getRectangle($(this));
if (intersectingRectangles(batmanRect, rect)) {
var batmanPosX = $("#batman").offset().left;
var chomelPosX = $("#chomel").offset().left;
console.log("batman has been shot!");
console.log("batman:" + batmanPosX);
console.log("chomel:" + chomelPosX);
console.log($(this).attr('data-arrow'));
if (batmanPosX < chomelPosX && $(this).attr('data-arrow') == "chomelShoot") {
$("#batman").animate({left: "-=50px"}, 40);
}
else if ($(this).attr('data-arrow') == "chomelShoot"){
$("#batman").animate({left: "+=50px"}, 40);
}
} else if (intersectingRectangles(chomelRect, rect)) {
var batmanPosX = $("#batman").offset().left;
var chomelPosX = $("#chomel").offset().left;
console.log("batman has been shot!");
console.log("batman:" + batmanPosX);
console.log("chomel:" + chomelPosX);
console.log($(this).attr('data-arrow'));
if (chomelPosX < batmanPosX && $(this).attr('data-arrow') == "batmanShoot") {
$("#chomel").animate({left: "-=50px"}, 40);
}
else if ($(this).attr('data-arrow') == "batmanShoot"){
$("#chomel").animate({left: "+=50px"}, 40);
}
}
});
$(".collidableRectangle").each(function () {
var rect = getRectangle($(this));
if (intersectingRectangles(batmanRect, rect)) {
console.log("BATMAN has hit a platform!");
}
});
$(".collidableRectangle").each(function () {
var rect = getRectangle($(this));
if (intersectingRectangles(chomelRect, rect)) {
console.log("CHOMEL has hit a platform!");
}
});
}
function land() {
jumping = false;
tombe = true;
}
function landChomel() {
jumpingChomel = false;
tombe = true;
}
document.addEventListener('keydown', function(e) { // Déclenche la fonction fire
switch (e.keyCode) {
case 76:
fire_batman();
break;
case 32:
fire_chomel();
break;
}
});
function fire_chomel() { //Fonctionne
var posTop = parseInt($(chomel).offset().top);
if (chomel.className == 'dirGauche') {
var posLeft = parseInt($(chomel).offset().left) - 30;
}
else {
var posLeft = parseInt($(chomel).offset().left) + 120;
}
var bullets = $('#arrow1');
var bulletElement = $('<div class="arrow1" data-arrow="chomelShoot" style="top: ' + (posTop + 14) + 'px; left: ' + posLeft + 'px"></div>');
bullets.append(bulletElement);
if (chomel.className == 'dirGauche') {
var options = {left: browserHeight * -15};
}
else {
var options = {left: browserHeight * 15};
}
ok = new Audio('sound/pistolet.mp3');
ok.play();
bulletElement.animate(options, 2000, "linear", function () {
$(this).remove();
});
}
function fire_batman() { //Fonctionne
var posTop = parseInt($(batman).offset().top) - 27;
if (batman.className == 'dirGauche') {
var posLeft = parseInt($(batman).offset().left) - 51;
}
else {
var posLeft = parseInt($(batman).offset().left) + 106;
}
var bullets = $('#arrow1');
var bulletElement = $('<div class="arrow1" data-arrow="batmanShoot" style="top: ' + (posTop + 50) + 'px; left: ' + posLeft + 'px"></div>');
bullets.append(bulletElement);
if (batman.className == 'dirGauche') {
var options = {left: browserHeight * -15};
}
else {
var options = {left: browserHeight * 15};
}
ok = new Audio('sound/pistolet.mp3');
ok.play();
bulletElement.animate(options, 2000, "linear", function () {
$(this).remove();
});
}
function intersectingRectangles(r1, r2) {
return !(r2.left > r1.right ||
r2.right < r1.left ||
r2.top > r1.bottom ||
r2.bottom < r1.top);
}
function getRectangle(figure) {
var rect = {};
rect.left = figure.offset().left;
rect.top = figure.offset().top;
rect.right = rect.left + figure.width();
rect.bottom = rect.top + figure.height();
return rect;
}
body {
padding: 0;
margin: 0;
background: url('http://image.noelshack.com/fichiers/2015/16/1429209179-bg.png');
background-color: #B4381F;
background-repeat: no-repeat;
background-attachment: fixed;
background-size: 100%;
background-position: 50% 30%;
overflow: hidden;
}
#batman{
background-image:url('http://image.noelshack.com/fichiers/2015/16/1429209179-batman.png');
width:119px;
height:87px;
display:block;
background-repeat: no-repeat;
position:absolute;
}
#chomel{
background-image:url('http://image.noelshack.com/fichiers/2015/16/1429209179-chomel.png');
width:107px;
height:87px;
display:block;
background-repeat: no-repeat;
position:absolute;
}
.dirDroite{
background-position: -140px 0px;
}
.dirGauche{
background-position: 0px 0px;
}
#hautGauche{
margin-top: 25vh;
position: fixed;
width: 15vw;
margin-left: 30vh;
height: 3vh;
background-color: #663303;
z-index: 1;
}
#hautDroite{
margin-top: 25vh;
position: fixed;
width: 15vw;
margin-left: 125vh;
height: 3vh;
background-color: #663303;
z-index: 2;
}
#milieu{
margin-top: 45vh;
position: fixed;
width: 50vw;
margin-left: 45vh;
height: 3vh;
background-color: #663303;
z-index: 3;
}
#basGauche{
margin-top: 65vh;
position: fixed;
width: 25vw;
margin-left: 27.75vh;
height: 3vh;
background-color: #663303;
z-index: 4;
}
#basDroite{
margin-top: 65vh;
position: fixed;
width: 22.18vw;
margin-left: 132.8vh;
height: 3vh;
background-color: #663303;
z-index: 5;
}
#base{
margin-top: 85vh;
position: fixed;
width: 49.77vw;
margin-left: 50.7vh;
height: 3vh;
background-color: #663303;
z-index: 6;
}
#invisible {
position: fixed;
right: 0;
bottom: 0px;
left: 0;
z-index: 200;
margin: auto;
background-color: black;
width: 100%;
height: 30px;
opacity: 0;
z-index: 7;
}
.arrow1 {
position: absolute;
z-index: 3;
width: 50px;
height: 11px;
background: url('http://image.noelshack.com/fichiers/2015/16/1429209179-bullet.png') 43px 19px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>LEVEL 1</title>
<link rel="stylesheet" type="text/css" href="style.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
</head>
<body>
<div data-platform="true" id="hautGauche" class="collidableRectangle"></div>
<div data-platform="true" id="hautDroite" class="collidableRectangle"></div>
<div data-platform="true" id="milieu" class="collidableRectangle"></div>
<div data-platform="true" id="basGauche" class="collidableRectangle"></div>
<div data-platform="true" id="basDroite" class="collidableRectangle"></div>
<div data-platform="true" id="base" class="collidableRectangle"></div>
<div data-platform="true" id="invisible"></div>
<div id="arrow1"></div>
<span style="margin-left:50px;" id="result"></span>
<div id="batman" class="dirGauche" style="left: 1100px; bottom: 580px;"></div>
<div id="chomel" class="dirGauche" style="left: 900px; bottom: 580px;"></div>
<div id="vie">
</div>
</div>
<script src="scripts/script.js" ></script>
</body>
</html>
The code above is the one with the working jump, here is the one with the working platforms :
var platforms = [];
var currentPlatform = null;
var $roger = $('#batman');
$(document).on('keydown', function (e) {
var top = $roger.offset().top;
var left = $roger.offset().left;
var newTop = top;
var newLeft = left;
switch (e.keyCode) {
case 32:
newTop = top - 400;
$roger.css("top", newTop);
setTimeout(function () {
$roger.css("top", top);
}, 100);
break;
case 37:
newLeft = left - 50;
$roger.css({left: newLeft});
break;
case 39:
newLeft = left + 50;
$roger.css({left: newLeft});
break;
}
});
setInterval(function () {
verifyPlatform();
}, 50);
$('[data-platform="true"]').each(function () {
var $element = $(this);
var x = $element.offset().left;
var y = $element.offset().top;
var xw = x + $element.width();
var yh = y + $element.height();
platforms.push({
element: $element,
x: x,
y: y,
xw: xw,
yh: yh
});
});
function getPlatformAvailable(platforms) {
var persoX = $roger.offset().left;
var persoYH = $roger.offset().top + $roger.height();
for (platform in platforms) {
var current = platforms[platform];
if (
((persoX + 50) >= current.x && persoX <= current.xw) &&
((persoYH) <= current.y)
) {
return current;
}
}
return false;
}
function verifyPlatform() {
var platformAvailable = getPlatformAvailable(platforms);
var platformAvailableString = platformAvailable.x +":"+ platformAvailable.y;
if (platformAvailable && platformAvailableString != currentPlatform) {
currentPlatform = platformAvailableString;
$roger.css('top', (platformAvailable.y - $roger.height()));
}
}
Thanks guys if you can understand and help me, i've been trying all day long.
Cheers !
I see you are binding the same event twice:
In the first code snippet:
$(document).keydown(function(e) { //Fonctionne
touche[e.keyCode] = true;
});
In the second code snippet:
$(document).on('keydown', function (e) {
var top = $roger.offset().top;
var left = $roger.offset().left;
var newTop = top;
var newLeft = left;
switch (e.keyCode) {
case 32:
newTop = top - 400;
$roger.css("top", newTop);
setTimeout(function () {
$roger.css("top", top);
}, 100);
break;
case 37:
newLeft = left - 50;
$roger.css({left: newLeft});
break;
case 39:
newLeft = left + 50;
$roger.css({left: newLeft});
break;
}
});
If you merge both codes together, that means that these 2 events will conflict and only one of the two will work.
Solution
Merge them properly together like this to solve it:
$(document).on('keydown', function (e) {
touche[e.keyCode] = true;
var top = $roger.offset().top;
var left = $roger.offset().left;
var newTop = top;
var newLeft = left;
switch (e.keyCode) {
case 32:
newTop = top - 400;
$roger.css("top", newTop);
setTimeout(function () {
$roger.css("top", top);
}, 100);
break;
case 37:
newLeft = left - 50;
$roger.css({left: newLeft});
break;
case 39:
newLeft = left + 50;
$roger.css({left: newLeft});
break;
}
});