How can I fix height, container with scrollbar - javascript

I'm using a simple JavaScript. I change the container's height and width. I think I need to fix the JavaScript, because it is working on the container which as height set in px, but I have set the height as %. The problem is appearing when you resize (you can't see full img or there is too much space) on bottom of the container.
Or maybe I'm wrong... Any tips?
function jsScroller (o, w, h) {
var self = this;
var list = o.getElementsByTagName("div");
for (var i = 0; i < list.length; i++) {
if (list[i].className.indexOf("Scroller-Container") > -1) {
o = list[i];
}
}
//Private methods
this._setPos = function (x, y) {
if (x < this.viewableWidth - this.totalWidth)
x = this.viewableWidth - this.totalWidth;
if (x > 0) x = 0;
if (y < this.viewableHeight - this.totalHeight)
y = this.viewableHeight - this.totalHeight;
if (y > 0) y = 0;
this._x = x;
this._y = y;
with (o.style) {
left = this._x +"px";
top = this._y +"px";
}
};
//Public Methods
this.reset = function () {
this.content = o;
this.totalHeight = o.offsetHeight;
this.totalWidth = o.offsetWidth;
this._x = 0;
this._y = 0;
with (o.style) {
left = "0px";
top = "0px";
}
};
this.scrollBy = function (x, y) {
this._setPos(this._x + x, this._y + y);
};
this.scrollTo = function (x, y) {
this._setPos(-x, -y);
};
this.stopScroll = function () {
if (this.scrollTimer) window.clearInterval(this.scrollTimer);
};
this.startScroll = function (x, y) {
this.stopScroll();
this.scrollTimer = window.setInterval(
function(){ self.scrollBy(x, y); }, 40
);
};
this.swapContent = function (c, w, h) {
o = c;
var list = o.getElementsByTagName("div");
for (var i = 0; i < list.length; i++) {
if (list[i].className.indexOf("Scroller-Container") > -1) {
o = list[i];
}
}
if (w) this.viewableWidth = w;
if (h) this.viewableHeight = h;
this.reset();
};
//variables
this.content = o;
this.viewableWidth = w;
this.viewableHeight = h;
this.totalWidth = o.offsetWidth;
this.totalHeight = o.offsetHeight;
this.scrollTimer = null;
this.reset();
};
function jsScrollbar (o, s, a, ev) {
var self = this;
this.reset = function () {
//Arguments that were passed
this._parent = o;
this._src = s;
this.auto = a ? a : false;
this.eventHandler = ev ? ev : function () {};
//Component Objects
this._up = this._findComponent("Scrollbar-Up", this._parent);
this._down = this._findComponent("Scrollbar-Down", this._parent);
this._yTrack = this._findComponent("Scrollbar-Track", this._parent);
this._yHandle = this._findComponent("Scrollbar-Handle", this._yTrack);
//Height and position properties
this._trackTop = findOffsetTop(this._yTrack);
this._trackHeight = this._yTrack.offsetHeight;
this._handleHeight = this._yHandle.offsetHeight;
this._x = 0;
this._y = 0;
//Misc. variables
this._scrollDist = 5;
this._scrollTimer = null;
this._selectFunc = null;
this._grabPoint = null;
this._tempTarget = null;
this._tempDistX = 0;
this._tempDistY = 0;
this._disabled = false;
this._ratio = (this._src.totalHeight - this._src.viewableHeight)/(this._trackHeight - this._handleHeight);
this._yHandle.ondragstart = function () {return false;};
this._yHandle.onmousedown = function () {return false;};
this._addEvent(this._src.content, "mousewheel", this._scrollbarWheel);
this._removeEvent(this._parent, "mousedown", this._scrollbarClick);
this._addEvent(this._parent, "mousedown", this._scrollbarClick);
this._src.reset();
with (this._yHandle.style) {
top = "0px";
left = "0px";
}
this._moveContent();
if (this._src.totalHeight < this._src.viewableHeight) {
this._disabled = true;
this._yHandle.style.visibility = "hidden";
if (this.auto) this._parent.style.visibility = "hidden";
} else {
this._disabled = false;
this._yHandle.style.visibility = "visible";
this._parent.style.visibility = "visible";
}
};
this._addEvent = function (o, t, f) {
if (o.addEventListener) o.addEventListener(t, f, false);
else if (o.attachEvent) o.attachEvent('on'+ t, f);
else o['on'+ t] = f;
};
this._removeEvent = function (o, t, f) {
if (o.removeEventListener) o.removeEventListener(t, f, false);
else if (o.detachEvent) o.detachEvent('on'+ t, f);
else o['on'+ t] = null;
};
this._findComponent = function (c, o) {
var kids = o.childNodes;
for (var i = 0; i < kids.length; i++) {
if (kids[i].className && kids[i].className == c) {
return kids[i];
}
}
};
//Thank you, Quirksmode
function findOffsetTop (o) {
var t = 0;
if (o.offsetParent) {
while (o.offsetParent) {
t += o.offsetTop;
o = o.offsetParent;
}
}
return t;
};
this._scrollbarClick = function (e) {
if (self._disabled) return false;
e = e ? e : event;
if (!e.target) e.target = e.srcElement;
if (e.target.className.indexOf("Scrollbar-Up") > -1) self._scrollUp(e);
else if (e.target.className.indexOf("Scrollbar-Down") > -1) self._scrollDown(e);
else if (e.target.className.indexOf("Scrollbar-Track") > -1) self._scrollTrack(e);
else if (e.target.className.indexOf("Scrollbar-Handle") > -1) self._scrollHandle(e);
self._tempTarget = e.target;
self._selectFunc = document.onselectstart;
document.onselectstart = function () {return false;};
self.eventHandler(e.target, "mousedown");
self._addEvent(document, "mouseup", self._stopScroll, false);
return false;
};
this._scrollbarDrag = function (e) {
e = e ? e : event;
var t = parseInt(self._yHandle.style.top);
var v = e.clientY + document.body.scrollTop - self._trackTop;
with (self._yHandle.style) {
if (v >= self._trackHeight - self._handleHeight + self._grabPoint)
top = self._trackHeight - self._handleHeight +"px";
else if (v <= self._grabPoint) top = "0px";
else top = v - self._grabPoint +"px";
self._y = parseInt(top);
}
self._moveContent();
};
this._scrollbarWheel = function (e) {
e = e ? e : event;
var dir = 0;
if (e.wheelDelta >= 120) dir = -1;
if (e.wheelDelta <= -120) dir = 1;
self.scrollBy(0, dir * 20);
e.returnValue = false;
};
this._startScroll = function (x, y) {
this._tempDistX = x;
this._tempDistY = y;
this._scrollTimer = window.setInterval(function () {
self.scrollBy(self._tempDistX, self._tempDistY);
}, 40);
};
this._stopScroll = function () {
self._removeEvent(document, "mousemove", self._scrollbarDrag, false);
self._removeEvent(document, "mouseup", self._stopScroll, false);
if (self._selectFunc) document.onselectstart = self._selectFunc;
else document.onselectstart = function () { return true; };
if (self._scrollTimer) window.clearInterval(self._scrollTimer);
self.eventHandler (self._tempTarget, "mouseup");
};
this._scrollUp = function (e) {this._startScroll(0, -this._scrollDist);};
this._scrollDown = function (e) {this._startScroll(0, this._scrollDist);};
this._scrollTrack = function (e) {
var curY = e.clientY + document.body.scrollTop;
this._scroll(0, curY - this._trackTop - this._handleHeight/2);
};
this._scrollHandle = function (e) {
var curY = e.clientY + document.body.scrollTop;
this._grabPoint = curY - findOffsetTop(this._yHandle);
this._addEvent(document, "mousemove", this._scrollbarDrag, false);
};
this._scroll = function (x, y) {
if (y > this._trackHeight - this._handleHeight)
y = this._trackHeight - this._handleHeight;
if (y < 0) y = 0;
this._yHandle.style.top = y +"px";
this._y = y;
this._moveContent();
};
this._moveContent = function () {
this._src.scrollTo(0, Math.round(this._y * this._ratio));
};
this.scrollBy = function (x, y) {
this._scroll(0, (-this._src._y + y)/this._ratio);
};
this.scrollTo = function (x, y) {
this._scroll(0, y/this._ratio);
};
this.swapContent = function (o, w, h) {
this._removeEvent(this._src.content, "mousewheel", this._scrollbarWheel, false);
this._src.swapContent(o, w, h);
this.reset();
};
this.reset();
};
#no-template-pager {
width: 34%;
height: 25vw;
overflow: hidden;
white-space: nowrap;
float: left;
}
.Scroller-Container {
position: relative;
width: 100%;
height: 100%;
}
#Scrollbar-Container {
position: relative;
top: 0px;
left: 0%;
background: green;
width: 1%;
height: 100%;
overflow: hidden;
}
.Scrollbar-Track {
width: 100%;
height: 100%;
position: absolute;
background: #222;
}
.Scrollbar-Handle {
position: absolute;
width: 100%;
height: 70%;
background: #8E8E8E;
-webkit-border-radius: 15px;
-moz-border-radius: 15px;
border-radius: 15px;
}
.Scrollbar-Handle:hover, .Scrollbar-Handle:active {
background: #fff;
}
#slider2 {
margin: 50px auto;
width: 60%;
height: 25vw;
background: #222;
}
#youtube {
width: 65%;
height: 25vw;
float: right;
background: blue;
}
.thumbs {
width: 100%;
height: 25%;
box-shadow: 0 -1px 0 #5A5A5A,
0 -1px 0 #707070;
}
.thumbs img {
margin: 3% 4%;
width: 80%;
height: 80%;
float: left;
}
<section id="slider2">
<div id="youtube">
</div>
<div id="no-template-pager" class="cycle-pager external">
<div class="Scroller-Container">
<!-- using thumbnail image files would be even better! -->
<div class="thumbs">
<img src="http://img.youtube.com/vi/Je7VuV9yHIw/mqdefault.jpg">
</div>
<div class="thumbs">
<img src="http://img.youtube.com/vi/uxps_fYUeJk/mqdefault.jpg">
</div>
<div class="thumbs">
<img src="http://img.youtube.com/vi/Zvr3cwbbqHU/mqdefault.jpg">
</div>
<div class="thumbs">
<img src="http://img.youtube.com/vi/Ka9xtXPD3BA/mqdefault.jpg">
</div>
<div class="thumbs">
<img src="http://img.youtube.com/vi/U8HVQXkeU8U/mqdefault.jpg">
</div>
<div class="thumbs">
<img src="http://img.youtube.com/vi/e7_UUfokexM/mqdefault.jpg">
</div>
</div>
</div>
<div id="Scrollbar-Container">
<div class="Scrollbar-Track">
<div class="Scrollbar-Handle"></div>
</div>
</div>
</section>
<script>
var scroller = null;
var scrollbar = null;
window.onload = function () {
scroller = new jsScroller(document.getElementById("no-template-pager"), 400, 200);
scrollbar = new jsScrollbar (document.getElementById("Scrollbar-Container"), scroller, true);
}
</script>
Link to CodePen 1. and to Javascript 2.:
[1]: http://codepen.io/psairidas/pen/RaVwzw
[2]: http://www.n-son.com/scripts/jsScrolling/jsScrollbar.html

You should probably set a max-height or max-width in pixels, so that it will resize but once it hits that max-height or max-width it won't get any smaller. Then if you want it to scroll, you can set overflow: scroll or overflow: auto (auto is generally recommended).

Related

How to make the slider width change when Resize. JavaScript?

When I change the width of the page it does not stretch in width. Sorry for my English. #How to make the slider width change when Resize.# For some reason, it remembers the first width.
Resize width and transform Please help me. I want to change the width of the screen and have the slider adjust to the width. This code is in pure Javascript. Who can help. I've been racking my head for 3 days, I'm just a beginner.
(function() {
let curTranslateX = 0;
let curPageNum = 0;
let dots = null;
let slideWidth = 0;
let duration = 300;
let pointStart, pointMove, pointEnd;
let slidePositions = [];
let isAutoLoop = false;
let hasArrow = true;
let scrollbar = {
el: '.slide-navbar',
isHide: true,
canClick: true
};
let slideContainer = document.querySelector('.container_slider');
let slideWrapper = slideContainer.querySelector('.slide_wrapper');
let slideItems = [...slideWrapper.querySelectorAll('.slide-item')];
const utils = {
hasClass: function(elem, className) {
return(new RegExp('(\\s|^)' + className + '(\\s|$)')).test(elem.className);
},
addClass: function(elem, className) {
if(!arguments.length) {
return;
}
if(typeof className === 'undefined' || this.hasClass(elem, className)) {
return;
}
let newClasses = elem.className.split(' ');
newClasses.push(className);
elem.className = newClasses.join(' ');
},
removeClass: function(elem, className) {
if(!arguments.length) {
return;
}
if(typeof className === 'undefined' || !this.hasClass(elem, className)) {
return;
}
let classes = elem.className.split(' ');
classes = classes.filter(cls => cls !== className);
elem.className = classes.join(' ');
},
isMobile: function() {
return(/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i).test(navigator.userAgent);
}
}
var slide = {
init: (function() {
document.addEventListener('DOMContentLoaded', function() {
dots = [...document.querySelectorAll('.slide-navbar span')];
dots.forEach(dot => {
utils.addClass(dot, 'dot');
});
if(utils.isMobile()) {
pointStart = 'touchstart';
pointMove = 'touchmove';
pointEnd = 'touchend';
} else {
pointStart = 'pointerdown';
pointMove = 'pointermove';
pointEnd = 'pointerup';
}
slide.bindTouchEvent();
slide.setCurrentPage();
}.bind(slide), false);
})(),
setTranslate: function(duration, offsetX, ...yz) {
this.style = `transition-duration: ${duration}ms; transform: translate3d(${offsetX}px, 0px, 0px);`;
curTranslateX = offsetX;
},
setCurrentPage: function(num) {
if(curPageNum !== -1) {
utils.removeClass(dots[curPageNum], 'dot-active');
utils.removeClass(slideItems[curPageNum], 'slide-active');
}
num = (typeof num === 'undefined') ? 0 : num;
curPageNum = num;
utils.addClass(dots[curPageNum], 'dot-active');
utils.addClass(slideItems[curPageNum], 'slide-active');
},
gotoPage: function(num) {
if(num < 0 || num > dots.length - 1) {
return;
}
slide.setTranslate.call(slideWrapper, duration, slidePositions[num]);
setTimeout(() => {
slide.setCurrentPage(num);
}, duration / 2);
},
bindTouchEvent: function() {
slideWidth = slideItems[0].scrollWidth;
slideContainer.style.width = `${slideWidth}px`;
let negMaxWidth = -slideWidth * (slideItems.length - 1);
for(let i = 0, wtd = 0; i < slideItems.length; i++, wtd -= slideWidth) {
slidePositions.push(wtd);
}
let startX,
startY,
initialPos = 0,
moveDist = 0,
direction = 0,
isMove = false,
startT = 0,
isPointOut = true;
slideContainer.addEventListener(pointStart, function(e) {
e.preventDefault();
if(!isPointOut && e.touches.length !== 1) {
return;
}
let startPoint = e.touches[0];
startX = startPoint.pageX;
startY = startPoint.pageY;
initialPos = curTranslateX;
startT = +new Date();
isMove = false;
isPointOut = false;
}.bind(this), false);
slideContainer.addEventListener(pointMove, function(e) {
if(isPointOut) {
return
}
let movePoint = e.touches[0];
let deltaX = movePoint.pageX - startX;
let deltaY = movePoint.pageY - startY;
let offsetX = initialPos + deltaX;
if(offsetX > 0 || offsetX < negMaxWidth) {
offsetX -= (deltaX / 2);
}
this.setTranslate.call(slideWrapper, 0, offsetX);
isMove = true;
deltaX = offsetX - initialPos;
moveDist = deltaX;
direction = deltaX > 0 ? 0 : 1;
}.bind(this), false);
slideContainer.addEventListener(pointEnd, function(e) {
e.preventDefault();
let deltaT = +new Date() - startT;
if(!isMove) {
if(utils.hasClass(e.target, 'slide-button-prev')) {
if(curPageNum === 0) {
return;
}
slide.gotoPage.call(e.target, curPageNum - 1);
} else if(utils.hasClass(e.target, 'slide-button-next')) {
if(curPageNum === dots.length - 1) {
return;
}
slide.gotoPage.call(e.target, curPageNum + 1);
}
return;
}
if(isPointOut) {
return;
}
isPointOut = true;
if(deltaT < 300 || Math.abs(moveDist) > slideWidth / 2) {
offsetX = direction === 0 ? curTranslateX + slideWidth - moveDist : curTranslateX - slideWidth - moveDist;
offsetX = offsetX > 0 ? 0 : offsetX;
offsetX = offsetX < negMaxWidth ? negMaxWidth : offsetX;
} else {
offsetX = curTranslateX - moveDist;
}
slide.setTranslate.call(slideWrapper, duration, offsetX);
let newPageNum = Math.round(Math.abs(offsetX) / slideWidth);
setTimeout(() => {
this.setCurrentPage(newPageNum);
}, duration / 2);
}.bind(this), false);
},
};
})();
.container_box {
max-width: 1400px;
margin: 0 auto;
}
.container_slider {
position: relative;
overflow: hidden;
}
.slide_wrapper {
position: relative;
z-index: 1;
display: flex;
transition-property: transform;
}
.container_slider .slide-item {
z-index: 1;
display: flex;
flex-shrink: 0;
width: 100%;
height: 300px;
user-select: none;
background-size: cover;
background-position: 50%;
background-repeat: no-repeat;
}
.slide-navbar {
position: absolute;
right: 0;
left: 0;
bottom: 0;
text-align: center;
font-size: 0;
z-index: 2;
}
.dot {
display: inline-block;
margin: 0 4px;
width: 8px;
height: 8px;
border-radius: 50%;
background-color: rgba(255, 255, 255, 0.5);
}
.dot-active {
width: 20px;
border-radius: 6px;
background-color: rgba(233, 233, 233, .9);
}
.slide-button-prev,
.slide-button-next {
display: inline-block;
position: absolute;
top: 50%;
width: 40px;
height: 60px;
z-index: 2;
color: rgba(233, 233, 233, .9);
text-align: center;
font-weight: 500;
}
.slide-button-prev {
left: 0;
transform: translateY(-50%);
}
.slide-button-next {
right: 0;
transform: translateY(-50%);
}
<div class="container_box">
<div class="container_slider">
<div class="slide_wrapper">
<div class="slide-item slide-active" style="background-color:green;"></div>
<div class="slide-item" style="background-color:blue;"></div>
<div class="slide-item" style="background-color:black;"></div>
</div>
<div class="control_slider slide-button-prev"><</div>
<div class="control_slider slide-button-next">></div>
<div class="slide-navbar">
<span class="dot dot-active">1</span>
<span class="dot">2</span>
<span class="dot">3</span>
</div>
</div>
</div>
First: I replaced the < and > by > and <:
<div class="control_slider slide-button-prev"><</div>
<div class="control_slider slide-button-next">></div>
To your question:
I found out that in bindTouchEvent: function() {}
exists the line
slideContainer.style.width = ${slideWidth}px;
This line is in charge to set a fix width. If you comment out this line all single slide-items reacts on resize.

Constraints problem with HTML element drag

I made script for dragging element around my react application in the way that limits are parent container. I achieved what I want but not in the way I want. I want when I reach limits to block that axis from trying to go further to avoid this annoying effect of script calculating and returning div in position.
const drag = (id) => {
const element = document.getElementById(id);
const parent = element.parentNode;
let newState = { x: 0, y: 0 };
let oldState = { x: 0, y: 0 };
const dragElement = (e) => {
e = e || window.event;
e.preventDefault();
oldState.x = e.clientX;
oldState.y = e.clientY;
document.onmouseup = stopDrag;
document.onmousemove = startDrag;
};
const startDrag = (e) => {
e = e || window.event;
e.preventDefault();
newState.x = oldState.x - e.clientX;
newState.y = oldState.y - e.clientY;
oldState.x = e.clientX;
oldState.y = e.clientY;
const handleX = () => {
let x = 0;
if (element.offsetLeft < 0) {
x = 0;
} else if (element.offsetLeft + element.offsetWidth > parent.offsetWidth) {
x = parent.offsetWidth - element.offsetWidth;
} else {
x = element.offsetLeft - newState.x;
}
return `${x}px`;
};
const handleY = () => {
let y = 0;
if (element.offsetTop < 0) {
y = 0;
} else if (element.offsetTop + element.offsetHeight > parent.offsetHeight) {
y = parent.offsetHeight - element.offsetHeight;
} else {
y = element.offsetTop - newState.y;
}
return `${y}px`;
};
element.style.top = handleY();
element.style.left = handleX();
};
const stopDrag = () => {
document.onmouseup = null;
document.onmousemove = null;
};
if (document.getElementById(element.id + "Header")) {
document.getElementById(element.id + "Header").onmousedown = dragElement;
} else {
element.onmousedown = dragElement;
}
};
drag("test");
.parent {
display: flex;
justify-content: center;
align-items: center;
position: absolute;
inset: 16px;
background: red;
}
.draggable {
position: absolute;
width: 50px;
height: 50px;
background: green;
}
<div class="parent">
<div class="draggable" id="test"></div>
</div>

How to add a game menu

I am trying to add a generic game menu with "start" to initiate the game. How do I go about doing this? Here is the code:
var LEFT_KEY = 37;
var UP_KEY = 38;
var RIGHT_KEY = 39;
var DOWN_KEY = 40;
var SPACE_KEY = 32;
var HERO_MOVEMENT = 3;
var lastLoopRun = 0;
var score = 0;
var iterations = 0;
var controller = new Object();
var enemies = new Array();
function createSprite(element, x, y, w, h) {
var result = new Object();
result.element = element;
result.x = x;
result.y = y;
result.w = w;
result.h = h;
return result;
}
function toggleKey(keyCode, isPressed) {
if (keyCode == LEFT_KEY) {
controller.left = isPressed;
}
if (keyCode == RIGHT_KEY) {
controller.right = isPressed;
}
if (keyCode == UP_KEY) {
controller.up = isPressed;
}
if (keyCode == DOWN_KEY) {
controller.down = isPressed;
}
if (keyCode == SPACE_KEY) {
controller.space = isPressed;
}
}
function intersects(a, b) {
return a.x < b.x + b.w && a.x + a.w > b.x && a.y < b.y + b.h && a.y + a.h > b.y;
}
function ensureBounds(sprite, ignoreY) {
if (sprite.x < 20) {
sprite.x = 20;
}
if (!ignoreY && sprite.y < 20) {
sprite.y = 20;
}
if (sprite.x + sprite.w > 480) {
sprite.x = 480 - sprite.w;
}
if (!ignoreY && sprite.y + sprite.h > 480) {
sprite.y = 480 - sprite.h;
}
}
function setPosition(sprite) {
var e = document.getElementById(sprite.element);
e.style.left = sprite.x + 'px';
e.style.top = sprite.y + 'px';
}
function handleControls() {
if (controller.up) {
hero.y -= HERO_MOVEMENT;
}
if (controller.down) {
hero.y += HERO_MOVEMENT;
}
if (controller.left) {
hero.x -= HERO_MOVEMENT;
}
if (controller.right) {
hero.x += HERO_MOVEMENT;
}
if (controller.space) {
var laser = getFireableLaser();
if (laser) {
laser.x = hero.x + 9;
laser.y = hero.y - laser.h;
}
}
ensureBounds(hero);
}
function getFireableLaser() {
var result = null;
for (var i = 0; i < lasers.length; i++) {
if (lasers[i].y <= -120) {
result = lasers[i];
}
}
return result;
}
function getIntersectingLaser(enemy) {
var result = null;
for (var i = 0; i < lasers.length; i++) {
if (intersects(lasers[i], enemy)) {
result = lasers[i];
break;
}
}
return result;
}
function checkCollisions() {
for (var i = 0; i < enemies.length; i++) {
var laser = getIntersectingLaser(enemies[i]);
if (laser) {
var element = document.getElementById(enemies[i].element);
element.style.visibility = 'hidden';
element.parentNode.removeChild(element);
enemies.splice(i, 1);
i--;
laser.y = -laser.h;
score += 100;
} else if (intersects(hero, enemies[i])) {
gameOver();
} else if (enemies[i].y + enemies[i].h >= 500) {
var element = document.getElementById(enemies[i].element);
element.style.visibility = 'hidden';
element.parentNode.removeChild(element);
enemies.splice(i, 1);
i--;
}
}
}
function gameOver() {
var element = document.getElementById(hero.element);
element.style.visibility = 'hidden';
element = document.getElementById('gameover');
element.style.visibility = 'visible';
}
function showSprites() {
setPosition(hero);
for (var i = 0; i < lasers.length; i++) {
setPosition(lasers[i]);
}
for (var i = 0; i < enemies.length; i++) {
setPosition(enemies[i]);
}
var scoreElement = document.getElementById('score');
scoreElement.innerHTML = 'SCORE: ' + score;
}
function updatePositions() {
for (var i = 0; i < enemies.length; i++) {
enemies[i].y += 4;
enemies[i].x += getRandom(7) - 3;
ensureBounds(enemies[i], true);
}
for (var i = 0; i < lasers.length; i++) {
lasers[i].y -= 12;
}
}
function addEnemy() {
var interval = 50;
if (iterations > 1500) {
interval = 5;
} else if (iterations > 1000) {
interval = 20;
} else if (iterations > 500) {
interval = 35;
}
if (getRandom(interval) == 0) {
var elementName = 'enemy' + getRandom(10000000);
var enemy = createSprite(elementName, getRandom(450), -40, 35, 35);
var element = document.createElement('div');
element.id = enemy.element;
element.className = 'enemy';
document.children[0].appendChild(element);
enemies[enemies.length] = enemy;
}
}
function getRandom(maxSize) {
return parseInt(Math.random() * maxSize);
}
function loop() {
if (new Date().getTime() - lastLoopRun > 40) {
updatePositions();
handleControls();
checkCollisions();
addEnemy();
showSprites();
lastLoopRun = new Date().getTime();
iterations++;
}
setTimeout('loop();', 2);
}
document.onkeydown = function(evt) {
toggleKey(evt.keyCode, true);
};
document.onkeyup = function(evt) {
toggleKey(evt.keyCode, false);
};
var hero = createSprite('hero', 250, 460, 20, 20);
var lasers = new Array();
for (var i = 0; i < 3; i++) {
lasers[i] = createSprite('laser' + i, 0, -120, 2, 50);
}
loop();
#hero {
/* background: #ff0000; */
background-image: url("man-of-space.png");
width: 40px;
height: 40px;
position: absolute;
}
#background {
background-image: url("space.png");
/* background: #000000; */
width: 500px;
height: 500px;
position: absolute;
left: 0px;
top: 0px;
}
.laser {
background: #00ff00;
width: 2px;
height: 50px;
position: absolute;
}
.enemy {
background-image: url("spaceship.png");
background-size: 40px 40px;
width: 40px;
height: 40px;
position: absolute;
}
#score {
color: #ffffff;
font-size: 18pt;
position: absolute;
left: 20px;
top: 20px;
}
#gameover {
color: #ff0000;
font-size: 20px;
position: absolute;
left: 160px;
top: 200px;
visibility: hidden;
}
<div id="background"></div>
<div id="hero"></div>
<div class="laser" id="laser0"></div>
<div class="laser" id="laser1"></div>
<div class="laser" id="laser2"></div>
<div id="score"></div>
<div id="gameover">GAME OVER</div>
You could wrap your game UI in a <div id="game" style="display: none;"> element so it will be hidden when the page is loaded. Then wrap your start menu in a <div id="startMenu"> element with a <button id="startButton">Start</button> that will be used to hide the start menu and show the game UI.
In your JS code you could wrap your game in a function so it can be started when you call it.
HTML:
<div id="startMenu">
<button id="startButton">Start</button>
</div>
<div id="game" style="display: none;">
<div id="background"></div>
<div id="hero"></div>
<div class="laser" id="laser0"></div>
<div class="laser" id="laser1"></div>
<div class="laser" id="laser2"></div>
<div id="score"></div>
<div id="gameover">GAME OVER</div>
</div>
JS:
function startGame() {
var LEFT_KEY = 37;
var UP_KEY = 38;
var RIGHT_KEY = 39;
var DOWN_KEY = 40;
var SPACE_KEY = 32;
var HERO_MOVEMENT = 3;
[...Your game code...]
loop();
}
document.getElementById('startButton').onclick = function() {
document.getElementById('startMenu').style.display = "none";
document.getElementById('game').style.display = "";
startGame();
};
Now you have a start menu (<div id="startMenu">) that you can customize however you like, and a game UI (<div id="game">) that will be shown only after the start button is pressed.
Add more HTML would be my suggestion. Maybe make a div that has all the start screen elements you need in it. When the start function happens, set that div's innerHTML to "".
Example:
document.getElementById('yourDivIdHere').innerHTML = '';

DIY - Pinch to Zoom for mobile with Javascript

in my project I came across with a need for pinch to zoom support, but not the basic one.
and there are two main "must have" while doing so.
1) only the DIV container will zoom, and not the rest of the page (eg: top bar)
2) I need to keep the window basic scroll
I've added a simple code showing how I've done so and it left me with 2 questions
I) the page is jumpy while I'm pinching for zoom.
II) have I calculate this correctly? or should I have it another way?
* you can find a working example in the link below
https://www.klika.co.il/canvas/pinch.html
// ----------- TOUCH --------------
//handles on move events for tracking touches
var touches = {
points: null,
start: function (e) {
if (gesture.is.on) {
e = e || window.event;
if (e.preventDefault)
e.preventDefault();
e.returnValue = false;
}
//reset touches
touches.points = null;
msg('touch start');
},
move: function (e) {
// msg('touch move');
if (e.touches.length > 1) {
// msg('touch move ' + e.touches.length + ' fingers');
//set touches only if two fingers are on
touches.points = { x: {}, y: {} }
for (var i = 0; i < e.touches.length; i++) {
touches.points.x[i] = e.touches[i].clientX;
touches.points.y[i] = e.touches[i].clientY;
}
}
},
end: function (e) {
msg('touch end');
}
};
// ----------- GESTURE --------------
var gesture = {
is: {
on: false,
init: false
},
data: {
content: null,
elem: null,
width: 0,
state: {},
},
start: function (e) {
gesture.is.on = true;
msg('gesture start');
gesture.data.content = $('.containter')[0];
gesture.data.elem = $('.containter .wrap')[0];
gesture.data.width = toFloat(gesture.data.elem.style.width, 100);
gesture.is.init = true;
},
move: function (e) {
if (!touches.points) { return; }
//set the body element for Y axis
const el = document.scrollingElement || document.documentElement;
//set mid points
var X1 = touches.points.x[0];
var Y1 = touches.points.y[0];
var X2 = touches.points.x[1];
var Y2 = touches.points.y[1];
var mid = getMidPoint(X1, Y1, X2, Y2);
//set start position on init
if (gesture.is.init) {
gesture.data.state = {
w: gesture.data.width / 100,
sl: ((gesture.data.content.scrollLeft + mid.x) / gesture.data.content.scrollWidth) * 100,
st: ((el.scrollTop + mid.y) / el.scrollHeight) * 100,
mid: mid
}
gesture.is.init = false;
}
//calc/set width of the wrapping DIV
var inc = e.scale * gesture.data.state.w;
var WPX = gesture.data.content.scrollWidth * inc;
var HPX = document.body.scrollHeight * inc;
var w = (WPX / gesture.data.content.scrollWidth) * 100;
gesture.data.elem.style.width = w + '%';
//calc/set scrollLeft of the wrapping DIV (X axis)
var sln = Math.round(((gesture.data.state.sl / 100) * gesture.data.content.scrollWidth) - (getWindowXY().w / 2));
if (sln < 0) { sln = 0; }
sln += gesture.data.state.mid.x - mid.x;
gesture.data.content.scrollLeft = sln;
//calc/set scrollLeft of the body element (Y axis)
var slt = Math.round(((gesture.data.state.st / 100) * el.scrollHeight) - (getWindowXY().h / 2));
if (slt < 0) { slt = 0; }
slt += gesture.data.state.mid.y - mid.y;
el.scrollTop = slt;
},
end: function (e) {
var w = toFloat(gesture.data.elem.style.width);
if (isNaN(w) || w < 100) {
gesture.data.elem.style.width = '100%';
}
gesture.is.on = false;
}
}
// -------- BIND ------
window.addEventListener('touchstart', touches.start, false);
window.addEventListener('touchmove', touches.move, true);
window.addEventListener('touchend', touches.end, true);
window.addEventListener('gesturestart', gesture.start, false);
window.addEventListener('gesturechange', gesture.move, false);
window.addEventListener('gestureend', gesture.end, false);
//------ GENERAL --------
String.prototype.format = function () {
var s = this,
i = arguments.length;
if (!s) {
return "";
}
while (i--) {
s = s.replace(new RegExp('\\{' + i + '\\}', 'gm'), arguments[i]);
}
return s;
}
var toFloat = function (val) {
return parseFloat(val.replace("%", ""));
}
var getWindowXY = function () {
var myWidth = 0, myHeight = 0;
if (typeof (window.innerWidth) == 'number') {
//Non-IE
myWidth = window.innerWidth;
myHeight = window.innerHeight;
} else if (document.documentElement && (document.documentElement.clientWidth || document.documentElement.clientHeight)) {
//IE 6+ in 'standards compliant mode'
myWidth = document.documentElement.clientWidth;
myHeight = document.documentElement.clientHeight;
} else if (document.body && (document.body.clientWidth || document.body.clientHeight)) {
//IE 4 compatible
myWidth = document.body.clientWidth;
myHeight = document.body.clientHeight;
}
return {
h: myHeight,
w: myWidth
}
}
var msg = function (text) {
$('.info').html(text);
}
var getMidPoint = function (x1, y1, x2, y2) {
return { x: ((x1 + x2) / 2), y: ((y1 + y2) / 2) }
}
window.oncontextmenu = function (event) {
event.preventDefault();
event.stopPropagation();
return false;
};
window.addEventListener('error', function (e) {
if (e.message == "Script error.") { return; }
if (e.message.indexOf('facebook') != -1) { return; }
msg(e.message);
}, false);
body {
margin: 0;
padding: 0;
width:100vw;
}
.top{
position: fixed;
width: 100%;
background-color: #333;
line-height: 40pt;
text-align: center;
color: #f1f1f1;
font-size: 20pt;
left: 0;
top: 0;
}
.top .info{
}
.containter {
width: 100%;
overflow-x: auto;
}
.containter .wrap {
display: flex;
flex-direction: column;
width: 100%;
}
.containter .wrap img {
width: 100%;
margin-top: 30pt;
}
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta name="viewport" content="width=device-width, height=device-height, user-scalable=no" />
<title>Pinch to zoom</title>
<script src="https://www.klika.co.il/plugins/jqTools/js/jquery-1.7.1.min.js" type="text/javascript"></script>
</head>
<body>
<div class="top">
<div class="info">Pinch to zoom</div>
</div>
<div class="containter">
<div class="wrap">
<img src="https://thumb7.shutterstock.com/display_pic_with_logo/91858/594887747/stock-photo-dreams-of-travel-child-flying-on-a-suitcase-against-the-backdrop-of-sunset-594887747.jpg" />
<img src="https://thumb9.shutterstock.com/display_pic_with_logo/1020994/556702975/stock-photo-portrait-of-a-happy-and-proud-pregnant-woman-looking-at-her-belly-in-a-park-at-sunrise-with-a-warm-556702975.jpg" />
<img src="https://thumb7.shutterstock.com/display_pic_with_logo/234100/599187701/stock-photo-funny-little-girl-plays-super-hero-over-blue-sky-background-superhero-concept-599187701.jpg" />
<img src="https://thumb1.shutterstock.com/display_pic_with_logo/1316512/661476343/stock-photo-funny-pineapple-in-sunglasses-near-swimming-pool-661476343.jpg" />
<img src="https://thumb1.shutterstock.com/display_pic_with_logo/2114402/689953639/stock-photo-adult-son-hugging-his-old-father-against-cloudy-sky-with-sunshine-689953639.jpg" />
<img src="https://thumb7.shutterstock.com/display_pic_with_logo/172762/705978841/stock-photo-businessman-looking-to-the-future-for-new-business-opportunity-705978841.jpg" />
</div>
</div>
</body>
</html>

Draw a bendable arrow between two html elements

I am developing a view for some items in my web site. Currently I have the items displayed in the HTML but now I need to draw some lines between the elements that will represent a connection between them, it's like a Gantt Chart but it doesn't include any time functionality, I only need to connect the items with the ones associated to them. I'm using JSTL to bring some data from a controller and I managed to draw the elements like the following image: http://i271.photobucket.com/albums/jj131/djrickel/before.png
And the way I need to display is in the following image:
http://i271.photobucket.com/albums/jj131/djrickel/after.png
This is how I'm creating my table containing the elements that I want to display:
<div class="container">
<table>
<tbody>
<c:forEach items="${nodeGraphs}" var="nodeGraph">
<tr>
<c:forEach var="i" begin="0" end="5">
<td>
<c:if test="${nodeGraph.columnID == i}">
<label class="label label-default">${nodeGraph.nodeObject.item.type}${nodeGraph.nodeObject.item.contextId}</label>
</c:if>
</td>
</c:forEach>
</tr>
</c:forEach>
</tbody>
</table>
</div>
Does anyone know a way to create connecting lines between the elements using JQuery, JSon, Javascript or any HTML process? I can change from the table I'm using to div or span without any issue. I'm just looking the best way to display the information. Thanks in advance.
Probably the best way to do that is use HTML5 canvas, but if You want use div's try use this code:
(On JSFiddle: http://fiddle.jshell.net/22rar61n/9/)
var Line = (function() {
var diff = function(a, b) {
var d = Math.abs(a - b);
if (d === 0) {
d = 1;
}
return d;
}
var countWidth = function(line) {
return diff(line.endX, line.startX);
};
var countHeight = function(line) {
return diff(line.endY, line.startY);
};
var Line = function(options) {
this.startX = options.startX;
this.startY = options.startY;
this.endX = options.endX;
this.endY = options.endY;
}
Line.prototype.drowIn = function($container) {
var self = this;
var line = jQuery("<div></div>", {
class: "line " + self.LineType(),
css: {
"color": "red",
"top": self.startY,
"left": self.startX,
"width": countWidth(self),
"height": countHeight(self),
"background-color": "#000"
}
});
$container.append(line);
};
Line.prototype.LineType = function() {
if (this.startX != this.endX) {
return "horizontal";
}
return "vertical";
}
return Line;
})();
var Arrow = (function() {
var Arrow = function(start, end) {
this.start = start;
this.end = end;
}
Arrow.prototype.drowIn = function($container) {
var ArrowContainer = jQuery("<div></div>", {
class: "arrowContainer"
});
var line1 = new Line({
startX: this.start.x,
startY: this.start.y,
endX: this.start.x,
endY: this.end.y
});
line1.drowIn(ArrowContainer);
var line2 = new Line({
startX: this.start.x,
startY: this.end.y,
endX: this.end.x,
endY: this.end.y
});
line2.drowIn(ArrowContainer);
$container.append(ArrowContainer);
}
return Arrow;
})();
var Element = (function() {
var Element = function(options) {
var op = jQuery.extend({}, options);
this.x = op.x || -1;
this.y = op.y || -1;
this.content = op.content || "";
this.container = op.$container || "";
this.node = null;
this.subElements = [];
};
Element.prototype.addSubElement = function(element) {
element.container = this.container;
element.content = this.content + "." + (this.subElements.length + 1);
this.subElements.push(element);
};
Element.prototype.drow = function() {
var self = this;
this.node = jQuery("<div></div>", {
class: "element",
text: this.content,
css: {
top: self.y,
left: self.x
}
});
this.container.append(this.node);
var nexLvl = 0;
var lastHeight = nexLvl;
var lastLvl = 0;
var oldIndex = -1;
var outerHeightAndTop = jQuery(self.node).outerHeight() + jQuery(self.node).offset().top;
jQuery.each(this.subElements, function(index, element) {
var height = outerHeightAndTop * (index + 1 + lastLvl);
if (lastHeight != 0) {
height = lastHeight + outerHeightAndTop;
}
if (nexLvl != 0) {
oldIndex = index;
height = height + ((jQuery(self.node).outerHeight()) * nexLvl);
lastLvl = nexLvl;
}
lastHeight = height;
nexLvl = element.getMaxLevel();
element.x = jQuery(self.node).outerWidth() + jQuery(self.node).offset().left;
element.y = height;
element.drow();
self.connectWith(element);
});
};
Element.prototype.connectWith = function(element) {
var startY = jQuery(this.node).outerHeight() + this.y;
var startX = (jQuery(this.node).outerWidth() / 2) + this.x;
var endY = (jQuery(element.node).outerHeight() / 2) + element.y;
var arrow = new Arrow({
x: startX,
y: startY
}, {
x: element.x,
y: endY
});
arrow.drowIn(this.container);
};
function getLevelOnPosition(index) {
return this.subElements[index].getMaxLevel();
}
Element.prototype.getMaxLevel = function(initLvl) {
var lvl = initLvl || 0;
var maxLvl = lvl;
if (this.subElements.length > 0) {
maxLvl = lvl++;
}
jQuery.each(this.subElements, function(index, element) {
lvl = element.getMaxLevel(lvl);
if (lvl > maxLvl) {
maxLvl = lvl;
}
});
return maxLvl;
}
return Element;
})();
jQuery(document).ready(function() {
var container = jQuery("#container");
var e = new Element({
x: 10,
y: 10,
content: "a1",
$container: container
});
var sube = new Element();
e.addSubElement(sube);
var sube2 = new Element();
sube.addSubElement(sube2);
sube2.addSubElement(new Element());
var e2 = new Element();
e.addSubElement(e2);
e2.addSubElement(new Element());
e.addSubElement(new Element());
e.drow();
});
#container {
position: relative;
}
#container > .element {
position: absolute;
border: 1px solid black;
background-color: gray;
color: white;
padding: 2px;
z-index: 10;
}
#container > .arrowContainer {
position: absolute;
}
#container > .arrowContainer > .line {
position: absolute;
z-index: 50;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="container"></div>

Categories