elements doesnt stick to the grid, css - css

help me to achieve the expected result.
i have a grid: the red part.
a nested grid: the blue part.
but im not having lucky implementing this on css. the grid is pretty simple, the roulettes with 50% of the screen, a place to put the numbers with 30% of the screen and a "bank" to store numbers with 20% of the screen.
the problem here is the nested grid. in each side of the nested grid should be a roullete, wheel and spin. they should mantain the 1:1 square aspect ratio and scale with the window. but they arent even sticking to the grid.
here is an image of the expected result:
and here is what i get so far:
const sectors = [{
color: "#f82",
label: "Stack"
},
{
color: "#0bf",
label: "10"
},
{
color: "#fb0",
label: "200"
},
{
color: "#0fb",
label: "50"
},
{
color: "#b0f",
label: "100"
},
{
color: "#f0b",
label: "5"
},
{
color: "#bf0",
label: "500"
},
];
const rand = (m, M) => Math.random() * (M - m) + m;
const tot = sectors.length;
const EL_spin = document.querySelector("#spin");
const ctx = document.querySelector("#wheel").getContext('2d');
const dia = ctx.canvas.width;
const rad = dia / 2;
const PI = Math.PI;
const TAU = 2 * PI;
const arc = TAU / sectors.length;
const friction = 0.991; // 0.995=soft, 0.99=mid, 0.98=hard
let angVel = 0; // Angular velocity
let ang = 0; // Angle in radians
const getIndex = () => Math.floor(tot - ang / TAU * tot) % tot;
function drawSector(sector, i) {
const ang = arc * i;
ctx.save();
// COLOR
ctx.beginPath();
ctx.fillStyle = sector.color;
ctx.moveTo(rad, rad);
ctx.arc(rad, rad, rad, ang, ang + arc);
ctx.lineTo(rad, rad);
ctx.fill();
// TEXT
ctx.translate(rad, rad);
ctx.rotate(ang + arc / 2);
ctx.textAlign = "right";
ctx.fillStyle = "#fff";
ctx.font = "bold 30px sans-serif";
ctx.fillText(sector.label, rad - 10, 10);
//
ctx.restore();
};
function rotate() {
const sector = sectors[getIndex()];
ctx.canvas.style.transform = `rotate(${ang - PI / 2}rad)`;
EL_spin.textContent = !angVel ? "SPIN" : sector.label;
EL_spin.style.background = sector.color;
}
function frame() {
if (!angVel) return;
angVel *= friction; // Decrement velocity by friction
if (angVel < 0.002) angVel = 0; // Bring to stop
ang += angVel; // Update angle
ang %= TAU; // Normalize angle
rotate();
}
function engine() {
frame();
requestAnimationFrame(engine)
}
// INIT
sectors.forEach(drawSector);
rotate(); // Initial rotation
engine(); // Start engine
EL_spin.addEventListener("click", () => {
if (!angVel) angVel = rand(0.25, 0.35);
});
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
.grid {
display: grid;
grid-template-rows: 50vh 30vh 20vh;
}
.roulettes {
display: grid;
grid-template-columns: 50fr 50fr;
}
#roulette {
display: inline-block;
position: relative;
overflow: hidden;
}
#wheel {
display: block;
}
#spin {
font: 1.5em/0 sans-serif;
user-select: none;
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
position: absolute;
top: 50%;
left: 50%;
width: 30%;
height: 30%;
margin: -15%;
background: #fff;
color: #fff;
box-shadow: 0 0 0 8px currentColor, 0 0px 15px 5px rgba(0, 0, 0, 0.6);
border-radius: 50%;
transition: 0.8s;
}
#spin::after {
content: "";
position: absolute;
top: -17px;
border: 10px solid transparent;
border-bottom-color: currentColor;
border-top: none;
}
#op_roulette {
display: inline-block;
position: relative;
overflow: hidden;
}
#op_wheel {
display: block;
}
#op_spin {
font: 1.5em/0 sans-serif;
user-select: none;
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
position: absolute;
top: 50%;
left: 50%;
width: 30%;
height: 30%;
margin: -15%;
background: #fff;
color: #fff;
box-shadow: 0 0 0 8px currentColor, 0 0px 15px 5px rgba(0, 0, 0, 0.6);
border-radius: 50%;
transition: 0.8s;
}
#op_spin::after {
content: "";
position: absolute;
top: -17px;
border: 10px solid transparent;
border-bottom-color: currentColor;
border-top: none;
}
<body>
<div class="grid" width="100vw" height="100vh">
<div class="roulettes">
<div id="roulette">
<canvas id="wheel" width="300%" height="300%"></canvas>
<div id="spin">SPIN</div>
</div>
<div id="op_roullete">
<canvas id="op_wheel" width="300%" height="300%"></canvas>
<div id="op_spin">SPIN</div>
</div>
</div>
<div id="operation">=</div>
<div id="bank">BANK</div>
</div>
</body>
PS. (the will is made by https://stackoverflow.com/users/383904/roko-c-buljan) i know that the wheel is draw by js, and it only draws in the wheel element. once i get the grid right i will change the code to draw a wheel on the op_wheel element too, so this is not a problem.

Related

Visibility of elements in CSS

I'm writing a React app, but my question I'm thinking is not about React but about CSS. I have a bar from which the user can choose a sort option:
<div className="innerLineVisor">
<div className="sortLine" ref={lineRef}>
{cuisines.map(cuisine =>
<div key={cuisine.id} className="sortButton">{cuisine.value}</div>
)}
</div>
</div>
Here are their styles:
.innerLineVisor {
width: 80%;
height: 40px;
border: #C80303 1px solid;
overflow: hidden;
position: absolute;
box-sizing: border-box;
left: 10%;
bottom: 0;
}
.sortLine {
height: 40px;
background-color: white;
position: absolute;
left: 0;
bottom: 0;
display: inline;
transition: 1s;
}
.sortButton {
float: left;
width: 120px;
padding: 5px 10px;
border: darkgray 1px solid;
border-radius: 10px;
background-color: white;
margin-top: 5px;
margin-left: 5px;
margin-right: 5px;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
box-sizing: border-box;
}
Now when one of the buttons does not fit on the left, I can see part of it. And on the right is empty until the button fits completely.
What can I do to see part of the button on the right as well?
This is the arrow code:
function leftMotion() {
setLimitPositions({...limitPositions, right: false})
if (linePosition + step > 0) {
lineRef.current.setAttribute('style', 'left: 0')
setLinePosition(0)
setLimitPositions({...limitPositions, left: true})
return
}
lineRef.current.setAttribute('style', 'left:' + (linePosition + step) + 'px')
setLinePosition(linePosition + step)
if (limitPositions.left && arrowsPressed.left) {
lineRef.current.setAttribute('style', 'left:' + (linePosition + 10) + 'px')
}
}
function rightMotion() {
setLimitPositions({...limitPositions, left: false})
lineRef.current.setAttribute('style', 'left:' + (linePosition - step) + 'px')
setLinePosition(linePosition - step)
const lineVisorWidth = getLineVisorWidth()
if (lineVisorWidth > (lineLength - (Math.abs(linePosition))) - lineVisorWidth) {
const limitRightPosition = lineLength - lineVisorWidth
lineRef.current.setAttribute('style', 'left:' + (-limitRightPosition) + 'px')
setLinePosition(-limitRightPosition)
setLimitPositions({...limitPositions, right: true})
}
}

How to place canvas circular progress bar in grid?

I am trying to use this Codepen to create inside each section of my grid container on the profile page separate progress circles, but I get only one visible circle, the others are just empty squares without progress circles.
Could someone please give me a clue what went wrong? I tried to re-name classes and tweaked the code, but it didn't work.
Part of html:
<div class="grid-container">
<div class="counter" data-cp-percentage="75" data-cp-color="#00bfeb"></div>
<div class="counter" data-cp-percentage="65" data-cp-color="#EA4C89"></div>
<div class="counter" data-cp-percentage="35" data-cp-color="#FF675B"></div>
<div class="counter" data-cp-percentage="44" data-cp-color="#FF9900"></div>
</div>
CSS
.profile_intro {
background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);
background-size: 400% 400%;
animation: gradient 15s ease infinite;
margin-top: 0px;
width: 100%;
height: 20%;
}
.profilepic-img {
vertical-align: center;
border-radius: 100px;
width: 100px;
height: 100px;
display: block;
margin-left: auto;
margin-right: auto;
z-index: 1;
}
#keyframes gradient {
0% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}
}
.userinfo {
margin: auto;
width: 50%;
padding: 5px;
text-align: center;
}
.useremail {
margin-top: 5%;
}
table {
border: 2px solid #cccccc;
width: 80%;
border-collapse: collapse;
margin-left: auto;
margin-right: auto;
text-align: center;
color: grey;
}
th,
td {
padding: 5px;
text-align: center;
}
th {
font-size: 18px;
}
.grid-container {
display: grid;
/*important!
justify-content: space-evenly;
grid-template-columns: auto auto; /*important!!
/* grid-template-columns: 50px 50px; /*Make the grid smaller than the container*/
*/ grid-gap: 10px;
background-color: #f1eee3;
padding: 10px;
align-content: center;
left: 0px;
}
.grid-container>div {
background-color: rgba(255, 255, 255, 0.8);
text-align: center;
/* padding: 10px 0; */
font-size: 3vw;
border-radius: 25px;
background: #faf8f4;
width: 35vw;
height: 35vw;
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
color: #383e3f;
text-decoration-style: solid;
}
/*progress Bar */
h1 {
background: rgba(255, 255, 255, 0.8);
box-shadow: 0px 1px 10px 2px rgba(0, 0, 0, 0.2);
border-bottom: 3px solid #00bfeb;
font-size: calc(1em + 1vmax);
}
.counter {
display: -webkit-inline-box;
display: inline-flex;
cursor: pointer;
width: 300px;
height: 300px;
max-width: 100%;
position: relative;
-webkit-box-pack: center;
justify-content: center;
-webkit-box-align: center;
align-items: center;
font-size: calc(1em + 1vmin);
-webkit-transition: height .2s ease-in-out;
transition: height .2s ease-in-out;
background: #fff;
border-radius: 50%;
box-shadow: 0px 1px 10px 2px rgba(0, 0, 0, 0.2);
margin: 1em 0;
}
.percentage {
position: absolute;
text-align: center;
top: 50%;
left: 0;
right: 0;
vertical-align: middle;
-webkit-transform: translate3d(0, -50%, 0);
transform: translate3d(0, -50%, 0);
}
Javascript
document.addEventListener("DOMContentLoaded", function() {
var circleProgress = (function(selector) {
var wrapper = document.querySelectorAll(selector);
Array.prototype.forEach.call(wrapper, function(wrapper, i) {
var wrapperWidth,
wrapperHeight,
percent,
innerHTML,
context,
lineWidth,
centerX,
centerY,
radius,
newPercent,
speed,
from,
to,
duration,
start,
strokeStyle,
text;
var getValues = function() {
wrapperWidth = parseInt(window.getComputedStyle(wrapper).width);
wrapperHeight = wrapperWidth;
percent = wrapper.getAttribute('data-cp-percentage');
innerHTML = '<span class="percentage"><strong>' + percent +
'</strong> %</span><canvas class="circleProgressCanvas"
width="' + (wrapperWidth * 2) + '" height="' + wrapperHeight *
2 + '"></canvas>';
wrapper.innerHTML = innerHTML;
text = wrapper.querySelector(".percentage");
canvas = wrapper.querySelector(".circleProgressCanvas");
wrapper.style.height = canvas.style.width = canvas.style.height
= wrapperWidth + "px";
context = canvas.getContext('2d');
centerX = canvas.width / 2;
centerY = canvas.height / 2;
newPercent = 0;
speed = 1;
from = 0;
to = percent;
duration = 1000;
lineWidth = 25;
radius = canvas.width / 2 - lineWidth;
strokeStyle = wrapper.getAttribute('data-cp-color');
start = new Date().getTime();
};
function animate() {
requestAnimationFrame(animate);
var time = new Date().getTime() - start;
if (time <= duration) {
var x = easeInOutQuart(time, from, to - from, duration);
newPercent = x;
text.innerHTML = Math.round(newPercent) + " %";
drawArc();
}
}
function drawArc() {
var circleStart = 1.5 * Math.PI;
var circleEnd = circleStart + (newPercent / 50) * Math.PI;
context.clearRect(0, 0, canvas.width, canvas.height);
context.beginPath();
context.arc(centerX, centerY, radius, circleStart, 4 * Math.PI,
false);
context.lineWidth = lineWidth;
context.strokeStyle = "#ddd";
context.stroke();
context.beginPath();
context.arc(centerX, centerY, radius, circleStart, circleEnd,
false);
context.lineWidth = lineWidth;
context.strokeStyle = strokeStyle;
context.stroke();
}
var update = function() {
getValues();
animate();
}
update();
var btnUpdate = document.querySelectorAll(".btn-update")[0];
btnUpdate.addEventListener("click", function() {
wrapper.setAttribute("data-cp-percentage",
Math.round(getRandom(5, 95)));
update();
});
wrapper.addEventListener("click", function() {
update();
});
var resizeTimer;
window.addEventListener("resize", function() {
clearTimeout(resizeTimer);
resizeTimer = setTimeout(function() {
clearTimeout(resizeTimer);
start = new Date().getTime();
update();
}, 250);
});
});
function easeInOutQuart(t, b, c, d) {
if ((t /= d / 2) < 1) return c / 2 * t * t * t * t + b;
return -c / 2 * ((t -= 2) * t * t * t - 2) + b;
}
});
circleProgress('.counter');
function getRandom(min, max) {
return Math.random() * (max - min) + min;
}
});
Found the bug: I didn't have in my HTML some elements that had been mentioned in JavaScript. Changed names of classes and it works fine at the moment. Thank you all!

CSS3 3D Rotation: How perspective work?

I'm working on 3D bloc following mouse move on it. I'm updating CSS values to create a 3D effect.
The Base look like:
document.addEventListener('DOMContentLoaded', function() {
let mouseMove = function (e) {
let el = e.currentTarget;
let delta_x = parseFloat(e.offsetX / el.offsetWidth).toFixed(3)
let delta_y = parseFloat(e.offsetY / el.offsetHeight).toFixed(3)
var transform = "rotateY(" + ((delta_x - 0.5) * 50) + "deg) " +
"rotateX(" + (-(delta_y - 0.5) * 50) + "deg)"
var boxShadow = parseInt(-(delta_x - 0.5) * 8) +"px " +
parseInt(-((delta_y - 0.5) * 8) + 2) +
"px 4px rgba(34, 25, 25, 0.4);"
el.setAttribute('style',
"transform: " + transform + "; " +
"box-shadow: " + boxShadow);
}
let els = document.getElementsByClassName("el")
let len = els.length
for(let i=0; i<len; i++) {
let el = els[i]
el.addEventListener("mousemove", mouseMove)
}
}, false);
html, body, #wrapper {
height: 100%;
margin: 0;
padding: 0;
}
#wrapper {
background: #a4d24b;
/*font-family: 'Open Sans', sans-serif; */
font-weight: 400;
font-size: 14px;
display: flex;
flex-wrap: wrap;
perspective: 500px;
}
.container {
position: relative;
margin: auto;
width: 20%;
height: 40%;
transition: all .25s;
transform-origin: 50% 50%;
}
.container:hover {
transform: translateZ(25px);
}
.el {
height: 100%;
background: #FFF; color: #000;
box-shadow: 0 2px 4px rgba(34, 25, 25, 0.4);
}
.el:not(:hover) {
transform: rotateY(0deg) rotateX(0deg) !important;
box-shadow: 0 2px 4px rgba(34, 25, 25, 0.4) !important;
}
<div id="wrapper">
<div class="container">
<div class="el"></div>
</div>
</div>
The JS concept is simple: When the mouse move on the bloc, I got the position (in %: position / bloc size) of the mouse on x and y.
For x (0 -> 1) I move the transform property from rotate: rotateY(-12deg) to rotate: rotateY(12deg)
Same thing for y (0 -> 1) from rotate: rotateX(-12deg) to rotate: rotateX(12deg)
I also move the box-shadow (with x and y) to help visualization.
The result look good, but if I add a background to this bloc the result look weird.
(Same code with background)
document.addEventListener('DOMContentLoaded', function() {
let mouseMove = function (e) {
let el = e.currentTarget;
let delta_x = parseFloat(e.offsetX / el.offsetWidth).toFixed(3)
let delta_y = parseFloat(e.offsetY / el.offsetHeight).toFixed(3)
var transform = "rotateY(" + ((delta_x - 0.5) * 50) + "deg) " +
"rotateX(" + (-(delta_y - 0.5) * 50) + "deg)"
var boxShadow = parseInt(-(delta_x - 0.5) * 8) +"px " +
parseInt(-((delta_y - 0.5) * 8) + 2) +
"px 4px rgba(34, 25, 25, 0.4);"
el.setAttribute('style',
"transform: " + transform + "; " +
"box-shadow: " + boxShadow);
}
let els = document.getElementsByClassName("el")
let len = els.length
for(let i=0; i<len; i++) {
let el = els[i]
el.addEventListener("mousemove", mouseMove)
}
}, false);
html, body, #wrapper {
height: 100%;
margin: 0;
padding: 0;
}
#wrapper {
background: #a4d24b;
/*font-family: 'Open Sans', sans-serif; */
font-weight: 400;
font-size: 14px;
display: flex;
flex-wrap: wrap;
perspective: 500px;
}
.container {
position: relative;
margin: auto;
width: 20%;
height: 40%;
transition: all .25s;
transform-origin: 50% 50%;
}
.container:hover {
transform: translateZ(25px);
}
.el {
height: 100%;
background: #FFF url(https://images-na.ssl-images-amazon.com/images/M/MV5BMjQyODg5Njc4N15BMl5BanBnXkFtZTgwMzExMjE3NzE#._V1_SY1000_SX686_AL_.jpg);
background-size: cover;
background-position: 50% 50%;
color: #000;
box-shadow: 0 2px 4px rgba(34, 25, 25, 0.4);
}
.el:not(:hover) {
transform: rotateY(0deg) rotateX(0deg) !important;
box-shadow: 0 2px 4px rgba(34, 25, 25, 0.4) !important;
}
<div id="wrapper">
<div class="container">
<div class="el"></div>
</div>
</div>
Now, it's look like only the top part working, and the bottom isn't moving in the good direction. (Best reproduction when the mouse is moving from top-left to bottom-right).
Did I made a mistake ? Or it's a perspective problem ?
Update Some browser didn't like the CSS bellow, if the white box didn't move when you move the mouse on it, just remove this.
.el:not(:hover) {
transform: rotateY(0deg) rotateX(0deg) !important;
box-shadow: 0 2px 4px rgba(34, 25, 25, 0.4) !important;
}
You need to have perspective applied on the immediate parent of the transformed element.
I solved using perspective: inherit
document.addEventListener('DOMContentLoaded', function() {
let mouseMove = function (e) {
let el = e.currentTarget;
let delta_x = parseFloat(e.offsetX / el.offsetWidth).toFixed(3)
let delta_y = parseFloat(e.offsetY / el.offsetHeight).toFixed(3)
var transform = "rotateY(" + ((delta_x - 0.5) * 50) + "deg) " +
"rotateX(" + (-(delta_y - 0.5) * 50) + "deg)"
var boxShadow = parseInt(-(delta_x - 0.5) * 8) +"px " +
parseInt(-((delta_y - 0.5) * 8) + 2) +
"px 4px rgba(34, 25, 25, 0.4);"
el.setAttribute('style',
"transform: " + transform + "; " +
"box-shadow: " + boxShadow);
}
let els = document.getElementsByClassName("el")
let len = els.length
for(let i=0; i<len; i++) {
let el = els[i]
el.addEventListener("mousemove", mouseMove)
}
}, false);
html, body, #wrapper {
height: 100%;
margin: 0;
padding: 0;
}
#wrapper {
background: #a4d24b;
/*font-family: 'Open Sans', sans-serif; */
font-weight: 400;
font-size: 14px;
display: flex;
flex-wrap: wrap;
perspective: 500px;
}
.container {
position: relative;
margin: auto;
width: 20%;
height: 40%;
transition: all .25s;
transform-origin: 50% 50%;
perspective: inherit;
}
.container:hover {
transform: translateZ(25px);
}
.el {
height: 100%;
background: #FFF url(https://images-na.ssl-images-amazon.com/images/M/MV5BMjQyODg5Njc4N15BMl5BanBnXkFtZTgwMzExMjE3NzE#._V1_SY1000_SX686_AL_.jpg);
background-size: cover;
background-position: 50% 50%;
color: #000;
box-shadow: 0 2px 4px rgba(34, 25, 25, 0.4);
}
.el:not(:hover) {
transform: rotateY(0deg) rotateX(0deg) !important;
box-shadow: 0 2px 4px rgba(34, 25, 25, 0.4) !important;
}
<div id="wrapper">
<div class="container">
<div class="el"></div>
</div>
</div>

css tooltip goes off screen

I'm using a pure CSS tooltip on this page: http://theroadmap.co/generation/
On small screen, hovering over some longer tooltips on right column causes tooltip to go off screen. Is there any way to get it to wrap when it reaches right end of screen?
Here is code for the tooltip:
/* TOOLTIP TIME */
.tooltip {
position: relative;
text-decoration: none;
}
.tooltip:hover:before {
display: block;
position: absolute;
padding: .5em;
content: attr(href);
min-width: 120px;
text-align: center;
width: auto;
height: auto;
white-space: nowrap;
top: -32px;
background: rgba(0,0,0,.8);
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
color: #fff;
font-size: 1.2em;
z-index: 1000;
}
.tooltip:hover:after {
position: absolute;
display: block;
content: "";
border-color: rgba(0,0,0,.8) transparent transparent;
border-style: solid;
border-width: 10px;
height: 0;
width: 0;
position: absolute;
top: -8px;
left: 1em;
}
var mousex = e.pageX + 20; //Get X coordinates
var mousey = e.pageY + 10; //Get Y coordinates
if((mousey+100)>$(window).height())
{
$('.tooltip')
.css({ top: mousey-100 ,left: mousex })
}
else if((mousex+200)>$(window).width())
{
$('.tooltip')
.css({ top: mousey ,left: mousex-200})
}
else
{
$('.tooltip')
.css({ top: mousey, left: mousex })
}
i had the same problem when i tried to display a file name. seems like the name was too long and there weren't any spaces in it, so i used
word-break: break-all;
in my .tooltip class.
this is my funtion for tooltip:
$('.file_attachments').hover(function () {
var tooltip = '<div class="tooltip"></div>';
// Hover over code
var title = $.trim($(this).attr('title'));
if (title.length > 0) {
$(this).data('tipText', title).removeAttr('title');
$('body').append(tooltip);
$('.tooltip').html(title);
$('.tooltip').fadeIn('slow');
} else {
$('body').append(tooltip);
}
}, function () {
// Hover out code
$(this).attr('title', $(this).data('tipText'));
$('.tooltip').remove();
}).mousemove(function (e) {
var mousex = e.pageX + 20; //Get X coordinates
var mousey = e.pageY + 10; //Get Y coordinates
$('.tooltip').css({top: mousey, left: mousex})
});

Google maps api highway vs road distance

I am using google maps api to calculate the rout from point A to point B.
The 'The DirectionsResult' object is giving me a lot of info regarding distance etc.
https://developers.google.com/maps/documentation/javascript/directions#DirectionsResults
However, I am interested to know what is the distance (part of the) route is on HIGHWAY roads and what part is in the CITY roads.
How can I do that?
Thanks!
There is no way using the API to differentiate between highways and non-highways.
However, you can assume the difference yourself by calculating the speed for each leg in the route.
Meta code:
// find meters per second and convert to miles per hour
mph = (route.leg[i].distance.value / route.leg[i].duration.value) * 2.23694
if mph >= 55
route.leg[i].road = highway
else
route.leg[i].road = city
Obviously this will not work if the results are taking traffic conditions into account.
example
var infowindow = new google.maps.InfoWindow();
var directions = new google.maps.DirectionsService();
var renderer = new google.maps.DirectionsRenderer({
suppressPolylines: true,
infoWindow: infowindow,
});
var map;
function initialize() {
var mapOptions = {
zoom: 13,
center: new google.maps.LatLng(40.7482333, -73.8681295),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map'), mapOptions);
google.maps.event.addDomListener(document.getElementById('go'), 'click',
route);
route();
}
function route() {
var request = {
origin: document.getElementById('from').value,
destination: document.getElementById('to').value,
travelMode: google.maps.DirectionsTravelMode.DRIVING
};
var panel = document.getElementById('panel');
panel.innerHTML = '';
directions.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
renderer.setDirections(response);
renderer.setMap(map);
renderer.setPanel(panel);
renderDirectionsPolylines(response);
console.log(renderer.getDirections());
} else {
renderer.setMap(null);
renderer.setPanel(null);
}
});
}
var polylineOptions = {
strokeColor: '#C83939',
strokeOpacity: 1,
strokeWeight: 4
};
var polylines = [];
function renderDirectionsPolylines(response) {
for (var i = 0; i < polylines.length; i++) {
polylines[i].setMap(null);
}
var legs = response.routes[0].legs;
for (i = 0; i < legs.length; i++) {
var steps = legs[i].steps;
for (j = 0; j < steps.length; j++) {
// find meters per second and convert to miles per hour
var mph = (steps[j].distance.value / steps[j].duration.value) * 2.23694
if (mph >= 55) {
// route.leg[i].road = highway
color = "#FF0000";
} else {
// route.leg[i].road = city
color = "black";
}
console.log("step " + j + " color=" + color + " mph=" + mph + " dist=" + steps[j].distance.value + " meters/time=" + steps[j].duration.value + " seconds");
var nextSegment = steps[j].path;
polylineOptions.strokeColor = color;
var stepPolyline = new google.maps.Polyline(polylineOptions);
for (k = 0; k < nextSegment.length; k++) {
stepPolyline.getPath().push(nextSegment[k]);
}
polylines.push(stepPolyline);
stepPolyline.setMap(map);
// route click listeners, different one on each step
google.maps.event.addListener(stepPolyline, 'click', (function(mph) {
return function(evt) {
infowindow.setContent("you clicked on the route<br>speed ~= " + mph.toFixed(2) + " mph<br>" + evt.latLng.toUrlValue(6));
infowindow.setPosition(evt.latLng);
infowindow.open(map);
}
}(mph)));
}
}
}
google.maps.event.addDomListener(window, 'load', initialize);
html,
body {
height: 100%;
padding: 0;
margin: 0;
color: black;
font-family: arial, sans-serif;
font-size: 13px;
}
#map {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 50%;
}
#panel-wpr {
position: absolute;
top: 0;
bottom: 0;
left: 50%;
right: 0;
overflow: auto;
}
#panel {
font-family: arial;
padding: 5px 5px;
}
#info {
padding: 5px;
}
#from,
#to {
width: 90%;
font-size: 1.2em;
}
.adp-directions {
width: 100%;
}
.input {
background-color: white;
padding-left: 8px;
border: 1px solid #D9D9D9;
border-top: 1px solid silver;
-webkit-border-radius: 1px;
-moz-border-radius: 1px;
border-radius: 1px;
}
.time {
margin: 0;
height: 17px;
border: 1px solid;
border-top-color: #CCC;
border-right-color: #999;
border-left-color: #999;
border-bottom-color: #CCC;
padding: 2px 15px 1px 1px;
}
button {
border: 1px solid #3079ED;
color: white;
background-color: #4D90FE;
background-image: -webkit-gradient(linear, left top, left bottom, from(#4D90FE), to(#4787ED));
background-image: -webkit-linear-gradient(top, #4D90FE, #4787ED);
background-image: -moz-linear-gradient(top, #4D90FE, #4787ED);
background-image: -ms-linear-gradient(top, #4D90FE, #4787ED);
background-image: -o-linear-gradient(top, #4D90FE, #4787ED);
background-image: linear-gradient(top, #4D90FE, #4787ED);
filter: progid: DXImageTransform.Microsoft.gradient(startColorStr='#4d90fe', EndColorStr='#4787ed');
display: inline-block;
min-width: 54px;
text-align: center;
font-weight: bold;
padding: 0 8px;
line-height: 27px;
-webkit-border-radius: 2px;
-moz-border-radius: 2px;
border-radius: 2px;
-webkit-transition: all 0.218s;
-moz-transition: all 0.218s;
-o-transition: all 0.218s;
transition: all 0.218s;
}
#info div {
line-height: 22px;
font-size: 110%;
}
.btn {} #panel-wpr {
border-left: 1px solid #e6e6e6;
}
#info {
border-bottom: 1px solid #E6E6E6;
margin-bottom: 5px;
}
h2 {
margin: 0;
padding: 0;
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div id="map"></div>
<div id="panel-wpr">
<div id="info">
<div>
<label>from:</label>
<input id="from" value="New York, NY" />
</div>
<div>
<label>to:</label>
<input id="to" value="Philadelphia, PA" />
</div>
<div class="btn">
<button id="go">Get Directions</button>
</div>
</div>
<div id="panel"></div>
</div>

Resources