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

Better image rotation on Javascript #2631

Closed
jsfan3 opened this issue Dec 3, 2018 · 8 comments
Closed

Better image rotation on Javascript #2631

jsfan3 opened this issue Dec 3, 2018 · 8 comments
Assignees
Milestone

Comments

@jsfan3
Copy link
Contributor

jsfan3 commented Dec 3, 2018

A code similar to the following, produces a strange rotation in Javascript, because the image is not only rotated, but also slightly moved during the moving (test with Chrome on Android and on iOS):

    timer = UITimer.timer(100, true, Display.getInstance().getCurrent(), () -> {
                Image icon = button.getIcon();
                Image rotated = button.rotate(-30);
                button.setIcon(rotated);
            }); 
@codenameone codenameone added this to the Version 6.0 milestone Dec 3, 2018
@shannah
Copy link
Collaborator

shannah commented Dec 3, 2018

Can you fill out your test case to reproduce it? I have the following and it seems to work ok. Rotation is identical in both js and simulator.

checked-64-ltgrey

private void testRotateImage() {
        Form f = new Form("Rotated image", new BorderLayout());
        try {
            Label l = new Label(Image.createImage(Display.getInstance().getResourceAsStream(null, "/Checked-64-ltgrey.png")));
            f.add(BorderLayout.CENTER, l);
            f.addShowListener(e->{
                UITimer timer = UITimer.timer(100, true,f, () -> {
                    Image icon = l.getIcon();
                    Image rotated = icon.rotate(-30);
                    l.setIcon(rotated);
                }); 
            });
            
        } catch (Throwable t) {
            Log.e(t);
        }
        f.show();
            
    }

@jsfan3
Copy link
Contributor Author

jsfan3 commented Dec 4, 2018

Full example code:

Main class:

Form hi = new Form("Hi World", BoxLayout.y());
        hi.add(new Label("Hi World"));
        Button button = new WaitingButton("Tap me");
        button.addActionListener(l -> {
            Log.p("Waiting Button pressed");
            UITimer.timer(2000, false, () -> {
                button.setEnabled(true);
            });
        });
        hi.add(button);
        hi.show();

WaitingButton.java

import com.codename1.ui.Button;
import com.codename1.ui.Display;
import com.codename1.ui.FontImage;
import com.codename1.ui.Image;
import com.codename1.ui.plaf.UIManager;
import com.codename1.ui.util.UITimer;

/**
 * A WaitingButton is a Button that shows a waiting icon and disable itself when
 * tapped; it stops showing the waiting icon when setEnabled(true) is called.
 *
 */
public class WaitingButton extends Button {

    private UITimer timer;
    
    public WaitingButton(String text) {
        this(text, "Button");
    }

    public WaitingButton(String text, String style) {
        super(text, style);
        super.addActionListener(l -> {
            super.setTextPosition(Button.LEFT);
            super.setIcon(FontImage.createMaterial(FontImage.MATERIAL_LOOP, UIManager.getInstance().getComponentStyle(style)).toImage());
            super.setEnabled(false);
            timer = UITimer.timer(100, true, Display.getInstance().getCurrent(), () -> {
                Image icon = super.getIcon();
                Image rotated = icon.rotate(-30);
                super.setIcon(rotated);
            }); 
        });
    }

    @Override
    public void setEnabled(boolean enabled) {
        if (enabled) {
            super.setIcon(null);
            if (timer != null) {
                timer.cancel();
            }
        }
        super.setEnabled(enabled);
    }

}

Result of the web-app installed on the iPhone home (the rotating arrows slightly moves up and down during the rotation, this thing doesn't happen on the native apps):
https://www.informatica-libera.net/docLavoro/rotation.mp4

@shannah
Copy link
Collaborator

shannah commented Dec 4, 2018

This is specific to font images and is related to calculating font widths, heights, and ascents which has been particularly tricky. It is closely related to the following issues:

#2527
#2540

Unfortunately the techniques that I am using for font size calculations are still approximate - and this is exposed when you are rotating an image of a glyph where you assume that the glyph is centered in the image, but, in fact, may not be exactly centered.

The current state of font sizing and alignment is at a "local maximum" state. It yields "pretty good" results across all browsers for the test cases in #2527 and #2540. I have taken a few stabs at improving things, but have not yet been able to improve on it. I have been able to resolve this particular issue at times, but at the expense of making other cases worse.

Anyways, that's the state of things. I'm going to attempt to deal with material fonts as a special case to see if I can improve this particular issue without negatively impacting the others.

@codenameone
Copy link
Collaborator

Can we provide a hint about this as a temporary workaround?
That way the rotate method of font image can rasterize the image by default when rotating in the JavaScript port. Would that work?

@shannah
Copy link
Collaborator

shannah commented Dec 4, 2018

That's the sort of thing I'm going to attempt. The tricky part is the rasterization step. Making sure that the glyph is rendered exactly in the center of the image, when the font width/height calculations aren't 100% accurate.

@shannah
Copy link
Collaborator

shannah commented Dec 4, 2018

I feel dirty. I put in a special case for font size calculation and rendering of the material design font. This appears to fix the issue in my tests. So far I've tested Chrome, Firefox, Safari on Mac (both retina and non-retina), Chrome on Android, Safari iOS, Chrome/Edge/Firefox on Windows 10.

This will be included in the next update on Friday.

@shannah shannah closed this as completed Dec 4, 2018
@jsfan3
Copy link
Contributor Author

jsfan3 commented Dec 4, 2018

Thank you!

@jsfan3
Copy link
Contributor Author

jsfan3 commented Dec 7, 2018

I've just tested the new image rotation (with the same code): it's a lot better!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants