Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7791077
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 1, 20262026-06-01T21:46:33+00:00 2026-06-01T21:46:33+00:00

I’ve got this canvas which the user can add images/text etc to. If the

  • 0

I’ve got this canvas which the user can add images/text etc to. If the user drags one of the items to either side of the canvas, it should expand if needed. I googled, but couldn’t find any reasonable solution. Also, the canvas is about 90% of the screen width, and 70% of the height.. I’m not asking for an entire solution.. I just need a tip on how to do this (Links, docs, whatever)

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-01T21:46:35+00:00Added an answer on June 1, 2026 at 9:46 pm

    Well, it’s difficult to guess what you’re trying to achieve. When you say “it should expand if needed”, what do you mean? Expand to fill the parent view? Expand to it’s intrinsic size?

    Here’s some (incomplete) code I use in a custom view class. Most of it is gleaned from multiple solutions on here and I give thanks to the original authors. The onDraw is the most interesting one. When you want to draw (where it says custom drawing here), you don’t need to worry about translation or scaling as the canvas itself is translated and scaled. In other words, your x and y co-ords are relative to the view size – simply multiply them by scale.

    public class LightsViewer extends ImageView {
    
    private float scale;
    
    // minimum and maximum zoom
    private float MIN_ZOOM = 1f;
    private float MAX_ZOOM = 5f;
    
    // mid point between fingers to centre scale
    private PointF mid = new PointF();
    
    private float scaleFactor = 1.f;
    private ScaleGestureDetector detector;
    
    // drag/zoom mode
    private final static int NONE = 0;
    
    // current mode
    private int mode ;
    
    private float startX = 0f;
    private float startY = 0f;
    
    private float translateX = 0f;
    private float translateY = 0f;
    
    private float previousTranslateX = 0f;
    private float previousTranslateY = 0f;
    
    public LightsViewer(Context context) {
    
        super(context);
        detector = new ScaleGestureDetector(getContext(), new ScaleListener());
    
        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        Display display = wm.getDefaultDisplay();
    
        displayWidth = display.getWidth();
        displayHeight = display.getHeight();
    
    }
    
    
    public LightsViewer(Context context, AttributeSet attrs) {
    
        super(context,attrs);
        detector = new ScaleGestureDetector(getContext(), new ScaleListener());
    
        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        Display display = wm.getDefaultDisplay();
    
        displayWidth = display.getWidth();
        displayHeight = display.getHeight();
    
    }
    
    @Override
    public boolean onTouchEvent(MotionEvent event) {
    
        int ZOOM = 2;
        int DRAG = 1;
    
        if (!allowZooming){return true;}
    
        switch (event.getAction() & MotionEvent.ACTION_MASK) {
    
            case MotionEvent.ACTION_DOWN:
    
                mode = DRAG;
    
                //We assign the current X and Y coordinate of the finger to startX and startY minus the previously translated
                //amount for each coordinates This works even when we are translating the first time because the initial
                //values for these two variables is zero.
                startX = event.getX() - previousTranslateX;
                startY = event.getY() - previousTranslateY;
    
                break;
    
            case MotionEvent.ACTION_MOVE:
    
                if (mode == ZOOM){
                    Log.d("LIGHTS","ACTION_MOVE:Move but ZOOM, breaking");
                    break;}
    
                translateX = event.getX() - startX;
                translateY = event.getY() - startY;
    
                //We cannot use startX and startY directly because we have adjusted their values using the previous translation values.
                //This is why we need to add those values to startX and startY so that we can get the actual coordinates of the finger.
                double distance = Math.sqrt(Math.pow(event.getX() - (startX + previousTranslateX), 2) +
                        Math.pow(event.getY() - (startY + previousTranslateY), 2)
                );
    
                if(distance > 0) {
                    dragged = true;
                }
    
                break;
    
            case MotionEvent.ACTION_POINTER_DOWN:
    
                midPoint(mid, event);
    
                mode = ZOOM;
    
                break;
    
            case MotionEvent.ACTION_UP:
    
                mode = NONE;
                dragged = false;
    
                //All fingers went up, so let's save the value of translateX and translateY into previousTranslateX and
                //previousTranslate
                previousTranslateX = translateX;
                previousTranslateY = translateY;
    
                break;
    
            case MotionEvent.ACTION_POINTER_UP:
    
                mode = NONE;
    
                //This is not strictly necessary; we save the value of translateX and translateY into previousTranslateX
                //and previousTranslateY when the second finger goes up
                previousTranslateX = translateX;
                previousTranslateY = translateY;
    
                break;
        }
    
        detector.onTouchEvent(event);
    
        //We redraw the canvas only in the following cases:
        //
        // o The mode is ZOOM
        //        OR
        // o The mode is DRAG and the scale factor is not equal to 1 (meaning we have zoomed) and dragged is
        //   set to true (meaning the finger has actually moved)
        if ((mode == DRAG && scaleFactor != 1f && dragged) || mode == ZOOM) {            
            this.invalidate();
        }
    
        return true;
    }
    
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    
        if (this.getImageMatrix().isIdentity()){return;}
    
        if (allowZooming){
            this.applyMatrix(this.getImageMatrix());
        }
    
    }
    
    @Override
    public void onDraw(Canvas canvas) {
    
        canvas.save();
    
        // scale the canvas
        canvas.scale(scaleFactor, scaleFactor, mid.x, mid.y);
    
        canvas.translate(translateX / scaleFactor, translateY / scaleFactor);
    
        super.onDraw(canvas);
    
        // do custom drawing here...e.g.
        canvas.drawCircle(100,100, 3 / scaleFactor,light.paint);
    
    
        canvas.restore();
    }
    
    private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
        @Override
        public boolean onScale(ScaleGestureDetector detector) {
            scaleFactor *= detector.getScaleFactor();
            scaleFactor = Math.max(MIN_ZOOM, Math.min(scaleFactor, MAX_ZOOM));
            return true;
        }
    }
    
    // calculate the mid point of the first two fingers
    private void midPoint(PointF point, MotionEvent event) {
        // ...
        float x = event.getX(0) + event.getX(1);
        float y = event.getY(0) + event.getY(1);
        point.set(x / 2, y / 2);
    
        Log.d("LIGHTS", x/2 + "," + y/2);
    
    }
    
    public void setMinZoom(float minZoom){
        this.MIN_ZOOM = minZoom;
    }
    
    public void applyMatrix(Matrix matrix){
    
        float[] matrixValues = new float[9];
        matrix.getValues(matrixValues);
    
        int x = (int)matrixValues[Matrix.MTRANS_X];
        int y = (int)matrixValues[Matrix.MTRANS_Y];
        float scale = matrixValues[Matrix.MSCALE_X];
    
        if (lights!=null){
            for (Light light:lights){
                light.setX((int)((light.originalX * scale) + x));
                light.setY((int)((light.originalY * scale) + y));
            }
        }
    
        // if either the x or y translations are less than 0, then the image has been cropped
        // so set the min zoom to the ratio of the displayed size and the actual size of the image
        if (matrixValues[Matrix.MTRANS_X] < 0 || matrixValues[Matrix.MTRANS_Y] <0){
            MIN_ZOOM = displayWidth / this.getDrawable().getIntrinsicWidth();
        }else{
            MIN_ZOOM = 1;
        }
    
    }
    
    public void enableZooming(boolean enable){
        allowZooming = enable;
    }
    
    public void setScale(float scale){
    
        for (Light light:lights){
            light.setX((int)(light.originalX * scale));
            light.setY((int)(light.originalY * scale));
        }
    }
    

    }

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

For some reason, after submitting a string like this Jack’s Spindle from a text
I have a string like this: La Torre Eiffel paragonata all&#8217;Everest What PHP function
I'm parsing an RSS feed that has an &#8217; in it. SimpleXML turns this
I have a text area in my form which accepts all possible characters from
Does anyone know how can I replace this 2 symbol below from the string
link Im having trouble converting the html entites into html characters, (&# 8217;) i
I am trying to understand how to use SyndicationItem to display feed which is
I used javascript for loading a picture on my website depending on which small
I have a jquery bug and I've been looking for hours now, I can't
I've got a string that has curly quotes in it. I'd like to replace

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.