I am an absolute beginner to Java Script. My task is to make an interactive radio where a song is played if a mouse is in a certain position on the map. It works but only in a certain size of the browser window. If I change the size the "song positions" are misplaced.
I am using p5 libraries.
This is my HTML code:
<!DOCTYPE html>
<html>
<head>
<title>Canvas Trial</title>
<link rel="stylesheet" type="text/css" href="style.css">
<script type="text/javascript" src="script.js"> </script>
<script src="../p5.min.js"></script>
<script src="../addons/p5.dom.min.js"></script>
<script src="../addons/p5.sound.min.js"></script>
</head>
<body>
<center><p class="title">CHRISTMAS RADIO</p></center>
<div class="radio" id="clickArea" onmousemove="trackMouse()">
<img id="radio" onclick="rotate()" src="images/radio.png""></img>
</div>
</body>
</html>
This is my CSS code:
canvas{
background-image: url("images/Map1.png");
background-position: center center;
background-repeat: no-repeat no-repeat;
padding-left: 0;
padding-right: 0;
margin-left: auto;
margin-right: auto;
display: block;
width: 800px;
border:solid 2px;
border-bottom-color:#ffe;
border-left-color:#eed;
border-right-color:#eed;
border-top-color:#ccb;
max-height:100%;
max-width:100%;
}
p.title{
font-family: Arial, Helvetica, sans-serif;
font-size: 250%;
font-weight: 900;
color: white;
text-shadow: -2px 0 #c61819, 0 2px #c61819, 2px 0 #c61819, 0 -2px #c61819;
}
.radio{
position:relative;
top: 10%;
padding-left: 0;
padding-right: 0;
margin-left: auto;
margin-right: auto;
display: block;
border: solid 2px;
border-color:#52361b;
padding:0;
width: 944px;
height:165px;
}
This is my Java Script:
var x = "";
var y = "";
var song1;
var song2;
function preload() {
song1 = loadSound('audio/2.mp3');
song2 = loadSound('audio/3.mp3');
}
function setup() {
createCanvas(944,566);
}
function draw() {
clear();
x = mouseX;
rect(x, y, 20, 565);
fill(82, 54, 27);
}
function trackMouse(){
var x = event.clientX;
console.log(window.screenX);
if(x>315&&x<340){
song1.loop();
document.getElementById("clickArea").style.backgroundColor="white";
} else {
song1.stop();
document.getElementById("clickArea").style.backgroundColor="black";
}
if(x>400&&x<450){
song2.loop();
document.getElementById("clickArea").style.backgroundColor="#FFDAB9";
} else {
song2.stop();
document.getElementById("clickArea").style.backgroundColor="black";
}
}
//document.getElementById("canvas").style.background-image="url("images/Map2.png")";
Do you have any suggestions/advices?
That is because you're using absolute values in pixels for locating the areas on the radio map and you're accessing them in var x. You would need relative values that is in percentage to have them constant even when the browser is resized.
You can try doing it by: getting the window.innerWidth and window.innerHeight, store it in variables say v1 and v2, that is your 100%. Now to obtain relative position coordinates, divide the current position you're using say 315 by it and multiply by 100.
Example : Say the width is 1200 pixels at maximize then, 315 is 26.25%
of 1200. That's the value you will use and it will work even when the
browser is resized.
(Absolute coodinate/ Complete width at maximized screen) X 100 = relative coordinate
(315/1200)x100 = 26.25%
Remember to make the changes to your code according to that and it should work fine. Hope, it gives you the idea.
Related
I can find similar answers but not exact. I have a map, that I want an image of a car to appear on top of when the mouse is clicked, and rotate so it always points towards the cursor while the mouse button is held down, and then when the mouse is depressed the image of the car disappears and the rotation is reset, so the next time the mouse is clicked the image appears pointing towards the top of the screen so it can be rotated again. I am trying to do this in javascript on a leaflet map.
The problem I have is the image does not rotate to point towards the cursor, it rotates unusually, and I can't make it reset to point upwards when the mouse is depressed
HTML:
<html>
<head>
<meta charset="utf-8">
<link href="style.css" rel="stylesheet">
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.7.1/dist/leaflet.css"
integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A=="
crossorigin=""/>
</head>
<body>
<div class="main-container">
<header>
<div class="navitem">
</div>
</header>
<section class="main-content">
<div id="gameMap">
</div>
<img id="carIcon" style="display: none; z-index:1000;height:80;width:100;" src="carIcon.png"/>
</section>
</div>
</body>
<script src="https://unpkg.com/leaflet#1.7.1/dist/leaflet.js" integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA=="crossorigin=""></script>
<script src="gameMap1.js"></script>
</html>
JAVASCRIPT:
//Initialize leaflet maps and disable dragging and scrolling
var mymap = L.map('gameMap',{
renderer: L.canvas()
}).setView([40.76396283699563, -73.9695559410492], 16);
L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}', {
attribution: 'Map data © OpenStreetMap contributors, CC-BY-SA, Imagery © Mapbox',
maxZoom: 18,
id: 'mapbox/satellite-v9',
tileSize: 512,
zoomOffset: -1,
accessToken: 'pk.eyJ1IjoiaGFsNiIsImEiOiJja2Fld2t4bG0wandzMnpwbmp2a24xemdqIn0.OhKsfnxo_9tOpw30fWU-CQ'
}).addTo(mymap);
mymap.dragging.disable();
mymap.scrollWheelZoom.disable();
let gameMapDiv = document.getElementById('gameMap');
let carImage = document.getElementById("carIcon");
//functions to make car image display and disappear
let displayCarImage = function(e){
carImage.style.display = '';
carImage.style.position = 'absolute';
carImage.style.left = clicked_x-52;
carImage.style.top = clicked_y+70;
carImage.style.pointerEvents = 'none';
};
let stopDisplayingCarImage = function(e){
carImage.style.display = 'none';
carImage.style.transform = 'rotate(0deg)';
angle = 0
}
//function to calculate angle to rotate the car image by
angle = 0;
function rotateImageAngle(){
let angle = Math.atan2(-((clicked_y+72) - mouseY), (clicked_x-50) - mouseX)*(180/Math.PI);
return angle;
};
//functions to control what happens when mouse is clicked, moved and depressed
var clicked_x = 0;
var clicked_y = 0;
mymap.on('mousedown', function(e) {
clicked_x =e.containerPoint.x;
clicked_y =e.containerPoint.y;
displayCarImage(e);
});
var mouseX = 0;
var mouseY = 0;
gameMapDiv.addEventListener("mousemove",function(e){
mouseX = e.clientX;
mouseY = e.clientY;
angleToRotateCar = rotateImageAngle() +'deg'
carImage.style.transform = 'rotate('+angleToRotateCar+')';
});
mymap.on('mouseup', function(e) {
stopDisplayingCarImage(e)
});
CSS:
:root {
position: relative;
font-family: "Comic Sans MS","Trebuchet MS",Arial, Helvetica, sans-serif;
}
body{
box-sizing: border-box;
text-align:center;
margin:0;
padding:0;
}
body, html{
height:100%;
width:100%
}
.main-container{
box-sizing: border-box;
display:flex;
flex-flow:column;
height:100%;
}
header{
flex:0 1 auto;
display:flex;
flex-direction: row;
justify-content: center;
align-items: center;
height:100px;
background-color: white;
border-bottom:solid 3px black;
box-shadow: 0 0 10px 5px rgba(0,0,0,0.19);
z-index: 1000;
}
.navitem{
height:80%;
}
.main-content{
flex:0 2 auto;
height:100%;
}
#gameMap{
height:90%;
z-index:900;
position:relative;
}
footer{
position: absolute;
left: 0;
bottom: 0;
height: 50px;
width: 100%;
overflow: hidden;
text-align: center;
margin: 0 auto;
}
[![https://image.flaticon.com/icons/png/512/0/798.png][1]][1]
so im making some vanilla js draggable modal boxes but i keep having trouble when it comes to the dragging.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" type="text/css" href="css/main.css">
<title>Me website mate</title>
</head>
<body>
<!--------------------------------------------------------------------------------------->
<button id="buttonone" class="button">click me</button>
<div id="boxone" class="box">
<div id="headerone" class="header">header
<div class="box-buttons">
<div id="box-close-one" class="operation-button" style="background-color: rgb(207, 9, 33);">×</div>
<div id="box-maximize" class="operation-button" style="background-color: rgb(248, 201, 27);">max</div>
<div id="box-minimize" class="operation-button" style="background-color: rgb(0, 104, 69);">min</div>
</div>
</div>
<div class="content">
content
</div>
<div class="resize"></div>
</div>
<!---------------------------------------------------------------------------------------->
<button id="buttontwo" class="button">click me</button>
<div id="boxtwo" class="box" style="left: 500px;">
<div id="headertwo" class="header">header
<div class="box-buttons">
<div id="box-close-two" class="operation-button" style="background-color: rgb(207, 9, 33);">×</div>
<div id="box-maximize" class="operation-button" style="background-color: rgb(248, 201, 27);">max</div>
<div id="box-minimize" class="operation-button" style="background-color: rgb(0, 104, 69);">min</div>
</div>
</div>
<div class="content">
content
</div>
<div class="resize"></div>
</div>
<script src="javaScript/main.js"></script>
</body>
</html>
the html has 2 buttons and 2 modal boxes each button opening the assigned box, each box had a close button that hides said modal box
.box{
/*display: none;*/
font-family: "Comic Sans MS", cursive, sans-serif;
font-size: 12px;
background-color: #666;
border: 1px solid #000;
position: absolute;
height: 280px;
width: 400px;
margin: 2px;
position: absolute;
left: 0px;
z-index: 9;
}
.header{
position: relative;
height: 32px;
line-height: 32px;
font-size: 1.2em;
vertical-align: middle;
padding: 0 8px 0 8px;
white-space: normal;
overflow: hidden;
background: rgb(69, 161, 211);/*69, 161(golden ratio), 211(prime)*/
cursor: grab;
position: initial;
}
.box-buttons{
position: absolute;
display: flex;
flex-direction: row-reverse;
right: 0em;
top: 0em;
}
.operation-button{
height: 31px;
width: 31px;
border: 1px solid black;
text-align: center;
cursor: pointer;
}
.content{
position: absolute;
width: 400px;
height: 248px;
}
some styling
const boxOne = document.querySelector("#boxone");
boxOne.style.display = "none";
const boxTwo = document.querySelector("#boxtwo");
boxTwo.style.display = "none";
/////
const buttonOne = document.querySelector("#buttonone");
const closeOne = document.querySelector("#box-close-one");
const headOne = document.querySelector("#headerone");
buttonOne.addEventListener("click", function open(e){
openBox(boxOne);
});
closeOne.addEventListener("click", function close(e){
closeBox(boxOne);
});
headOne.addEventListener("mousedown",function grab(e){
mouseDown(boxOne, headOne,e);
});
/////
const buttonTwo = document.querySelector("#buttontwo");
const closeTwo = document.querySelector("#box-close-two");
const headTwo = document.querySelector("#headertwo");
buttonTwo.addEventListener("click",function open(e){
openBox(boxTwo);
});
closeTwo.addEventListener("click",function close(e){
closeBox(boxTwo);
});
function mouseDown(B,H,i){
var box = B;
var head = H;
head.style.cursor = "grabbing";
window.addEventListener("mousemove",drag);
window.addEventListener("mouseup",drop);
var windowHeight = window.innerHeight;
var windowWidth =window.innerWidth;
let previousX = i.clientX;
let previousY = i.clientY;
function drag(i){
let currentX = previousX - i.clientX;
let currentY = previousY - i.clientY;
const bounds = box.getBoundingClientRect();
console.log(bounds);
box.style.left = bounds.left - currentX + "px";
box.style.top = bounds.top - currentY + "px";
previousX = i.clientX;
previousY = i.clientY;
}
function drop(){
head.style.cursor = "grab";
window.removeEventListener("mousemove",drag);
window.removeEventListener("mouseup",drop);
}
}
function openBox(rect){
if (rect.style.display === "none") {
rect.style.display = "block";
}
console.log("open");
}
function closeBox(rectClose){
if(rectClose.style.display !== "none"){
rectClose.style.display = "none";
}
console.log("close");
}
it opens and closes well but it seems to be having a lot of trouble when i try to drag it. it always seems to go to the bottom right of the screen for some reason. Ive tried this project before but only with a single box, the code for the single box worked great and dragged perfectly fine but when ive tried to copy the same instructions , it fails. ik that it my code rn is inefficient but rn its just a prototype. Ive tried console.log to trouble shoot it but when i do the same to the previous project which worked fine, the output of the console looks pretty much the same. i dont know if im missing something bc i am a beginner, ive never taken a class on JS, so i dont really know what to look for or how to properly debug this. I would really appreciate the help and if possible, i would like to keep it in vanilla JS for the practice.
so after some experimenting, i boiled the answer down to the fact that the box moved 2 pixels to the right and 2 pixels down plus the movement of my mouse. I know this because I printed out the bounds variable to the console and moving my mouse only up (with a straightedge) and to the side. im still not sure what causes this however i just added a "-2" to the box.style.left and box.style.top to mitigate this problem so now the code is
box.style.left = (bounds.left - currentX) - 2 + "px";
box.style.top = (bounds.top - currentY) -2 + "px";
thank you to anybody that actually tired to figure it out and help me
I have created a button which should shift the window's Y to "BOX - 5" div's Y middle through onclick. So in other words I want to set the "Box - 5" div in the middle of the window. I have tried many methods using window.scrollTo and using elements.innerHeight/2, but I still cannot center the element to the middle of the window/screen. Please Help.
I wish to only use Javascript, but if its not possible with it then I would accept jQuery script.
index.html:
window.onbeforeunload = function () {
this.scrollTo(0, 0);
}
var content = document.getElementById("content"),
current = 0;
for (var y=0;y<10;y++) {
var box = document.createElement("div");
box.id = "box";
box.innerHTML = "Box - " + (y+1);
content.appendChild(box);
}
document.querySelector("BUTTON").onclick = function() {
var box_5 = document.querySelectorAll("#box")[4];
/*
NEED HELP HERE
*/
}
body {
margin: 0;
}
#box {
position: relative;
height: 500px;
width: 100%;
margin: 5% auto 5% auto;
color: black;
background-color: skyblue;
border: black 1px solid;
font-size: 50px;
text-align: center;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<button>CLICK TO SET THE WINDOW'S Y MIDDLE TO (BOX 5)'s Y MIDDLE</button>
<div id="content"></div>
</body>
</html>
Updated your snippet as below. You can use DOM element property offsetTop to check its Y position and use window.scroll to scroll the view to that element. Another sidenote, it's better to not assign the same id to multiple elements, so I change the id property to class and added identifier _{index} for the class name.
window.onbeforeunload = function () {
this.scrollTo(0, 0);
}
var content = document.getElementById("content"),
current = 0;
for (var y=0;y<10;y++) {
var box = document.createElement("div");
box.className += "box _" + (y+1);
box.innerHTML = "Box - " + (y+1);
content.appendChild(box);
}
document.querySelector("BUTTON").onclick = function() {
var box_5 = document.querySelectorAll(".box._5")[0];
if (box_5) {
// scroll the window view to the element
window.scroll({
top: box_5.offsetTop,
behavior: 'smooth',
})
}
}
body {
margin: 0;
}
.box {
height: 500px;
width: 100%;
margin: 5% auto 5% auto;
color: black;
background-color: skyblue;
border: black 1px solid;
font-size: 50px;
text-align: center;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<button>CLICK TO SET THE WINDOW'S Y MIDDLE TO (BOX 5)'s Y MIDDLE</button>
<div id="content"></div>
</body>
</html>
I have an Iframe that loops through an array of published Google sheets. Is there a way that I can have the iframe scroll down over time to display all the data from the published URLs?
Ideally, I would like to get the results sheets to start from the top and over 30 seconds, scroll down to the bottom, then when at the bottom, switch to the next results sheet. This would then continually loop from Site 1 to Site 5.
Here is my code:
var sites = [
"https://docs.google.com/spreadsheets/d/1Gd4eYAukSIvU0VS_zt37TWNiKi15-lB3V8f5AA3IXJU/pubhtml?gid=0&single=true",
"https://docs.google.com/spreadsheets/d/1Gd4eYAukSIvU0VS_zt37TWNiKi15-lB3V8f5AA3IXJU/pubhtml?gid=1991236368&single=true",
"https://docs.google.com/spreadsheets/d/1Gd4eYAukSIvU0VS_zt37TWNiKi15-lB3V8f5AA3IXJU/pubhtml?gid=205619546&single=true",
"https://docs.google.com/spreadsheets/d/1Gd4eYAukSIvU0VS_zt37TWNiKi15-lB3V8f5AA3IXJU/pubhtml?gid=1480439822&single=true",
"https://docs.google.com/spreadsheets/d/1Gd4eYAukSIvU0VS_zt37TWNiKi15-lB3V8f5AA3IXJU/pubhtml?gid=1101347808&single=true"
];
var currentSite = sites.length;
$(document).ready(function() {
var $iframe = $("iframe").attr("src", "https://docs.google.com/spreadsheets/d/1Gd4eYAukSIvU0VS_zt37TWNiKi15-lB3V8f5AA3IXJU/pubhtml?gid=0&single=true");
setInterval(function() {
(currentSite == 1) ? currentSite = sites.length - 1: currentSite = currentSite - 1;
$iframe.attr("src", sites[currentSite]);
}, 10000);
});
iframe {
height: 768px;
width: 1024px;
border: 2px solid gray;
}
body {
width: 1024px;
length: 768px;
background-color: #C9C9C9;
margin: 0 auto;
}
#heading-wrapper {
margin: 0 auto;
background-color: #FF6600;
border: 2px solid black;
text-align: center;
width: 1024px;
}
#heading-wrapper h1 {
font-family: Arial;
vertical-align: middle;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<head>
<title>Live Results</title>
</head>
<body>
<div id="heading-wrapper">
<h1>Live Results</h1>
</div>
<iframe></iframe>
</body>
I don't even know if it is possible to have it scroll slowly down.
Take a look at
iframe.contentWindow.scrollTo(x, y);
You could create a function that calls that periodically with an incremented y scroll amount.
use set interval and change the scrollTop property of your containing element:
setInterval(changeScrollPosition, 50); // every 50 milliseconds
function changeScrollPosition(el)
{
var currentTop = el.scrollTop;
el.scrollTop = currentTop + howMuchYouWantToScrollBy;
}
<link rel="stylesheet" type="text/css" href="reset.css" />
<style type="text/css">
body { position: relative; }
.contain { position:relative; overflow: hidden; width: 80%; height: 100%; margin: 0 auto; }
.box {
background-color: #F0F0F0;
color: #888;
font-family: Arial, Tahoma, serif;
font-size: 13px; }
.box p { padding: 10px; }
.box span {
float: left;
font-size: 26px;
font-weight: bold; }
div.alt { background-color: #CCC; }
</style>
<script type="text/javascript" src="jquery-1.3.2.min.js"></script>
<script type="text/javascript">
var myFluidGrid = {
COLNUMBER : 2, // Minimum column number.
COLMARGIN : 10, // Margin (in pixel) between columns/boxes.
COLWIDTH : 240, // Fixed width of all columns.
doLayout : function() {
var self = this;
var pointer = 0;
var arr = [];
var columns = Math.max(this.COLNUMBER, parseInt($('body').innerWidth() / (this.COLWIDTH + this.COLMARGIN)));
$('.box').css('position', 'absolute').css('width', this.COLWIDTH + 'px');
$('.box').each(function() {
var tempLeft = (pointer * (self.COLWIDTH + self.COLMARGIN));
$(this).css('left', tempLeft + 'px');
var tempTop = 0;
if (arr[pointer]) { tempTop = arr[pointer]; }
$(this).css('top', tempTop + 'px');
arr[pointer] = tempTop + $(this).outerHeight() + self.COLMARGIN;
pointer++;
if (pointer === columns) { pointer = 0; }
});
}
};
$(window).ready(function() {
myFluidGrid.doLayout();
}).resize(function() {
myFluidGrid.doLayout();
});
</script>
<div class="contain">
<div class="box">This is box number 1...</div>
<div class="box">This is box number 2...</div>
<div class="box">This is box number 3...</div>
</div>
Demo of current code: http://grahamthomas.me/temp/test.html
Trying to get the above grid to remain centered in the window no matter its size. I currently have it roughly centered, but when the window size is adjusted, the centering becomes untrue until the new column is populated with content (i.e. when the dynamic grid is between columns--larger than 3 columns, but no quite 4).
I'm not great at JS, but my logic is:
create a 100% wrapper (which would mimic the body.innerWidth
dimension in the JS)
create a centered wrapper inside this (80% for example)
place the content in the centered wrapper
once the 100% wrapper is large enough to handle an additional column, append the new div within the centered wrapper
You can clearly see the overflow:hidden property 'run over' the right-most boxes when dragging the window smaller. I assume from this, the window width isn't being calculated properly. I tried variants of var columns, like:
var columns = Math.max(this.COLNUMBER, parseInt(($('body').innerWidth() * 0.8)/ (this.COLWIDTH + this.COLMARGIN)));
..which keeps the columns within the window, but still isn't a proper center.
I've been looking at this for a while, anyone have any ideas?
Thanks
No JavaScript required:
<html>
<head>
<style>
body {
text-align: center;
}
div.main {
position: absolute;
top: 100px;
left: 50%;
margin-left: -40%;
width: 80%;
}
div.main div.block {
height: 180px;
width: 180px;
background: #a00;
float: right;
margin: 10px;
}
</style>
</head>
<body>
<div class="main">
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
</div>
</body>
</html>