2011-09-23 3 views
18

में स्केलिंग/डाउन या ड्रैगिंग के बाद कैनवास निर्देशांक प्राप्त करें मैं एक ऐसे अनुप्रयोग को विकसित कर रहा हूं जिसमें मैं छवियों को चिपका रहा हूं, ड्राइंग और कैनवास पर पेंटिंग कर रहा हूं। यह ऐप कैनवास को ऊपर/नीचे स्केल कर सकता है या इसे विभिन्न स्थान पर खींच सकता है। मेरी समस्या यह है: कैनवास को स्केल करने या खींचने के बाद मुझे सही कैनवास निर्देशांक नहीं मिल सकते हैं। मैं उंगली रंग आकर्षित करने के लिए के बाद कैनवास माप लिया जाता है या घसीटा लेकिन सही जगह है जहाँ मैं छुआ गया है प्राप्त करने में असमर्थ चाहते .. :( इसके अलावा, मैं नए मधुमक्खी हूँ। यहाँ कोड है।एंड्रॉइड

@Override 
public void onDraw(Canvas canvas) { 
    super.onDraw(canvas); 

    canvas.save(); 
    //canvas.translate(mPosX, mPosY); 
    canvas.scale(mScaleFactor, mScaleFactor, super.getWidth() * 0.5f, 
      super.getHeight() * 0.5f); 
    mIcon.draw(canvas); 
    for (Path path : listPath) { 
     canvas.drawPath(path, paint); 
    } 
    canvas.restore(); 
} 

public TouchExampleView(Context context, AttributeSet attrs, int defStyle) { 
    super(context, attrs, defStyle); 

} 

@Override 
public boolean onTouchEvent(MotionEvent ev) { 
    // Let the ScaleGestureDetector inspect all events. 
    mScaleDetector.onTouchEvent(ev); 

    final int action = ev.getAction(); 
    switch (action & MotionEvent.ACTION_MASK) { 
    case MotionEvent.ACTION_DOWN: { 
     final float x = ev.getX(); 
     final float y = ev.getY(); 

     mLastTouchX = x; 
     mLastTouchY = y; 
     mActivePointerId = ev.getPointerId(0); 
     break; 
    } 

    case MotionEvent.ACTION_MOVE: { 
     final int pointerIndex = ev.findPointerIndex(mActivePointerId); 
     final float x = ev.getX(pointerIndex); 
     final float y = ev.getY(pointerIndex); 

     // Only move if the ScaleGestureDetector isn't processing a gesture. 
     if (!mScaleDetector.isInProgress()) { 
      final float dx = x - mLastTouchX; 
      final float dy = y - mLastTouchY; 

      mPosX += dx; 
      mPosY += dy; 

      invalidate(); 
     } 

     mLastTouchX = x; 
     mLastTouchY = y; 

     break; 
    } 

    case MotionEvent.ACTION_UP: { 
     mActivePointerId = INVALID_POINTER_ID; 
     break; 
    } 

    case MotionEvent.ACTION_CANCEL: { 
     mActivePointerId = INVALID_POINTER_ID; 
     break; 
    } 

    case MotionEvent.ACTION_POINTER_UP: { 
     final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; 
     final int pointerId = ev.getPointerId(pointerIndex); 
     if (pointerId == mActivePointerId) { 
      // This was our active pointer going up. Choose a new 
      // active pointer and adjust accordingly. 
      final int newPointerIndex = pointerIndex == 0 ? 1 : 0; 
      mLastTouchX = ev.getX(newPointerIndex); 
      mLastTouchY = ev.getY(newPointerIndex); 
      mActivePointerId = ev.getPointerId(newPointerIndex); 
     } 
     break; 
    } 
    } 

    float objectNewX,objectNewY; 
    if (mScaleFactor >= 1) { 
     objectNewX = ev.getX() + (ev.getX() - super.getWidth() * 0.5f) * (mScaleFactor - 1); 
     objectNewY = ev.getY() + (ev.getY() - super.getHeight() * 0.5f) * (mScaleFactor - 1); 
    } else { 
     objectNewX = ev.getX() - (ev.getX() - super.getWidth() * 0.5f) * (1 - mScaleFactor); 
     objectNewY = ev.getY() - (ev.getY() - super.getHeight() * 0.5f) * (1 - mScaleFactor); 
    } 

    if (ev.getAction() == MotionEvent.ACTION_DOWN) { 
     path = new Path(); 
     path.moveTo(objectNewX,objectNewY); 
     path.lineTo(objectNewX,objectNewY); 
    } else if (ev.getAction() == MotionEvent.ACTION_MOVE) { 
     path.lineTo(objectNewX,objectNewY); 
     listPath.add(path); 
    } else if (ev.getAction() == MotionEvent.ACTION_UP) { 
     path.lineTo(objectNewX,objectNewY); 
     listPath.add(path); 
    } 

    return true; 
} 

private class ScaleListener extends 
     ScaleGestureDetector.SimpleOnScaleGestureListener { 
    @Override 
    public boolean onScale(ScaleGestureDetector detector) { 
     mScaleFactor *= detector.getScaleFactor(); 

     // Don't let the object get too small or too large. 
     mScaleFactor = Math.max(0.1f, Math.min(mScaleFactor, 5.0f)); 

     invalidate(); 
     return true; 
    } 
} 
+0

* मुझे सही कैनवास निर्देशांक प्राप्त नहीं हो सकता *। आपको और अधिक विशिष्ट होना चाहिए। क्या पैमाने ही काम करता है? परिभाषित करें कि आप सही कैनवास निर्देशांक * के रूप में क्या उम्मीद करते हैं? अभी उनके साथ क्या गलत है? – Knickedi

+0

छवि को ज़ूम करने का प्रयास करें और फिर कैनवास पर कुछ पेंट करें .. फिर आपको पता चल जाएगा। –

+0

भी असम्बद्ध कैनवास.ट्रांसलेट (एमपीओएसएक्स, एमपीओएसवाई); –

उत्तर

19

सम्पन्न । यह अंत में अपने आप से

को यह सूत्र लागू करके सब कुछ ड्रा (px, py) निर्देशांक:

float px = ev.getX()/mScaleFactor + rect.left; 
float py = ev.getY()/mScaleFactor + rect.top; 
rect = canvas.getClipBounds(); 
//Get them in on Draw function and apply above formula before drawing 
+0

अरे आवेस मैं भी वही चीज़ पर फंस गया हूं। मुझे आपके समाधान को ठीक से समझ में नहीं आया क्या आप कृपया अपना कोड साझा कर सकते हैं या मुझे इसके साथ मदद कर सकते हैं? – user1169079

+0

आपकी समस्या कहां है ??? मेरे मामले में, जहां मुझे स्क्रीन पर कुछ आकर्षित करना है, मैंने फ्लोट x = ev.getX()/mScaleFactor + rect.left; event.getX() के बजाय एक्स के लिए; इसी तरह वाई अक्ष के लिए। रेक्ट तैयार कैनवास के क्लिपबाउंड है। हमें इसे कुछ आयताकार चर में सहेजना है। वे लगातार ड्रा फंक्शन में अपडेट कर रहे हैं। –

+0

http://stackoverflow.com/questions/9989170/clickable-area-after-scaling-with-respect-to-positions-of-touch-event .. अगर आप इसे मदद कर सकते हैं तो यह जांचें ... – user1169079

7
@Override 
protected void onDraw(Canvas canvas) { 
    super.onDraw(canvas); 
    clipBounds_canvas = canvas.getClipBounds(); 
    /////Do whatever you want to do..!!!    
}; 

@Override 
public boolean onTouchEvent(MotionEvent ev) { 
    int x = ev.getX()/zoomFactor + clipBounds_canvas.left; 
    int y = ev.getY()/zoomFactor + clipBounds_canvas.top; 
    //Use the above two values insted of ev.getX() and ev.getY(); 
} 

आशा इस में मदद मिलेगी

+0

उपर्युक्त दो मान x और y ऑफसेट हैं जहां मेरा हिट क्षेत्र/क्लिक होगा? या मुझे उपरोक्त एक्स और वाई मान का उपयोग करके मेरी ड्रा ऑब्जेक्ट्स को अपडेट करने की आवश्यकता है? – user1169079

+0

आपको ऊपर वर्णित रिश्तेदार एक्स और वाई के अनुसार अनुमानित ड्रा ऑब्जेक्ट्स को अपडेट करने की आवश्यकता है। –

+0

धन्यवाद दोस्त !!! मुझे पता चला है कि मेरी वस्तु कहां चल रही है .. लेकिन मैं क्लिक करने योग्य क्षेत्र को उसी स्थिति में कैसे स्थानांतरित नहीं करता हूं जिस पर मैं काम कर रहा हूं .. अगर आपके पास कोई सुझाव है तो !!! मैंने getHitRect को आजमाया और इसे ऑफ़सेट जोड़ दिया? कामकाजी काम !!! – user1169079