Scroll top does not equal as moving blocks up - javascript

I am trying to make some 2d game with javascript, html and css.
This is just a start but it seems like I have some weird problem.
When I move up I move my player block up and scroll top but scroll top is scrolling more then player block moved.
I am getting player block position to move up with 50px and document scrollTop position to move up same 50px by subscription.
$(document).ready(function() {
//map info
var $map = $('#map'),
viewportWidth = +$(window).width(),
viewportHeight = +$(window).height(),
mapWidth = +$map.width(),
mapHeight = +$map.width();
//player info
var $player = $('.player').eq(0);
//Adding some logic
//Half height and width of map and half of viewport to center it
var halfMW = mapWidth / 2,
halfMH = mapHeight / 2,
halfVW = viewportWidth / 2,
halfVH = viewportHeight / 2;
//Now we need to get subsrtiction of half map width and half viewport width
//and same for height
var mapPositionX = halfMW - halfVW,
mapPositionY = halfMH - halfVH;
//Now we need to put map in negative values so the viewport stands in the center
//Css example
/*
$map.css({
'top': '-' + mapPositionY + 'px',
'left': '-' + mapPositionX + 'px'
});
*/
//Scroll example
$(document).scrollLeft(mapPositionX);
$(document).scrollTop(mapPositionY);
//moving player
$(document).keydown( function(key) {
console.log(key.which);
//down - 40
//right - 39
//up - 38
//left - 37
if(key.which === 38) {
var posUP = +$player.css("top").replace("px", "");
$player.css('top', posUP-50+'px');
$(document).scrollTop($(document).scrollTop() - 50);
}
});
});
html, body {
margin: 0;
padding: 0;
}
#map {
width: 10000px;
height: 10000px;
background: #71D014;
position: relative;
overflow: scroll;
}
.blocks {
width: 100px;
height: 100px;
position: absolute;
top: 4950px;
left: 4950px;
background: orange;
}
.player {
width: 50px;
height: 50px;
position: absolute;
top: 5050px;
left: 5050px;
background: #005ED2;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Tanks</title>
<link rel="stylesheet" href="css/main.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</head>
<body>
<div id="map">
<div class="blocks"></div>
<div class="player"></div>
</div>
<script src="js/main.js"></script>
</body>
</html>

I found out what was the problem.
Well up, down, left and right arrows on keyboard are set as defaults for moving scroll x and y and I just needed to add preventDefault(); on start.

Related

Move element by certain amount while scrolling

I want to move the white box to the right by 50% while scrolling until it reaches the red section. The distance to the red section is 1000px in the example.
The code below moves the box to the right as I scroll down, and I'm just using a random number 10 to slow down the movement but I can't get my head around to make it move evenly for every scroll event until the box reaches the red section and move 50% to the right.
var xPos = 0;
function getXPos(target, windowPos) {
var amount = windowPos - target;
xPos = amount / 10;
return xPos;
}
$(window).scroll(function() {
var windowPos = $(window).scrollTop();
var sectionOne = $('section.one').offset().top;
var sectionTwo = $('section.two').offset().top;
var box = $('.box');
if (windowPos > sectionOne && windowPos < sectionTwo) {
box.css({
"transform": 'translateX(' + getXPos(sectionOne, windowPos) + '%)'
});
}
});
body {
margin: 0;
}
.box {
background: white;
position: sticky;
top: 0;
width: 300px;
height: 300px;
}
section.one {
height: 1000px;
background: blue;
}
section.two {
height: 1000px;
background: red;
}
<section class="one">
<div class="box"></div>
</section>
<section class="two"></section>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
There is also another issue with scroll that if I scroll too fast, the box won't move as much.
Here is the fiddle for demonstration.
https://jsfiddle.net/sungsoonz/0Lspo2d9/
So I used the logic of making a progress bar for whole page but for your section with class "one". So when you scroll the section 100% of it's height the "left" css property on the div with class "box" becomes at value of "100%". But as I understood we need to stop moving when we reach section with class "two" with div with class "box". So {left: 100%} will become when we have scrolled whole section with class "box" minus the visible height of div with class "box". Then it is easily calculated to move only for 50% of width of section with class "one" (-width of div with class "box" width / 2 to center it). Hope I described my solution clearly (xd). Hope it helps
The code:
one = document.querySelector(".one")
two = document.querySelector(".two")
box = document.querySelector(".box")
$(window).on('scroll', function (){
if (window.scrollY >= (one.scrollHeight - box.offsetHeight)) {
$('.box').css('left', `calc(50% - ${(box.offsetWidth / 2)}px`);
return
}
$scrolledFrom = $(document).scrollTop();
$documentHeight = $(document).height() - ($(".two").height() + box.offsetHeight);
$leftOffset = ($scrolledFrom / $documentHeight) * 100;
$('.box').css('left', `calc(${($leftOffset / 2)}% - ${(box.offsetWidth / 2)}px`);
console.log ()
});
body {
margin: 0;
}
.box {
background: white;
position: sticky;
top: 0;
left: 0;
width: 300px;
height: 300px;
}
section.one {
height: 1000px;
background: blue;
}
section.two {
height: 1000px;
background: red;
}
<section class="one">
<div class="box"></div>
</section>
<section class="two"></section>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

Can't use jQuery to override inline style generated by jQuery?

My code is forking this pen, I also include my code in the stack snippet under this post.
what I want to achieve are:
When the cursor is not inside the body, the eyeball would move randomly ( achieved ).
When the cursor enters the body, the eyeball follows the cursor ( achieved ).
When the cursor leaves the body, the eyeball starts moving randomly again ( not achieved ).
I called the function which is used to move the eyeball randomly in on("mouseleave") event, and it does move to a random position but it will immediately go back to the last cursor position, rather than staying at the new position. Can anyone point me to the right direction to fix the problem?
Thanks!
var
mouseOvering = false,
pupil = $("#pupil"),
eyeball = $("#iris"),
eyeposx = 40,
eyeposy = 20,
r = $(pupil).width()/2,
center = {
x: $(eyeball).width()/2 - r,
y: $(eyeball).height()/2 - r
},
distanceThreshold = $(eyeball).width()/2 - r,
mouseX = 0,
mouseY = 0;
$("body").ready( function(){
if ( !mouseOvering ) {
moveRandomly();
}
});
$("body").on('mouseleave', function(){
mouseOvering = false;
moveRandomly();
console.log("mouseleave");
});
$("body").on('mousemove', function(e){
mouseOvering = true;
console.log("mouseovering");
followCursor(e);
});
function moveRandomly() {
var loop = setInterval(function(){
var xp = Math.floor(Math.random()*80);
var yp = Math.floor(Math.random()*80);
pupil.animate({left:xp, top:yp});
}, 3500);
}
function followCursor(e) {
var d = {
x: e.pageX - r - eyeposx - center.x,
y: e.pageY - r - eyeposy - center.y
};
var distance = Math.sqrt(d.x*d.x + d.y*d.y);
if (distance < distanceThreshold) {
mouseX = e.pageX - eyeposx - r;
mouseY = e.pageY - eyeposy - r;
} else {
mouseX = d.x / distance * distanceThreshold + center.x;
mouseY = d.y / distance * distanceThreshold + center.y;
}
var xp = 0, yp = 0;
var loop = setInterval(function(){
// change 1 to alter damping/momentum - higher is slower
xp += (mouseX - xp) / 1;
yp += (mouseY - yp) / 1;
pupil.css({left:xp, top:yp});
}, 2);
}
body {
background-color: #D1D3CF;
}
#container {
display: inline;
height: 400px;
width: 400px;
}
#eyeball {
background: radial-gradient(circle at 100px 100px, #EEEEEE, #000);
height: 300px;
width: 300px;
border-radius: 100%;
position: relative;
}
#iris {
top: 10%;
left: 10%;
background: radial-gradient(circle at 100px 100px, #4DC9EF, #000);
height: 80%;
width: 80%;
border-radius: 100%;
position: absolute;
}
#pupil {
top: 10%;
left: 10%;
background: radial-gradient(circle at 100px 100px, #000000, #000);
height: 55%;
width: 55%;
border-radius: 100%;
position: absolute;
}
#keyframes move {
50% {
transform: translate(-50px, 50px);
}
}
#keyframes move2 {
50% {
transform: translate(-20px, 20px);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="container">
<div id="eyeball">
<div id="iris">
<div id="pupil"></div>
</div>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="script.js"></script>
</body>
</html>
With Javascript you can only track where the cursor is on the webpage. If you shift your cursor outside the body, it's not possible for your code to know where the cursor is.
This is the reason the eye tracking your cursor stops moving when you move your cursor outside the window.
The problem is that once the followcursor function was started it kept on moving back to the last known mouse position, even after the mouse had left the body. I just put a check on your mouseOvering variable inside your followcursor function:
var
mouseOvering = false,
pupil = $("#pupil"),
eyeball = $("#iris"),
eyeposx = 40,
eyeposy = 20,
r = $(pupil).width()/2,
center = {
x: $(eyeball).width()/2 - r,
y: $(eyeball).height()/2 - r
},
distanceThreshold = $(eyeball).width()/2 - r,
mouseX = 0,
mouseY = 0;
$("body").ready( function(){
if ( !mouseOvering ) {
moveRandomly();
}
});
$("body").on('mouseleave', function(){
mouseOvering = false;
console.log("mouseleave");
});
$("body").on('mousemove', function(e){
mouseOvering = true;
console.log("mouseovering");
followCursor(e);
});
function moveRandomly() {
var loop = setInterval(function(){
var xp = Math.floor(Math.random()*80);
var yp = Math.floor(Math.random()*80);
if (!mouseOvering) {
pupil.animate({left:xp, top:yp});
}
}, 3500);
}
function followCursor(e) {
var d = {
x: e.pageX - r - eyeposx - center.x,
y: e.pageY - r - eyeposy - center.y
};
var distance = Math.sqrt(d.x*d.x + d.y*d.y);
if (distance < distanceThreshold) {
mouseX = e.pageX - eyeposx - r;
mouseY = e.pageY - eyeposy - r;
} else {
mouseX = d.x / distance * distanceThreshold + center.x;
mouseY = d.y / distance * distanceThreshold + center.y;
}
var xp = 0, yp = 0;
var loop = setInterval(function(){
// change 1 to alter damping/momentum - higher is slower
xp += (mouseX - xp) / 1;
yp += (mouseY - yp) / 1;
if (mouseOvering) {
pupil.css({left:xp, top:yp});
}
}, 2);
}
body {
background-color: #D1D3CF;
}
#container {
display: inline;
height: 400px;
width: 400px;
}
#eyeball {
background: radial-gradient(circle at 100px 100px, #EEEEEE, #000);
height: 300px;
width: 300px;
border-radius: 100%;
position: relative;
}
#iris {
top: 10%;
left: 10%;
background: radial-gradient(circle at 100px 100px, #4DC9EF, #000);
height: 80%;
width: 80%;
border-radius: 100%;
position: absolute;
}
#pupil {
top: 10%;
left: 10%;
background: radial-gradient(circle at 100px 100px, #000000, #000);
height: 55%;
width: 55%;
border-radius: 100%;
position: absolute;
}
#keyframes move {
50% {
transform: translate(-50px, 50px);
}
}
#keyframes move2 {
50% {
transform: translate(-20px, 20px);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="container">
<div id="eyeball">
<div id="iris">
<div id="pupil"></div>
</div>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="script.js"></script>
</body>
</html>

How to change element width on scroll?

I'm pretty new at coding, and right now I'm working on a small school assignment where the idea is to create a single serving site.
I want to make a face from the side with a nose that grows - from left to right - (exactly like Pinocchio) when scrolling the page.
Maybe the code I have written will help to explain what I want to do more accurately...
My question is: what should I do to have my nose element fixed centered to the left, and growing more and more to the right when scrolling? When I set the position to fixed my nose element disappears.
This is my source of inspiration/code -> http://jsfiddle.net/95EtZ/11/
Here is my code:
$(function() {
var Node = $('#container'),
BaseWidth = Node.width();
$(window).resize(function() {
$('#container').css({
top: ($(window).height() - $('#container').outerHeight()) / 2
});
});
$(window).resize();
var $scrollingDiv = Node;
$(window).scroll(function() {
var winScrollTop = $(window).scrollTop() + 0,
zeroSizeHeight = $(document).height() - $(window).height(),
newSize = BaseWidth * (1 - (winScrollTop / zeroSizeHeight) * (2 / 3));
Node.css({
width: newSize,
"marginTop": winScrollTop + "px"
});
});
});
#added {
background: white;
height: 1500px;
overflow: hidden;
position: relative;
}
#container {
width: 600px;
height: 100px;
background-color: #567;
margin: 0 auto;
position: relative;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="main.css">
</head>
<body>
<div id="added">
<div id="container"></div>
</div>
</body>
</html>
Just make the div floating left and it should work.
#container {
width: 600px;
height: 2000px;
background-color: #567;
margin: 0 auto;
position:relative;
float:left;
}

Support multiple inputs JQuery

I'm learning how to develop a game in html/css3/javascript/jquery and i have to support multiple keyboard inputs.
By following a book, i have written this code:
var pingpong = {};
pingpong.pressedKeys = [];
$(function() {
// set interval to call gameloop every 30 milliseconds
pingpong.timer = setInterval(gameloop, 30);
// mark down what key is down and up into an array called
// "pressedKeys"
$(document).keydown(function(e) {
pingpong.pressedKeys[e.which] = true;
});
$(document).keyup(function(e) {
pingpong.pressedKeys[e.which] = false;
});
});
function gameloop() {
movePaddles();
}
function movePaddles() {
// use our custom timer to continuously check if a key is
// pressed.
if (pingpong.pressedKeys[KEY.UP]) {// arrow-up
// move the paddle B up 5 pixels
var top = parseInt($("#paddleB").css("top"));
$("#paddleB").css("top", top - 5);
}
if (pingpong.pressedKeys[KEY.DOWN]) {// arrow-down
// move the paddle B down 5 pixels
var top = parseInt($("#paddleB").css("top"));
$("#paddleB").css("top", top + 5);
}
if (pingpong.pressedKeys[KEY.W]) {// w
// move the paddle A up 5 pixels
var top = parseInt($("#paddleA").css("top"));
$("#paddleA").css("top", top - 5);
}
if (pingpong.pressedKeys[KEY.S]) {// s
// move the paddle A down 5 pixels
var top = parseInt($("#paddleA").css("top"));
$("#paddleA").css("top", top + 5);
}
}
But it does not work. I mean, the paddles don't move! Any idea?
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>MyGame</title>
<style>
#playground {
background: #e0ffe0;
width: 400px;
height: 200px;
position: relative;
overflow: hidden;
}
#ball {
background: #fbb;
position: absolute;
width: 20px;
height: 20px;
left: 150px;
top: 100px;
border-radius: 10px;
}
.paddle {
background: #bbf;
left: 50px;
top: 70px;
position: absolute;
width: 30px;
height: 70px;
}
#paddleB {
left: 320px;
}
</style>
</head>
<body>
<header>
<h1>Test</h1>
</header>
<div id="game">
<div id="playground">
<div id="paddleA" class="paddle"></div>
<div id="paddleB" class="paddle"></div>
<div id="ball"></div>
</div>
</div>
<footer>
This is an example of creating a Game.
</footer>
<script src="js/jquery-1.11.3.js"></script>
<script src="js/html5games.pingpong.js"></script>
</body>
</html>
MyGoal
Move with S (down) and W (up) the left paddle, and with arrow up (UP) and arrow down (down) the right paddle. If i press S AND arrow down, the left paddle must move up, and the right paddle must move down, AT THE SAME TIME. (The events must not stop each other).
What i get
The keyboard input does not work. The paddles don't move.
UPDATE
I forgot to add this to the .js code:
var KEY = {
UP : 38,
DOWN : 40,
W : 87,
S : 83
};

Moving css scaled div using javascript

I have posted my problem at http://jsfiddle.net/ugnf4/ as it would be make it easier.
Below is my html / javascript code
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="mainContainer">
<div id="pageContainer" style="background: #cdcdcd;"></div>
</div>
<style>
BODY {
margin: 0px;
padding: 0px;
}
#pageContainer {
position: relative;
margin: 10px auto;
-webkit-transform-origin:50% 20%;
-webkit-transform:scale(1.37);
width: 1218px;
height: 774px;
border: 1px solid #000000;
}
#mainContainer {
width: 100%;
overflow: hidden;
}
</style>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
</script>
<script type="text/javascript">
$(document).ready(function() {
setHeight();
$(window).resize(setHeight);
});
function setHeight()
{
$('#mainContainer').css({'height': $(window).height()});
}
$('#mainContainer').mousemove(function (e) {
});
</script>
</body>
</html>
Currently #mainContainer div has overflow hidden as i dont want to show scroll bars and #pageContainer div (inner div) is scaled at 1.37 using css3, as in certain cases based on screen / browser width height #pageContainer's content would be hidden because of overflow hidden.
I want to code javascript so that if somebody moves cursor in #mainContainer, based on position of mouse X and Y co-ordinates I would like to move #pageContainer so that similar position of #pageContainer would be visible (I hope it is clear).
I m having problem as I m using -webkit-transform-origin, unable to understand how to move #pageContainer around with respect to mouse co-ordinates of #mainContainer.
UPDATE:
I m looking something like what happens in issuu.com website when you open an ebook and zoom it more than the browser size (Should make it more clear)
I m looking for algo or pointer how to achieve it (how to calculate it) not necessarily a working script.
How can this be achieved.
Below is working html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="mainContainer">
<div id="pageContainer" >
<div id="pageContainerInner"style="background: #cdcdcd;">
</div>
</div>
<style>
BODY {
margin: 0px;
padding: 0px;
}
#pageContainer {
margin: 10px auto;
-webkit-transform-origin:50% 20%;
-webkit-transform:scale(1.37);
width: 1218px;
height: 774px;
}
#mainContainer {
width: 100%;
overflow: hidden;
}
#pageContainerInner {
position: relative;
width: 1218px;
height: 774px;
border: 1px solid #000000;
top: 0;
left: 0;
}
</style>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
</script>
<script type="text/javascript">
var pageWidth = 1220;
var pageHeight = 776;
var scale = 1.37;
var scaledDelta = 5; //Percentage mouse position approximation
$(document).ready(function() {
setHeight();
$(window).resize(setHeight);
});
function setHeight()
{
$('#mainContainer').css({'height': $(window).height()});
}
$('#mainContainer').mousemove(function (e) {
// Calculate the offset of scaled Div
var offsetX = $('#pageContainer').offset().left;
var offsetY = $('#pageContainer').offset().top;
// Calculate div origin with respect to screen
var originX = (-1 * offsetX) / scale;
var originY = (-1 * offsetY) / scale;
var wWdt = $(window).width();
var wHgt = $(window).height();
// Now convert screen positions to percentage
var perX = e.pageX * 100 / wWdt;
var perY = e.pageY * 100 / wHgt;
// Div content which should be visible
var pageX = perX * pageWidth / 100;
var pageY = perY * pageHeight / 100;
// Calculate scaled divs new X, Y offset
var shiftX = (originX - pageX) + (e.pageX / scale);
var shiftY = (originY - pageY) + (e.pageY / scale);
$('#pageContainerInner').css({'left': shiftX+'px', 'top': shiftY+'px'});
});
</script>
</body>
</html>
Hope this will help others.
I have posted a probable solution at http://jsfiddle.net/PYP8c/.
Below are the modified styles for your page.
BODY {
margin: 0px;
padding: 0px;
}
#mainContainer {
width: 100%;
overflow: hidden;
position: relative;
margin: 10px auto;
-webkit-transform-origin:50% 20%;
-webkit-transform:scale(1.37);
width: 1218px;
height: 774px;
border: 1px solid #000000;
}
#pageContainer {
position:absolute;
top:0px;
}
This is the javascript code for the same.
$(document).ready(function() {
//setHeight();
//$(window).resize(setHeight);
});
function setHeight()
{
$('#mainContainer').css({'height': $(window).height()});
}
$('#mainContainer').mousemove(function (e) {
var contentHeight = $("#pageContainer").height();
var minTop = 774 - contentHeight;
if(minTop>0)
minTop = 0;
var currTop = ((e.pageY-10)/774.0)*(minTop);
document.getElementById("pageContainer").style.top = currTop+'px';
});
Its just a demo on how you could get the text to move based on the mouse coordinates.
You could make a lot of changes, like adding a scrollbar that fades which gives the user a feedback about how much content is still available in both the vertical directions.
Also I have used hard coded values for height, but in your final version I would recommend you get the height of the mainContainer division dynamically.

Categories