mapsplugin / cordova-plugin-googlemaps

Google Maps plugin for Cordova
Apache License 2.0
1.66k stars 916 forks source link

Problem with OnsenUI #199

Closed hirbod closed 10 years ago

hirbod commented 10 years ago

Dear Masashi, I spent the last weeks for testing and trying and did a lot of stuff with your great plugin. Now I faced a big problem when it comes up to the "real world".

I'm using OnsenUI (I guess it is familiar for you, it's at some point similar with Ionic, as they both rely on AngularJS and they use CSS transitions for animation)

I got everything up now, even complicated stuff like facebook-connect works fine with my server, but your plugin just stays black!

I looked at Safari remote debugging and it seems like every element get's background-color: rgba(0,0,0,0) (I know, you placed the map under the webview and in that fact it is import to make everything transparent), but in my case, I don't see nothing. Initalizing at least seems to be fine.

I made a video so maybe you got an idea whats wrong here, as you've figured out what was wrong before with Ionic.

I would appreciate any help so much!

Video with the problem: https://www.youtube.com/watch?v=5pIY38A8vCI&feature=youtu.be

As you can see at the end of the video, when I call the plugin for the second time it wouldn't even initialize again.

wf9a5m75 commented 10 years ago

Sorry I don't know the OnsenUI. Anyway, the plugin changes th webview background color as transparent. Use map.seyBackground("white")

hirbod commented 10 years ago

Did you watch the video? There is no map. It is just black. If I change to white, everything will be white, but also without a map?

http://onsenui.io/ (something very similar like Ionic)

hirbod commented 10 years ago

OnsenUI makes one weird thing. It adds follwing

directly after the sliding-menu

A div with:

background-color: black; top: 0px; left: 0px; right: 0px; bottom: 0px; position: absolute; display: block;

And its a <div style="..."></div>. Thats the reason it stays in top of the map. I guess I can fix this bug by myself, but what can I do with the transparent sliding menu? I keeps transparent, even after I added map.setBackgroundColor('white').

When I start to swipe the sliding-menu, it becomes transparent immediately and I can see all the elements. When my MapController gets called a second time, it does not reinit the map.

hirbod commented 10 years ago

This fixed at least nearly all problems:


        // this is quite dirty, but this did the trick with the black map
        $('ons-sliding-menu div:first').css('background-color', 'rgba(0,0,0,0)');

        // this is important for reinit
        if($rootScope.map) {
            $rootScope.map.remove();
            $('#map_canvas').remove();
        }

        setTimeout(function(){

            var div = document.getElementById("map_canvas");
            $('#map_canvas').css('height', $(window).height() - $('#map_canvas').offset().top);

            $rootScope.map = plugin.google.maps.Map.getMap(div);
            $rootScope.map.setBackgroundColor('white');

            //$rootScope.map.refreshLayout();

        }, 600); // and timeout for clear transitions

the problem with the menu is z-index related. I guess I need to do some dirty hacks but at least everything seems to work nearly as expected!

wf9a5m75 commented 10 years ago

Congrats.

hirbod commented 10 years ago

Maybe this Plugin could fix this kind of bugs "out of the box".. cause OnsenUI and Ionic are one of the best frameworks outthere

hirbod commented 9 years ago

Hi,

my described hack does not work anymore with the new version of OnsenUI. You need to change one line to get this work with OnsenUI 1.2.0+

//$('ons-sliding-menu div:first').css('background-color', 'rgba(0,0,0,0)');
$('.page__background').not('.page--menu-page__background').css('background-color', 'rgba(0,0,0,0)');

And remember: OnsenUI loads stuff trough AJAX / async. This plugin can handle only one Gmap-Init per page. Store all your map related stuff (when using Angular-JS on Onsen) into $rootScope and be sure to put this litte code-piece inside your controller when you init the map:

        if($rootScope.map) {

            $rootScope.map.clear();
            $rootScope.map.remove();
            //$('#map_canvas').remove();
            $('.gmap_div:not(:last)').remove();
            $rootScope.map = '';
        }

My map was initialized like this:

            $rootScope.map = plugin.google.maps.Map.getMap(mapDiv, {

Make sure you call the right .gmap_div class (don't use #id)

JcDenton86 commented 9 years ago

Hello @Hirbod, can you provide how did you manage to make it work with Onsen UI 1.2.1, cause I always get a black screen. I am using sliding-menu and the menu page has a 'map' list item. When I tap on that I open the map page where I get the black screen.

My setup is: AngularJS 1.3, Onsen UI 1.2.1, jQuery 1.11, Android Google Play Services v22

And also I used the test branch of this plugin cause is compatible with v22 of play services. I get no errors in the console log when the page is loaded.

Thank you in advance

JcDenton86 commented 9 years ago

ok.. I am showing how am I using the plugin and I get the black screen when navigating on map page.

/*The View: map.html*/
<ons-page ng-controller="mapController" modifier="mappage">
        <!--<ons-toolbar>
            <div class="left">
              <ons-toolbar-button ng-click="menu.toggle()">
                <ons-icon icon="ion-navicon" size="28px" fixed-width="false"></ons-icon>
              </ons-toolbar-button>
            </div>
          <div class="center">
            Greta
          </div>
        </ons-toolbar>-->

       <div style="width:100%;height:400px" id="map_canvas" class="gmap_div"></div>

      </ons-page>

And in the mapController.js I do the following

/*The Controller: mapController.js */
module.controller('mapController',function($scope,$rootScope,$timeout){
    $rootScope.initMap = function() {
        $('.page__background').not('.page--menu-page__background').css('background-color', 'rgba(0,0,0,0)');
        if($rootScope.map) {
            $rootScope.map.clear();
            $rootScope.map.remove();
            $('.gmap_div:not(:last)').remove();
            $rootScope.map = '';
        }
        $timeout(function(){
            var div = document.getElementById("map_canvas");
            $rootScope.map = plugin.google.maps.Map.getMap(div,{
                    'backgroundColor': '#f9f9f9',
                    'mapType': plugin.google.maps.MapTypeId.HYBRID,
                    'controls': {
                    'compass': true,
                    'myLocationButton': false,
                    'indoorPicker': false,
                    'zoom': true
                },
                    'gestures': {
                    'scroll': true,
                    'tilt': true,
                    'rotate': true
                }
            });
            $rootScope.map.setDebuggable(true);
            $rootScope.map.on(plugin.google.maps.event.MAP_READY, function(map){
                console.log('map ready!');
            });
        }, 600, false);
    } 
    ons.ready(function(){console.log('Map onsen ready');
        $rootScope.initMap();
    });
});

Any help is really appreciated.. The setup (google play services, libs, etc.) seems fine, because I get no errors but only successful messages for the initialization of the plugin and the map.

hirbod commented 9 years ago

Hi @JcDenton86,

I guess there is still one div in the dom-tree, which isn't set to transparent. Try using the inspector and check every single <div> / <any> (some of them are position absolute with width/height 100% and they won't get transparent cause this plugin cannot detect them as parent-node.

When you found it, make it transparent and it should work. There could be more reasons. If you stuck and need help, let's do a teamviewer session and I will look for it right on your desktop.

JcDenton86 commented 9 years ago

I even removed the toolbar and left only the map_canvas div on the page (updated my previous post) but still the same. Which other div you mean? On another page other than the map.html?

hirbod commented 9 years ago

You need to find your div in the inspector and bubble up every single node (parent) and check the css value for background-color.

Remember: This plugin put it's content behind the regular webview, therefore, every single node in front of it has to be transparent (even html and body) in order to make the map visible.

Actually, this plugin will do it automagically, but it can only detect parent nodes, not absolute positioned elements which will make the map invisible. As said, this is a quite bit complex topic and I've invested so much time making this plugin to work perfectly with OnsenUI - but there are so many other points which will take too much time to explain. It would be the best when I checked by my own.

Edit: just open the inspector with Chrome inspect (chrome://inspect), choose your android device and start deleting every parent node (but not the one where the map is inside. Once you removed the right element, you know where you'd stuck

JcDenton86 commented 9 years ago

Ok if you would like to check it, I am sending you a teamviewer id

hirbod commented 9 years ago

remove the pass

JcDenton86 commented 9 years ago

@Hirbod , thank you for your help. I found out at first that adding modifier="transparent" to the <ons-page> element of the map page only along with that line of js:

$('.page__background').not('.page--menu-page__background').css('background-color', 'rgba(0,0,0,0)')

eventually showed the map on the emulator as expected. Later on I removed the modifier from my page and left only the js line. I rebuild the app and it still showed the map as expected.. That's more than weird..

Though when I am installing the app on my device it doesn't show up. Again Onsen related I think.. because it shows up once or not.. but on emulator is shows up normally every time Thanks

hirbod commented 9 years ago

Seems to be a timing issue with initalizing a page and setting it to transparent. Maybe you need to delay that line

$('.page__background').not('.page--menu-page__background').css('background-color', 'rgba(0,0,0,0)')into a timeout. I really do not have any issues with my "hacks".. works damn fast and like native.

JcDenton86 commented 9 years ago

Yes when the map shows up on the device it's a native performance, but the issue is that it doesn't come up every time as it does on the emulator. Wrapping up, though, the initMap function in a timeout did the trick..and now comes up every time on the device.

hirbod commented 9 years ago

:+1:

kariscomp commented 9 years ago

I realized Onsen adds a div with a black background color just before the with the map div. I fixed this by writing a css selector that sets any div put above the page to have a transparent background. You could achieve the same using jquery.

hirbod commented 9 years ago

Yes I've also done the same as you can see below

sangariv commented 9 years ago

HI, i have used all the steps u have told above.but i am getting black background after closing sliding menu.can u pls help me to fix this.

sangariv commented 9 years ago

HI, after adding this line,on swiping the sliding-menu, it becomes transparent immediately and I can see all the elements in the page div.can u please help me. $('.pagebackground').not('.page--menu-pagebackground').css('background-color', 'rgba(0,0,0,0)')

hirbod commented 9 years ago

@sangariv , I guess you're using "reveal" animation on the slide-menu. You need to change to "push", otherwise, it won't work as expected.

<ons-sliding-menu ... ... type="reveal">

and change to

<ons-sliding-menu ... ... type="push">

By default, it is reveal, so if there is no type set, add `type="push"to your sliding menu

sangariv commented 9 years ago

yes it works .thanks a lot.

ldenoue commented 6 years ago

I had the same problem but because I forgot to include the correct CSS files in my iOS app bundle that also contained my HTML page.

onsenui.min.css onsen-css-components.min.css