I am struggling since 2 days with something I was thinking easy, on a map, I have to display a marker for each user with the user FB profile picture inside.
I am wondering how I can have a result similar to this one? What I tried was really hackish.
I put the FB picture as the marker icon
I put a CSS class on the label of the marker
I find the sibling to add this border and this arrow to decorate the user picture
but it doesn't work when there is more than one marker on the map.
.marker-labels {
display: none !important;
+ div {
background-color: $dark-gray;
border: 2px solid $dark-gray;
#include radius(0.2em);
height: 54px !important;
width: 54px !important;
overflow: inherit !important;
> img {
height: 50px;
width: 50px;
}
&:after {
content: ' ';
height: 0;
width: 0;
border: 6px solid transparent;
border-top-color: $dark-gray;
position: absolute;
top: 52px;
left: 19px;
}
}
}
global question:
how can I get an icon like that (http://mt-st.rfclipart.com/image/thumbnail/24-1d-5f/blue-glossy-square-map-pin-or-speech-bubble-Download-Royalty-free-Vector-File-EPS-29153.jpg for instance) with a custom user picture inside? is it possible?
otherwise how is it possible to customize the icon (if it is the profile picture) to have a result similar to the screenshot
thanks for your help
This answer assumes you already have the URIs for the facebook profile images. Honestly, it feels there is an easier way, but I found some code that shows how to create a custom marker with custom HTML elements and I went from there. From there's it's pretty easy to create a custom marker that accepts a image URI as a parameter. From the original, I just added an imageSrc parameter, moved the styling outside the code by attaching a class name to the new div. In terms of html and css, I just appended an image with the passed image URI into the div, and just added some CSS to make it look like what you have.
Demo
So the javascript code looks something like this:
function CustomMarker(latlng, map, imageSrc) {
this.latlng_ = latlng;
this.imageSrc = imageSrc; //added imageSrc
this.setMap(map);
}
CustomMarker.prototype = new google.maps.OverlayView();
CustomMarker.prototype.draw = function () {
// Check if the div has been created.
var div = this.div_;
if (!div) {
// Create a overlay text DIV
div = this.div_ = document.createElement('div');
// Create the DIV representing our CustomMarker
div.className = "customMarker" //replaced styles with className
var img = document.createElement("img");
img.src = this.imageSrc; //attach passed image uri
div.appendChild(img);
google.maps.event.addDomListener(div, "click", function (event) {
google.maps.event.trigger(me, "click");
});
// Then add the overlay to the DOM
var panes = this.getPanes();
panes.overlayImage.appendChild(div);
}
// Position the overlay
var point = this.getProjection().fromLatLngToDivPixel(this.latlng_);
if (point) {
div.style.left = point.x + 'px';
div.style.top = point.y + 'px';
}
};
CustomMarker.prototype.remove = function () {
// Check if the overlay was on the map and needs to be removed.
if (this.div_) {
this.div_.parentNode.removeChild(this.div_);
this.div_ = null;
}
};
CustomMarker.prototype.getPosition = function () {
return this.latlng_;
};
I think I added only one or two lines here. You can just add this to your page I think. With this in place you can just style the container as normal, and it should apply to all the custom markers. You can add elements and classes as you see fit to achieve the look you are looking for. But for completion's sake I added the styles I used for the demo here.
.customMarker { /* the marker div */
position:absolute;
cursor:pointer;
background:#424242;
width:100px;
height:100px;
/* we'll offset the div so that
the point passed doesn't end up at
the upper left corner but at the bottom
middle. so we'll move it left by width/2 and
up by height+arrow-height */
margin-left:-50px;
margin-top:-110px;
border-radius:10px;
padding:0px;
}
.customMarker:after { //triangle
content:"";
position: absolute;
bottom: -10px;
left: 40px;
border-width: 10px 10px 0;
border-style: solid;
border-color: #424242 transparent;
display: block;
width: 0;
}
.customMarker img { //profile image
width:90px;
height:90px;
margin:5px;
border-radius:2px;
}
And for the demo I have some sample data in array and placed them on the map using a for loop.
var data = [{
profileImage: "http://domain.com/image1.jpg",
pos: [37.77, -122.41],
}, {
profileImage: "http://domain.com/image2.jpg",
pos: [37.77, -122.41],
}]
for(var i=0;i<data.length;i++){
new CustomMarker(
new google.maps.LatLng(data[i].pos[0],data[i].pos[1]),
map,
data[i].profileImage
)
}
I hope that helps.
Related
I'm relatively new to this and trying to create a pop-up. I'm not sure how to get the pop-up to be in the middle of the page and still populate the box correctly, since it ends up being inside the table. I tried setting a position in the CSS but that didn't work. Maybe I did it wrong?
PHP
foreach ($updateInfo['updates'] as $update) {
echo "<table><tr><td>";
if (isset($update['details']['newsDetails']['fldDatePosted'])) {
echo '<a class="news_popper">'.$update['details']['newsDetails']['fldDatePosted'].'</a><div class="news_pop"><p>'.$update['details']['newsDetails']['fldBody'].'</p></div>';
}
echo "</td></tr></table>";
}
CSS
.news_pop {
display:none;
position: absolute;
z-index: 99999;
padding: 10px;
background: #ffffff;
border: 1px solid #A2ADBC;
}
JS
$(function() {
$('a.news_popper').click(function() {
$(this).next(".news_pop").toggle();
});
});
I would suggest coding a popup in a more object oriented approach, that way you can call it whenever you need it throughout the page, and you can have multiple instances if needed. What I would do is create a constructor for the popup and a div that manages the pop ups.
First the pop up manager:
const popUpManager = (function popUpManager() {
const $popUpManager = document.createElement('div');
$popUpManager.className = "pop-up_manager";
document.body.append($popUpManager);
return {
createPopUp: () => {
const popup = new Popup();
const $popup = popup.getPopup();
$popUpManager.append($popup);
return popup;
}
}
})();
We create a div called pop-up_manager that will house your popup and allow you to place it where ever you need throughout the page.
Then we need to create the blueprint for what a popup is:
class Popup{
constructor() {
this.$popup = document.createElement('div');
this.$popup.className = 'pop-up';
this.$popup.innerHTML = '<div class="exit-button">X</div><div class="body"></div>';
this.$exitButton = this.$popup.querySelector('.exit-button');
this.$body = this.$popup.querySelector('.body');
this.setUpListeners();
}
getPopup() {
return this.$popup;
}
setContent($content) {
if (typeof $content === 'string') {
this.$body.innerHTML = $content;
} else {
this.$body.appendChild($content);
}
}
Every time we call new Popup(); we will generate a div that floats over the page that we can set to house anything we want by passing content to the setContent() method. This will create what is in the pop up.
Finally, the styling can be configured to whatever you want in the css:
.pop-up {
position: fixed;
height: 300px;
width: 300px;
background-color: grey;
/* Positioning */
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.body {
height: 100%;
width: 100%;
}
.exit-button {
cursor: pointer;
}
To call the popup from anywhere in you JS all you have to do is:
$('a.news_popper').click(function() {
const popup = popUpManager.createPopUp();
popup.setContent('<h1>INSERT CONTENT TO SHOW USER HERE</h1>');
});
Here is a codepen: CodePen Link
I just want to ask. I want to make the product image thumbnail in shopify disappear when I scrolled down to bottom of the page, and I want a bit of transition with it.. I really can't figure out how to do this..
Here's my code..
https://jsfiddle.net/vsLdz4qb/1/
function myFunction(screenWidth) {
if (screenWidth.matches) { // If media query matches
window.onscroll = function(ev) {
if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
document.getElementByClass("product-single__thumbnails").style.transition = "0.65s";
document.getElementByClass("product-single__thumbnails").style.opacity = 0;
}
};
}
}
let screenWidth = window.matchMedia("(min-width: 750px)");
myFunction(screenWidth); // Call listener function at run time
screenWidth.addListener(myFunction)
Thank you so much in advance!
The correct document method is document.getElementsByClassName and since it returns an array you need the first element of it so change this:
document.getElementByClass("product-single__thumbnails").style.transition = "0.65s";
document.getElementByClass("product-single__thumbnails").style.opacity = 0;
to:
document.getElementsByClassName("product-single__thumbnails")[0].style.transition = "0.65s";
document.getElementsByClassName("product-single__thumbnails")[0].style.opacity = 0;
You can read more about the method here
You should use getElementsByClassName in place of getElementByClass(This is not correct function)
and this will return an array like structure so you need to pass 0 index, if only one class available on page.
or you can try querySelector(".product-single__thumbnails");
and for transition, you can define that in your .product-single__thumbnails class like: transition: opacity .65s linear; - use here which property, you want to animate.
<!-- [product-image] this is for product image scroll down disappear -->
function myFunction(screenWidth) {
if (screenWidth.matches) { // If media query matches
window.onscroll = function(ev) {
if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
document.getElementsByClassName("product-single__thumbnails")[0].style.opacity = 0;
}
};
}
}
let screenWidth = window.matchMedia("(min-width: 350px)");
myFunction(screenWidth); // Call listener function at run time
screenWidth.addListener(myFunction)
body {
margin:0;
height: 1000px;
}
.product-single__thumbnails {
background-color: red;
color: white;
width: 50px;
height: 50px;
position: fixed;
transition: opacity .65s linear;
border-radius: 4px;
margin: 20px;
text-align: center;
}
<div class="product-single__thumbnails">
<p>red</p>
</div>
As you can see here : http://www.shadownet.com.mv/products-2/
The first container sticks on top when scrolled vertically from the container. It should end and the second container "SHADOW SERVER SERIES" should stick on top replacing the first one (bringing the first one to the original position) when it is scrolled vertically from the container.
Right now i use this JS code to make the first one stick but when i use it for the second one, it sticks both on top and doesn't give the intended results :
var menu = document.querySelector('#sticky')
var menuPosition = menu.getBoundingClientRect().top;
window.addEventListener('scroll', function() {
if (window.pageYOffset >= menuPosition) {
menu.style.position = 'fixed';
menu.style.top = '42px';
menu.style.width = '100%';
} else {
menu.style.position = 'static';
menu.style.top = '';
}
});
I apologize for my bad english, im not a native speaker.
If you can use CSS, I would use the menuPosition as state in CSS.
So first the JS function would control state:
var menu = document.querySelector('#sticky'),
menuPosition = menu.getBoundingClientRect().top;
window.addEventListener('scroll', function() {
if (window.pageYOffset >= menuPosition){
document.body.classList.add('scrolled');
} else {
document.body.classList.remove('scrolled');
}
});
I've used classList which has a polyfill.
As Obsidian Age pointed out, move the variable menuPosition inside the event controller when it's CSS is dynamic from the top.
Then in CSS, use the body state to control offset for both containers:
#sticky { display: none; position: static; top: 48px; /*...*/ }
#sticky + #sticky2 { display: none; position: static; width: 100%;/*...*/ }
.scrolled #sticky { display: block; position: fixed; }
.scrolled #sticky + #sticky2 { display: block; position: fixed; }
The + in CSS only works if both containers are direct children of the same parent.
For this particular one,
I used stickyJS which worked wonderfully and out of the box. I was using a wordpress website. I added the script to header.php and added the JS snippet on desired page, set IDs for the two containers and gave z-index so that they go above each other when in view.
I am new to Javascript but I was able to piece together something to create a random background image on page load. This was successfully used for a Div object on the page.
Since this worked well, I wanted to use this command again for a second Div object on the same page. Both Divs had separate CSS style names so I thought this would be fine. However as soon as I use both commands together, only one will work.
I assumed it was an overloading problem, but I tried renaming everything I could and it still hasn't solved it. Is there something else I need to rename that I'm missing or do I need to frame the two separate commands differently?
Below is the JS code, CSS and HTML:
Thanks in advance!
/*! random background image 2*/
window.onload = function frontimage() {
var thediv2 = document.getElementById("topimg");
var imgarray2 = new Array("f1.svg", "f2.svg");
var spot2 = Math.floor(Math.random()* imgarray2.length);
thediv2.style.background = "url(img/f-img/"+imgarray2[spot2]+")";
thediv2.style.backgroundSize = "70%";
thediv2.style.backgroundAttachment = "fixed";
thediv2.style.backgroundRepeat = "no-repeat";
thediv2.style.zIndex = "2";
thediv2.style.backgroundColor = "rgba(255,204,255,0.5)";
}
/*! random background image 1*/
window.onload = function backimage() {
var thediv = document.getElementById("imgmain");
var imgarray = new Array("b1.jpg", "b2.jpg", "b3.jpg", "b4.jpg", "b5.jpg");
var spot = Math.floor(Math.random()* imgarray.length);
thediv.style.background = "url(img/b-img/"+imgarray[spot]+")";
thediv.style.backgroundSize = "100%";
thediv.style.backgroundAttachment = "fixed";
thediv.style.backgroundRepeat = "no-repeat";
thediv.style.zIndex = "1";
}
#bigimg {
clear: both;
float: left;
margin-left: 0;
width: 100%;
display: block;
}
#imgmain {
background: 50% 0 no-repeat fixed;
z-index: 1;
width: 100%;
}
#topimg {
z-index: 2;
position: absolute;
background-image: url(../img/f-img/f2.svg);
background-repeat: no-repeat;
background-position: 50% -25%;
background-size:contain;
width: 100%;
margin: auto;
padding: 0;
}
<div id="bigimg">
<section id="imgmain"></section>
<section id="topimg"></section>
</div>
With addEventListener, you can add as many event handlers as you want.
window.addEventListener('load', function frontimage() {
// ...
});
window.addEventListener('load', function backimage() {
// ...
});
You are overriding your first window.onload by reassigning the callback function.
Try this:
window.onload = function() {
frontimage();
backimage();
}
I would to create a menu with the following appearance:
I have managed to create the background color using css and the rounded corners as well.
I am now attempting to add the top arrow.
How can I add an element to the menu itself (the arrow), and shift its original open position?
You can modify the renderTpl of the menu to include the triangle at the top. I would recommend creating a class which extends Ext.menu.Menu. See this example.
Ext.define('Ext.menu.TriangleMenu', {
extend: 'Ext.menu.Menu',
initComponent: function () {
//get the original template
var originalTpl = Ext.XTemplate.getTpl(this, 'renderTpl');
//add the triangle div (or img, span, etc.)
this.renderTpl = new Ext.XTemplate([
'<div class="menu-triangle"></div>',
originalTpl.html, //the html from the original tpl
originalTpl.initialConfig //the config options from the original tpl
]);
this.callParent();
},
beforeSetPosition: function () {
//shift the menu down from its original position
var pos = this.callParent(arguments);
if (pos) {
pos.y += 5; //the offset (should be the height of your triangle)
}
return pos;
}
});
How you render the triangle is entirely up to you. You can do it without having to use an image by using this neat little border trick.
.menu-triangle {
height: 0;
width: 0;
border-bottom: 5px solid black;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
}