Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Zoom-in is blurry in webkit-based browsers #84

Closed
adred opened this issue Mar 27, 2014 · 21 comments
Closed

Zoom-in is blurry in webkit-based browsers #84

adred opened this issue Mar 27, 2014 · 21 comments

Comments

@adred
Copy link

adred commented Mar 27, 2014

I think the title explains itself. In Firefox and IE, the issue doesn't occur.

@adred adred changed the title Zoom is blurry in webkit-based browsers Zoom-ini is blurry in webkit-based browsers Mar 27, 2014
@adred adred changed the title Zoom-ini is blurry in webkit-based browsers Zoom-in is blurry in webkit-based browsers Mar 27, 2014
@timmywil
Copy link
Owner

This can't be fixed by panzoom. It is a webkit issue

@adred
Copy link
Author

adred commented Mar 28, 2014

Weird SVGPan doesn't seem to have this issue: http://www.cyberz.org/projects/SVGPan/tiger.svg

@timmywil
Copy link
Owner

I double-checked and neither does panzoom if setting transforms on a group element in SVG.

@gornypiotr
Copy link

Hiya guys
I've been using panzoom since yesterday and am still checking with our designer if SVG is the way to handle our current task. I'd like to use panzoom to zoom on different parts of the SVG image, but in Chrome it becomes blurry, as you guys discuss here. Can I do anything about it? @timmywil you write that "setting transforms on a group element in SVG" should help, but how do I do it? Any help would be appreciated.
Here's the piece of code I use:

var $map = $('.customers-map');
if ($map.length > 0)
{
    var $panzoom = $map.find('.panzoom').panzoom();
    $panzoom.parent().on('mousewheel.focal', function (e)
    {
        e.preventDefault();
        var delta = e.delta || e.originalEvent.wheelDelta;
        var zoomOut = delta ? delta < 0 : e.originalEvent.deltaY > 0;
        $panzoom.panzoom('zoom', zoomOut, {
            increment: 0.1,
            animate: false,
            focal: e
        });
    });
}

and my html is:

<div class="customers-map">
    <div class="panzoom">
        <img src="images/customers/customers-map.svg">
    </div>
</div>

@tlimited
Copy link

Found a workaround. I flip between -webkit-perspective 1 and 0 on every panzoomzoom.

I'm doing something like this:
var flag = true;
function doThisOnEveryPanzoomzoom(){
$('#mypanzoom').css({
'-webkit-perspective': (flag?1:0)
});
flag = !flag;
}

@timmywil
Copy link
Owner

@tlimited Interesting trick. I'll look into this.

@timmywil timmywil reopened this Jun 12, 2014
@veke
Copy link

veke commented Jun 17, 2014

v1.12.4 is last working version with chrome desktop and mobile. Newer versions will work on ios safari and ios chrome only.

Workaround by tlimited will work on desktop chrome but not on mobile. I noticed that in desktop chrome when the image is blurry, if you use chrome inspector and highlight any element on page, the image become sharp again. Repaint problem? (that perpective change triggers repaint, i assume)

@gius80
Copy link

gius80 commented Jun 22, 2014

I found a trick that works also on mobile for me (chrome and native android browser).
Just put these lines in css:

.panzoom {
-webkit-backface-visibility: initial !important;
-webkit-transform-origin: 50% 50%;
}

@veke
Copy link

veke commented Jun 22, 2014

EDIT: This seems to work,
Thanks

@blerchin
Copy link

blerchin commented Jul 3, 2014

I found that the gius80's fix worked, but that it slowed down performance on tablets quite a bit.

Instead, I added a panzoom onEnd callback which zooms in ever so slightly after the user has finished their action. This seems to cause panzoom to re-render with no blurriness. I'm sure there is a better way to get to the root of the problem, but this solution seems to work on Chrome desktop and Android at least.

$el.panzoom({
    onEnd: function(){
        $el.panzoom( 'zoom', {increment: .01});
    }
});

@timmywil
Copy link
Owner

timmywil commented Jul 3, 2014

This is a catch-22. The webkit issue is explained well in this article. Panzoom is using -webkit-backface-visibility: hidden to promote the element to its own composite layer to take advantage of hardware acceleration. This has improved the performance of animations across devices. That said, webkit doesn't animate hardware-accelerated layers without blurring when any part of the animation happens to fall on a half-pixel. Panzoom can't provide a reliable, universal fix for this.

So, the question is, do we want faster animations that are sometimes blurry in webkit until webkit addresses the issue, or do we want to drop hardware acceleration?

@timmywil
Copy link
Owner

timmywil commented Jul 3, 2014

BTW, even if Panzoom doesn't force the separate layer, it will happen sometimes anyway. Webkit will automatically create separate layers under certain circumstances (e.g. animating opacity).

@veke
Copy link

veke commented Jul 3, 2014

"when any part of the animation happens to fall on a half-pixel"
Maybe the zoom level can be forced to full pixels with Math.floor or Math.ceil?

@timmywil
Copy link
Owner

timmywil commented Jul 3, 2014

It's not the zoom level. From the article, it seems the element dimensions must start out divisible by 2, which is not appropriate for Panzoom to enforce (especially on responsive pages).

@lamotora
Copy link

Fixed blurry is comment lin 821 //'backface-visibility': 'hidden',

@BrunoCaxito
Copy link

gius80 your trick works, thanks a lot.

.panzoom {
     -webkit-backface-visibility: initial !important;
     -webkit-transform-origin: 50% 50%;
 }

@jdonahue82
Copy link

I am working on a related problem where the initial rendering of a downscaled image gets extremely pixelated when panzoom is enabled. This does not occur in Firefox, but does occur in Chrome and IE. When applying the suggestion from @gius80 it renders correctly in Chrome. Still testing IE and failing at least in IE9. Thanks for bringing me one step closer!

@marcelboettcher
Copy link

@jdonahue82 does it work for you in Safari as well? No solutions works in Safari for me.

@sgrgala
Copy link

sgrgala commented Jun 17, 2015

@marcelboettcher I agree. None of the solutions are working for Safari

@henryruhs
Copy link

henryruhs commented Aug 27, 2015

According to my experience with a custom zoom (not jquery.panzoom) implementation:

Mobile Safari and Chrome get blurry once you have multiple elements using CSS transform laying over another using CSS position.

I guess this is a general issue with multiple layers that get hardware accelerated.

Maybe this is helpful for solving the problem.

@tuckerconnelly
Copy link

Found another workaround!

You can force a redraw using this code on panzoomzoom.

This is the same as backface-visibility: initial, though, super slow. So you can debounce the function by 100ms. I used lodash for this, but you can manually debounce.

Here's the code:

$('#panzoom-el').on('panzoomzoom', _.debounce( function () {
    this.style.display='none';
    this.offsetHeight;
    this.style.display='';
}, 100));

Hope this helps :)

@lock lock bot locked as resolved and limited conversation to collaborators Aug 8, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests