Addev
Addev

Reputation: 32233

Viewport fit screen width and big images

I'm trying to use a WebView for displaying a big image with the built-in multitouch and trying to avoid memory crashes.

I set the webView this way:

    setInitialScale(20);
    WebSettings settings = getSettings();
    settings.setJavaScriptEnabled(true);
    settings.setUseWideViewPort(true);
    settings.setLoadWithOverviewMode(true);
    settings.setSupportZoom(true);
    settings.setBuiltInZoomControls(true);

And then load the following code:

<head>
<meta
    name="viewport"
    content="width=device-width, user-scalable=yes"
/>

</head>
<body
    style="margin: 0; padding: 0">
    <img
        alt="image"
        src="THE_SRC_GOES_HERE"
        id="theImage"
    >
</body>

The problem is that if it loads a medium image (1600x1200 for example) it works nice and the image fits the screen width.

enter image description here

But if the image is bigger 7300x5200 in my example, it appears like zoomed in and with the zoom out disabled.

enter image description here

If you want to test the images urls are:

img1 & img2

NOTE: I'm not the owner of that images and I'm only using it for testing

Upvotes: 10

Views: 3463

Answers (5)

Darshan Rivka Whittle
Darshan Rivka Whittle

Reputation: 34031

I've actually got this working on ICS by doing something a little counter-intuitive. While others are suggesting adding style="width:100%" to the img tag, my solution is to actually add style="height:100%" instead.

This works for me on my Android 4.0+ devices, but unfortunately it starts partially zoomed in (so the image height fills the view) on my older devices.

  1. It avoids the white space problem on all devices I tested.
    • ICS shows space on initial fully-zoomed out view, but as you zoom in, it disappears exactly as you want.
    • On older devices, there is never white space below, due to the initial zoom level.
  2. The zoom is not perfect, but much better.
    • On ICS, you get exactly what you want (match the width).
    • On older devices, the zoom is significantly more manageable than what you're getting in your second example in the question.

In short, I've met your requirements on ICS and gotten you much closer to them on older devices. I'll edit my answer if I come up with anything else, but this seems worth sharing at this point, even if imperfect.

Upvotes: 3

Alexandre de Champeaux
Alexandre de Champeaux

Reputation: 1892

I'm more off a web developper, here is the code that works on android ics browser, this should work the same in a webview :

<!DOCTYPE html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="user-scalable=yes, initial-scale=1.0, width=device-width">
<style>
    html,body{
        width:100%;
        height:100%;
        margin:0;
        padding:0;
    }
    #my-image{
        width:100%;
        margin:0;
        padding:0;
    }
</style>

</head>
<body>
    <img id="my-image" src="http://gachie.blog.com/files/2011/06/tour_eiffel.jpg"/>
</body>

I tried it as well which a much biger image (http://macjacart.ca/admin/Product_Images/8UhBphVEae.jpg) and it worked smoothly.

Hope it helps!

[EDIT]

Since I have not enough room to post it in the comments, I'll put it there :

What you want is basically to cut off the bottom of the viewport as soon as your image height takes the full screen. You need some javascript to do that, and since the javascript does not have a zoom event, it's not going to require some hacks. Since android support flash, you could try this solution to get a zoom event. As soon as the zoom reach a certain level, which depends on image ratio, you update the css of your image with a height:100%, and set width to auto.

You can basically constrain width or height depending on which one is 100%. You might also want to set the height progressivelly to 100% as the user is zooming, either way you are going to see a "jump" at some point.

Take a look at this post as well, this might help you.

Upvotes: 2

Orbiting Eden
Orbiting Eden

Reputation: 1512

How about this: (retracted - still doesn't work right)

<html>
<head>
<meta
    name="viewport"
    content="width=device-width, user-scalable=yes"
/>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" type="text/javascript"></script>
</head>
<body
    style="margin: 0; padding: 0">
    <img onload="view = new Viewport(this.width, this.height)"
        alt="image"
        src="http://orbitingeden.com/orrery/textures/stars.jpg"
        id="theImage"
    >
<script>
    Viewport = function(width, height){
        var theImage = document.getElementById('theImage');
        this.width = width;
        this.height = height;
        this.set = function(){
            var metas = document.getElementsByTagName('meta');
            for(i=0; i<metas.length; i++){
                if(metas[i].name == 'viewport'){
                    metas[i].setAttribute('content','width=' + width + 
                                ', height='+ height + ', user-scalable=yes');
                    theImage.style.width = '100%';
                }
            }
        }
        this.set();
    }
    $('body').bind("gesturechange", function(event) {
        view.set();
    });

</script>
</body>
</html>

Upvotes: 2

Caroline
Caroline

Reputation: 651

Don't know the correct answer but a possible walkarround could be set the img max-width to a "non-very high value" for example 2*screen.width when the page is loaded

Upvotes: 3

ghostfly
ghostfly

Reputation: 728

I think your images still end up larger than the viewport by default. Try this

<html>
<head>
<meta
    name="viewport"
    content="width=device-width, user-scalable=yes"
/>

</head>
<body
    style="margin: 0; padding: 0">
    <img
        alt="image"
        src="http://www.deviantart.com/download/165022929/Wallpaper_2010_by_scrumen.png"
        id="theImage"
        style="width:100%"
    >
</body>
</html>

Upvotes: 4

Related Questions