Ending a svg path drawing in FabricJs using right mouse click - onclick

I am using fabric JS version 4.5.0 working on a draw application.
I want to use the right mouse click to end the brush drawing but cannot achieve this.
please take a look at this codepen snippet (credits to michaelsboost) I am doing something similar to it.
if (tool.toString().toLowerCase() === 'pencil') {
changeObjectSelection(false);
canvas.freeDrawingBrush = new fabric.PencilBrush(canvas);
canvas.freeDrawingBrush.strokeLineCap = $('#brushStrokeCap').val(); // butt / round / square
canvas.freeDrawingBrush.strokeLineJoin = $('#brushStrokeLineJoin').val(); // bevel / round / miter
canvas.freeDrawingBrush.strokeMiterLimit = $('#brushMiter').val();
canvas.freeDrawingBrush.width = 1;
canvas.freeDrawingBrush.color = strokePickr.getColor().toRGBA().toString();
canvas.isDrawingMode = true;
}
what changes need to be added there to use left mouse click and right mouse click interchangebly to end a svg path drawing?
currently, if you select the pencil tool, clicked using your left mouse button it starts the drawing.
If you right clicked it opens a menu, select copy image, and move your mouse.
Undesired behaviour: try to left click, the whole drawing disappears.
Desired behaviour: right mouse click should end the drawing as a svg on canvas.

// Get a reference to the canvas element
var canvas = new fabric.Canvas('canvas');
canvas.isDrawingMode = true;
// Add a rectangle to the canvas
var rect = new fabric.Rect({
left: 100,
top: 100,
fill: 'green',
width: 100,
height: 100
});
canvas.add(rect);
document.onclick = hideMenu;
document.oncontextmenu = rightClick;
function hideMenu() {
document.getElementById("contextMenu").style.display = "none"
}
function rightClick(e) {
e.preventDefault();
var menu = document.getElementById("contextMenu")
menu.style.display = 'block';
menu.style.left = e.pageX + "px";
menu.style.top = e.pageY + "px";
}
.context-menu {
position: absolute;
text-align: center;
background: lightgray;
border: 1px solid black;
}
.context-menu ul {
padding: 0px;
margin: 0px;
min-width: 150px;
list-style: none;
}
.context-menu ul li {
padding-bottom: 7px;
padding-top: 7px;
border: 1px solid black;
}
.context-menu ul li a {
text-decoration: none;
color: black;
}
.context-menu ul li:hover {
background: darkgray;
}
<canvas id="canvas" width="1920px" height="1080px"></canvas>
<div id="contextMenu" class="context-menu" style="display:none">
<ul>
<li onclick="canvas.isDrawingMode = true">Drawing mode true</li>
<li onclick="canvas.isDrawingMode = false">Drawing mode false</li>
</ul>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/4.5.0/fabric.min.js"></script>

Related

How to create dynamic custom style on mat -dialog on each mat-table row with top triangle in Angular - Material

Here is my sample code.
Please find my working sample code here
I need to set triangle on right top corner in mat-dialog box - Angular.
I am getting top right corner triangle dialog box using static css on last row.
But here not able to get on each row on change request button click.
The below code is for the Dialog box Component
openDialog(Id, Currency, Amount, Reason, StatusDescription, payment, event) {
let targetAttr = event.target.getBoundingClientRect();
const dialogConfig = new MatDialogConfig();
dialogConfig.disableClose = true;
dialogConfig.autoFocus = true;
dialogConfig.data = {
Id: Id,
Reason: Reason,
StatusDescription: StatusDescription
};
dialogConfig.position = {
top: targetAttr.y + targetAttr.height + 10 + "px",
left: targetAttr.x - targetAttr.width - 20 + "px"
};
dialogConfig.panelClass = ['my-panel','arrow-top'];
const dialogRef = this.dialog.open(EditingDialogComponent, dialogConfig);
dialogRef.afterClosed().subscribe(
data => {
console.log("Dialog output:", data)
}
);
}
The Below code is from style.scss
/* Add application styles & imports to this file! */
#import "~#angular/material/prebuilt-themes/indigo-pink.css";
.my-panel {
overflow: hidden !important;
border-radius: 5px !important;
padding: 0px !important;
color: #fff;
}
.my-panel.arrow-top {
margin-top: 40px;
}
.my-panel.arrow-top:after {
content: " ";
position: absolute;
right: 100px;
top: 365px;
border-top: none;
border-right: 15px solid transparent;
border-left: 15px solid transparent;
border-bottom: 15px solid gray;
}
I am getting like this.
But I want dialog box with upper arrow on each row under change request button click event

Zooming in overflow: scroll

I am trying to implement correctly scaling and zooming in css way. I created an example with scaled view. When click, the view should be zoomed and then to be able to scroll.
https://jsfiddle.net/opb5tcy8/4/
I have several issues with it:
Can I somehow get rid of the margin-left and margin-top on the .zoomed class? I did not manage to scale it without necessity to shift it with these margins.
When clicked, I can get the click position by clientX. I would like to use it to fluently scroll to the clicked position during zooming. However I can't manage the scroll to be fluent and when removing the margin-left it is kind of jumpy and not nice.
When you zoom in and move the scroll to the center and then zoom out, you can see the zoom is not nice as it first scrolls to the right. Is there a way to prevent it?
When you scroll to corners in Chrome on OSX it tends do navigate back/forward in browser. Is there a way to prevent this behaviour?
UPDATE:
The first part can be solved with transform-origin: 0 0. The other issues stays mostly the same as it is demonstrated.
Hm... I could say it is impossible to satisfy point 2 your condition with current browsers' support. The other are possible, as in this demo:
$(document).ready(function() {
var windowHalfWidth = $("#window").width() / 2;
var scalingFactor = 0.55;
var throtte = false;
$("#slider").click(function(event) {
//Simple event throtte to prevent click spamming breaking stuff up
if (throtte) return false;
throtte = true;
setTimeout(function() {
throtte = false;
}, 1000);
var xSelf = event.pageX - $("#window").offset().left + $("#window").scrollLeft();
if ($(this).hasClass("zoomed")) {
$("#window").animate({
scrollLeft: (xSelf / scalingFactor - windowHalfWidth)
}, 1000, "linear");
} else {
$("#window").animate({
scrollLeft: (xSelf * scalingFactor - windowHalfWidth)
}, 1000, "linear");
}
$("#slider").toggleClass("zoomed");
});
});
body {
background-color: #eee;
margin-top: 10px; /*reduced margin for easier view in SO */
}
#window {
width: 500px;
height: 200px;
margin: 0 auto;
overflow-x: auto;
overflow-y: hidden;
border: 1px solid #999;
position: relative;
background-color: white;
}
#slider {
width: 900px;
height: 600px;
background-color: #fff;
position: absolute;
transition: 1s linear;
top: 0;
left: 0;
transform-origin: 0 0;
}
#slider.zoomed {
transform: scale(0.55);
}
#slider div {
width: 50px;
height: 50px;
line-height: 50px;
position: absolute;
top: 75px;
background-color: #eee;
text-align: center;
}
#obj1 {
left: 10px;
}
#obj2 {
left: 210px;
}
#obj3 {
left: 410px;
}
#obj4 {
left: 610px;
}
#obj5 {
left: 810px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="window">
<div id="slider" class="zoomed">
<div id="obj1">1</div>
<div id="obj2">2</div>
<div id="obj3">3</div>
<div id="obj4">4</div>
<div id="obj5">5</div>
</div>
</div>
As you can see, the zooming & scrolling is quite laggy, especially when the far right size is zoomed in.
The reason is simple, because jQuery and css both have their own animation loop, and they are not in sync. In order to solve this we'll need to somehow manage to do both scrolling & scaling animations with only one system, either jQuery or CSS.
Problem is: jQuery don't have a scaling feature, and css can't scroll elements. Wonderful.
If your scaling can be done with width/height though, it would be possible, using jquery width&height animate(). But if the #slider consists of many components I guess it can't be done.
So um writing an answer just to say it's impossible is kind of a let down, so I think maybe I can suggest an alternative, using dragging to scroll content (similar to the way Google map work):
var windowHalfWidth, startX, startLeft, minLeft, dragging = false,
zooming = false;
var zoomElement = function(event) {
var xSelf = event.pageX - $("#window").offset().left - parseFloat($("#slider").css("left"));
if ($("#slider").hasClass("zoomed")) {
minLeft = windowHalfWidth * 2 - 900;
var newLeft = Math.min(Math.max((-(xSelf / 0.55 - windowHalfWidth)), minLeft), 0);
$("#slider").css("left", newLeft + "px");
} else {
minLeft = windowHalfWidth * 2 - 900 * 0.55;
var newLeft = Math.min(Math.max((-(xSelf * 0.55 - windowHalfWidth)), minLeft), 0);
$("#slider").css("left", newLeft + "px");
}
$("#slider").toggleClass("zoomed");
}
$(document).ready(function() {
windowHalfWidth = $("#window").width() / 2;
minLeft = windowHalfWidth * 2 - 900 * 0.55;
$("#slider").on({
mousedown: function(event) {
dragging = true;
startX = event.pageX;
startLeft = parseFloat($(this).css("left"));
},
mousemove: function(event) {
if (dragging && !zooming) {
var newLeft = Math.min(Math.max((startLeft + event.pageX - startX), minLeft), 0);
$("#slider").css("left", newLeft + "px");
}
},
mouseup: function(event) {
dragging = false;
if (Math.abs(startX - event.pageX) < 30 && !zooming) {
// Simple event throtte to prevent click spamming
zooming = true;
$("#slider").css("transition", "1s");
setTimeout(function() {
zooming = false;
$("#slider").css("transition", "initial");
}, 1000);
zoomElement(event);
}
},
mouseleave: function() {
dragging = false;
}
});
});
body {
background-color: #eee;
margin-top: 10px; /*reduced margin for easier view in SO */
}
#window {
width: 500px;
height: 200px;
margin: 0 auto;
overflow: hidden;
border: 1px solid #999;
position: relative;
background-color: white;
}
#slider {
width: 900px;
height: 600px;
background-color: #fff;
position: absolute;
top: 0;
left: 0;
transform-origin: 0 0;
}
#slider.zoomed {
transform: scale(0.55);
}
#slider div {
width: 50px;
height: 50px;
line-height: 50px;
position: absolute;
top: 75px;
background-color: #eee;
text-align: center;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
#obj1 {
left: 10px;
}
#obj2 {
left: 210px;
}
#obj3 {
left: 410px;
}
#obj4 {
left: 610px;
}
#obj5 {
left: 810px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="window">
<div id="slider" class="zoomed">
<div id="obj1">1</div>
<div id="obj2">2</div>
<div id="obj3">3</div>
<div id="obj4">4</div>
<div id="obj5">5</div>
</div>
</div>
This variation manages to get CSS to do both animation, by sacrificing the scrollbar (which is pretty ugly imo, who needs it?) and use css left instead.
So I hope if in the end you can't find a good solution, at least you have this to consider as fall back version.
I'll address the points individually and then give an example at the end.
When clicked, I can get the click position by clientX. I would like to
use it to fluently scroll to the clicked position during zooming.
In my opinion scroll animations during transitions can be a bit choppy in webkit browsers. Try balancing the animation time of the jQuery effect with the animation time of the css transition.
When you zoom in and move the scroll to the centre and then zoom out, you can see the zoom is not nice as it first scrolls to the right. Is there a way to prevent it?
Bring the scrollLeft property of the div#window back to 0px. Again, tweaking the animation times will make this less jerky.
When you scroll to corners in Chrome on OSX it tends do navigate back/forward in browser. Is there a way to prevent this behaviour?
You could use the mouseover and mouseout events to toggle a overflow:hidden css on the body.
Here's an example change to your code:
var slider = $("#slider").on('click', function(event) {
if (!slider.hasClass('zoomed')) {
// zoom back to left position
$('#window').animate({scrollLeft:'0px'});
}else{
// zoom to click position within slider
$('#window').animate({scrollLeft:event.clientX + 'px'}, 2000);
}
slider.toggleClass("zoomed");
});
/* stop window scrolling when using slider */
slider
.on('mouseover', function () {
$(document.body).css({overflow:'hidden'});
})
.on('mouseout', function () {
$(document.body).css({overflow:'auto'});
});
And an updated fiddle.

How to style dropdown buttons using Zurb Foundation 5?

I am using Zurb Foundation 5 with Sass mixins and I want to change the style of the dropdown arrow. I am pretty confident that it lies somewhere inside of here but I'm not sure what it is:
// Dropdown Buttons
// $include-html-button-classes: $include-html-classes;
// We use these to set the color of the pip in dropdown buttons
// $dropdown-button-pip-color: #fff;
// $dropdown-button-pip-color-alt: #333;
// $button-pip-tny: rem-calc(6);
// $button-pip-sml: rem-calc(7);
// $button-pip-med: rem-calc(9);
// $button-pip-lrg: rem-calc(11);
// We use these to style tiny dropdown buttons
// $dropdown-button-padding-tny: $button-pip-tny * 7;
// $dropdown-button-pip-size-tny: $button-pip-tny;
// $dropdown-button-pip-opposite-tny: $button-pip-tny * 3;
// $dropdown-button-pip-top-tny: -$button-pip-tny / 2 + rem-calc(1);
// We use these to style small dropdown buttons
// $dropdown-button-padding-sml: $button-pip-sml * 7;
// $dropdown-button-pip-size-sml: $button-pip-sml;
// $dropdown-button-pip-opposite-sml: $button-pip-sml * 3;
// $dropdown-button-pip-top-sml: -$button-pip-sml / 2 + rem-calc(1);
// We use these to style medium dropdown buttons
// $dropdown-button-padding-med: $button-pip-med * 6 + rem-calc(3);
// $dropdown-button-pip-size-med: $button-pip-med - rem-calc(3);
// $dropdown-button-pip-opposite-med: $button-pip-med * 2.5;
// $dropdown-button-pip-top-med: -$button-pip-med / 2 + rem-calc(2);
// We use these to style large dropdown buttons
// $dropdown-button-padding-lrg: $button-pip-lrg * 5 + rem-calc(3);
// $dropdown-button-pip-size-lrg: $button-pip-lrg - rem-calc(6);
// $dropdown-button-pip-opposite-lrg: $button-pip-lrg * 2.5;
// $dropdown-button-pip-top-lrg: -$button-pip-lrg / 2 + rem-calc(3);
Here is what I have:
And I want the dropdown arrow to look more like this:
How can I achieve this? Thanks in advance!
===== EDIT =====
With this scss:
.dropdown.button:before{
width: 15px;
height: 15px;
border: none;
background: url("../images/dropdown.png") no-repeat;
}
And this html:
fake#emailaddress.com<br>
<ul id="drop" data-dropdown-content class="f-dropdown">
The button looks like this:
How do I move the arrow now?
Updated jsfiddle:http://jsfiddle.net/Y4jDW/
There is no default arrow фы in your example, but you can overwrite Foundation's styles. Simply add these styles:
.dropdown.button:before{
width: 10px; //width of your arrow
height: 10px; //height of your arrow
border: none;
background: url(...) no-repeat; //url for image
}
You can find the class in css/foundation.css line:1261
This is the original code :
.top-bar-section .has-dropdown > a:after {
content: "";
display: block;
width: 0;
height: 0;
border: inset 5px;
border-color: rgba(168, 168, 168, 1) transparent transparent transparent;
border-top-style: solid;
margin-top: -2.5px;
top: 22.5px; }
You can try this :
.top-bar-section .has-dropdown > a:after {
content: "";
display: block;
width: 10px;
height: 10px;
border: none;
background-image: url(img/arrow.png) no-repeat;
margin-top: -2.5px;
top: 22.5px; }
Good luck !

Animate LI into div

I jave just created a Twitter widget for my website and I want to fade in and out the last 5 or more tweets at set intervals using css3 I have set my div to be 60% width with a height of 90px same as my UL and LI as shown below...
div#twitterwidget {
width: 60%;
margin-right: auto;
margin-bottom: 5px;
margin-left: auto;
height: 90px;
font-family: Tahoma, Geneva, sans-serif;
font-size: 16px;
color: #EC9A20;
font-weight: bold;
text-shadow:0 1px 0 rgba(0,0,0,0.5)
}
div#twitterwidget ul {
list-style:none;
height:90px;
overflow:hidden
}
div#twitterwidget ul li {
height:90px
}
All I want to achieve is is load up the the next tweet from the bottom using css3 animations!
Many thanks for your help
Phillip Dews
As Requested here is my HTML
<div id="twitterwidget"><script src="js/twitterWidget.js"></script>
<script>
twitterFetcher.fetch('347858782015086592', '', 5, true, false, true, '', false, handleTweets);
function handleTweets(tweets){
var x = tweets.length;
var n = 0;
var element = document.getElementById('twitterwidget');
var html = '<ul>';
while(n < x) {
html += '<li>' + tweets[n] + '</li>';
n++;
}
html += '</ul>';
element.innerHTML = html;
}
</script>
</div>
In that case, I think it would be far easier to use javascript (here with jQuery) to animate your widget. I am not sure of you exaclty want, but this is the idea :
function animateWidget() {
li = $('div#twitterwidget>ul>li:first');
li.slideUp(1000, function(){
li.clone().appendTo('div#twitterwidget>ul').show();
li.remove();
});
}
$(document).ready(function(){
setInterval(animateWidget,1000);
});
What is done here is :
run the animation every 1s
animate the first tweet with slideUp
when the animation is done, put the tweet in the end of the list
See the updated Fiddle

Styling Google Maps InfoWindow

I've been attempting to style my Google Maps InfoWindow, but the documentation is very limited on this topic. How do you style an InfoWindow?
Google wrote some code to assist with this. Here are some examples: Example using InfoBubble, Styled markers and Info Window Custom (using OverlayView).
The code in the links above take different routes to achieve similar results. The gist of it is that it is not easy to style InfoWindows directly, and it might be easier to use the additional InfoBubble class instead of InfoWindow, or to override GOverlay. Another option would be to modify the elements of the InfoWindow using javascript (or jQuery), like later ATOzTOA suggested.
Possibly the simplest of these examples is using InfoBubble instead of InfoWindow. InfoBubble is available by importing this file (which you should host yourself): http://google-maps-utility-library-v3.googlecode.com/svn/trunk/infobubble/src/infobubble.js
InfoBubble's Github project page.
InfoBubble is very stylable, compared to InfoWindow:
infoBubble = new InfoBubble({
map: map,
content: '<div class="mylabel">The label</div>',
position: new google.maps.LatLng(-32.0, 149.0),
shadowStyle: 1,
padding: 0,
backgroundColor: 'rgb(57,57,57)',
borderRadius: 5,
arrowSize: 10,
borderWidth: 1,
borderColor: '#2c2c2c',
disableAutoPan: true,
hideCloseButton: true,
arrowPosition: 30,
backgroundClassName: 'transparent',
arrowStyle: 2
});
infoBubble.open();
You can also call it with a given map and marker to open on:
infoBubble.open(map, marker);
As another example, the Info Window Custom example extends the GOverlay class from the Google Maps API and uses this as a base for creating a more flexible info window. It first creates the class:
/* An InfoBox is like an info window, but it displays
* under the marker, opens quicker, and has flexible styling.
* #param {GLatLng} latlng Point to place bar at
* #param {Map} map The map on which to display this InfoBox.
* #param {Object} opts Passes configuration options - content,
* offsetVertical, offsetHorizontal, className, height, width
*/
function InfoBox(opts) {
google.maps.OverlayView.call(this);
this.latlng_ = opts.latlng;
this.map_ = opts.map;
this.offsetVertical_ = -195;
this.offsetHorizontal_ = 0;
this.height_ = 165;
this.width_ = 266;
var me = this;
this.boundsChangedListener_ =
google.maps.event.addListener(this.map_, "bounds_changed", function() {
return me.panMap.apply(me);
});
// Once the properties of this OverlayView are initialized, set its map so
// that we can display it. This will trigger calls to panes_changed and
// draw.
this.setMap(this.map_);
}
after which it proceeds to override GOverlay:
InfoBox.prototype = new google.maps.OverlayView();
You should then override the methods you need: createElement, draw, remove and panMap. It gets rather involved, but in theory you are just drawing a div on the map yourself now, instead of using a normal Info Window.
You can modify the whole InfoWindow using jquery alone...
var popup = new google.maps.InfoWindow({
content:'<p id="hook">Hello World!</p>'
});
Here the <p> element will act as a hook into the actual InfoWindow. Once the domready fires, the element will become active and accessible using javascript/jquery, like $('#hook').parent().parent().parent().parent().
The below code just sets a 2 pixel border around the InfoWindow.
google.maps.event.addListener(popup, 'domready', function() {
var l = $('#hook').parent().parent().parent().siblings();
for (var i = 0; i < l.length; i++) {
if($(l[i]).css('z-index') == 'auto') {
$(l[i]).css('border-radius', '16px 16px 16px 16px');
$(l[i]).css('border', '2px solid red');
}
}
});
You can do anything like setting a new CSS class or just adding a new element.
Play around with the elements to get what you need...
I used the following code to apply some external CSS:
boxText = document.createElement("html");
boxText.innerHTML = "<head><link rel='stylesheet' href='style.css'/></head><body>[some html]<body>";
infowindow.setContent(boxText);
infowindow.open(map, marker);
google.maps.event.addListener(infowindow, 'domready', function() {
// Reference to the DIV that wraps the bottom of infowindow
var iwOuter = $('.gm-style-iw');
/* Since this div is in a position prior to .gm-div style-iw.
* We use jQuery and create a iwBackground variable,
* and took advantage of the existing reference .gm-style-iw for the previous div with .prev().
*/
var iwBackground = iwOuter.prev();
// Removes background shadow DIV
iwBackground.children(':nth-child(2)').css({'display' : 'none'});
// Removes white background DIV
iwBackground.children(':nth-child(4)').css({'display' : 'none'});
// Moves the infowindow 115px to the right.
iwOuter.parent().parent().css({left: '115px'});
// Moves the shadow of the arrow 76px to the left margin.
iwBackground.children(':nth-child(1)').attr('style', function(i,s){ return s + 'left: 76px !important;'});
// Moves the arrow 76px to the left margin.
iwBackground.children(':nth-child(3)').attr('style', function(i,s){ return s + 'left: 76px !important;'});
// Changes the desired tail shadow color.
iwBackground.children(':nth-child(3)').find('div').children().css({'box-shadow': 'rgba(72, 181, 233, 0.6) 0px 1px 6px', 'z-index' : '1'});
// Reference to the div that groups the close button elements.
var iwCloseBtn = iwOuter.next();
// Apply the desired effect to the close button
iwCloseBtn.css({opacity: '1', right: '38px', top: '3px', border: '7px solid #48b5e9', 'border-radius': '13px', 'box-shadow': '0 0 5px #3990B9'});
// If the content of infowindow not exceed the set maximum height, then the gradient is removed.
if($('.iw-content').height() < 140){
$('.iw-bottom-gradient').css({display: 'none'});
}
// The API automatically applies 0.7 opacity to the button after the mouseout event. This function reverses this event to the desired value.
iwCloseBtn.mouseout(function(){
$(this).css({opacity: '1'});
});
});
//CSS put in stylesheet
.gm-style-iw {
background-color: rgb(237, 28, 36);
border: 1px solid rgba(72, 181, 233, 0.6);
border-radius: 10px;
box-shadow: 0 1px 6px rgba(178, 178, 178, 0.6);
color: rgb(255, 255, 255) !important;
font-family: gothambook;
text-align: center;
top: 15px !important;
width: 150px !important;
}
I have design google map infowindow with image & some content as per below.
map_script (Just for infowindow html reference)
for (i = 0; i < locations.length; i++) {
var latlng = new google.maps.LatLng(locations[i][1], locations[i][2]);
marker = new google.maps.Marker({
position: latlng,
map: map,
icon: "<?php echo plugins_url( 'assets/img/map-pin.png', ELEMENTOR_ES__FILE__ ); ?>"
});
var property_img = locations[i][6],
title = locations[i][0],
price = locations[i][3],
bedrooms = locations[i][4],
type = locations[i][5],
listed_on = locations[i][7],
prop_url = locations[i][8];
content = "<div class='map_info_wrapper'><a href="+prop_url+"><div class='img_wrapper'><img src="+property_img+"></div>"+
"<div class='property_content_wrap'>"+
"<div class='property_title'>"+
"<span>"+title+"</span>"+
"</div>"+
"<div class='property_price'>"+
"<span>"+price+"</span>"+
"</div>"+
"<div class='property_bed_type'>"+
"<span>"+bedrooms+"</span>"+
"<ul><li>"+type+"</li></ul>"+
"</div>"+
"<div class='property_listed_date'>"+
"<span>Listed on "+listed_on+"</span>"+
"</div>"+
"</div></a></div>";
google.maps.event.addListener(marker, 'click', (function(marker, content, i) {
return function() {
infowindow.setContent(content);
infowindow.open(map, marker);
}
})(marker, content, i));
}
Most important thing is CSS
#propertymap .gm-style-iw{
box-shadow:none;
color:#515151;
font-family: "Georgia", "Open Sans", Sans-serif;
text-align: center;
width: 100% !important;
border-radius: 0;
left: 0 !important;
top: 20px !important;
}
#propertymap .gm-style > div > div > div > div > div > div > div {
background: none!important;
}
.gm-style > div > div > div > div > div > div > div:nth-child(2) {
box-shadow: none!important;
}
#propertymap .gm-style-iw > div > div{
background: #FFF!important;
}
#propertymap .gm-style-iw a{
text-decoration: none;
}
#propertymap .gm-style-iw > div{
width: 245px !important
}
#propertymap .gm-style-iw .img_wrapper {
height: 150px;
overflow: hidden;
width: 100%;
text-align: center;
margin: 0px auto;
}
#propertymap .gm-style-iw .img_wrapper > img {
width: 100%;
height:auto;
}
#propertymap .gm-style-iw .property_content_wrap {
padding: 0px 20px;
}
#propertymap .gm-style-iw .property_title{
min-height: auto;
}
Use the InfoBox plugin from the Google Maps Utility Library. It makes styling/managing map pop-ups much easier.
Note that you'll need to make sure it loads after the google maps API:
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_KEY&callback=initMap" async defer></script>
<script src="/js/infobox_packed.js" async defer></script>
Map InfoWindow supports html and css.
I usually create html string with css class. So I can attach any style I want to.
var contentString = '<div>Any Html here</div>';
marker.infowindow = new google.maps.InfoWindow({
content: contentString,
});
Here is the ref.
You could use a css class too.
$('#hook').parent().parent().parent().siblings().addClass("class_name");
Good day!

Resources