ソースを参照

********************************** *********************
调整不跟随view缩放

zhangweixin 3 年 前
コミット
7a3c43278c

+ 65 - 21
sybotan-android-graphy/src/main/java/com/sybotan/android/graphy/SGraphyItem.kt

@@ -30,7 +30,7 @@ import android.graphics.RectF
 import android.util.Log
 import com.sybotan.android.graphy.enums.SGraphyItemFlag
 import com.sybotan.android.graphy.listeners.SGraphyItemPosListener
-import com.sybotan.android.graphy.utils.MatrixTools
+import com.sybotan.android.graphy.utils.MatrixUtil
 import com.sybotan.base.extensions.toJson
 import org.jetbrains.anko.doAsync
 import java.util.*
@@ -41,7 +41,6 @@ import java.util.*
  * @author  庞利祥(sybotan@126.com)
  */
 open class SGraphyItem(parent: SGraphyItem? = null) {
-
     /**
      * 类对象
      */
@@ -52,6 +51,7 @@ open class SGraphyItem(parent: SGraphyItem? = null) {
         /** 当前焦点Item */
         private var currentFocusItem: SGraphyItem? = null
 
+
         /**
          * MotionEvent转子对象MotionEvent
          *
@@ -61,17 +61,28 @@ open class SGraphyItem(parent: SGraphyItem? = null) {
          */
         fun toChildMotionEvent(child: SGraphyItem, e: SMotionEvent): SMotionEvent {
             val ce = SMotionEvent(e)
-            ce.matrix.postTranslate(child.pos.x, child.pos.y);
-            ce.matrix.postScale(child.scale.x, child.scale.y);
-            ce.matrix.postRotate(child.rotate,0f, 0f);
+//            ce.matrix.postTranslate(child.pos.x, child.pos.y);
+//            ce.matrix.postScale(child.scale.x, child.scale.y);
+//            ce.matrix.postRotate(child.rotate,0f, 0f);
+            ce.matrix.preTranslate(child.pos.x, child.pos.y);
+            ce.matrix.preScale(child.scale.x, child.scale.y);
+            ce.matrix.preRotate(child.rotate,0f, 0f);
+
             // 不跟随缩放
             if (!child.isTransform) {
-                ce.matrix.postScale(child._inverseScale, child._inverseScale);
+                val src = kotlin.floatArrayOf(0f, 1f, 2f, 3f, 4f, 5f, 6f, 7f, 8f)
+//                ce.matrix.postScale(child._inverseScaleX, child._inverseScaleY);
+                ce.matrix.getValues(src)
+                val matrix = Matrix()
+                matrix.preTranslate(src[2], src[5])
+                matrix.preScale(child.scale.x,child.scale.y)
+                matrix.preRotate(child.rotate)
+                ce.matrix = matrix
             }
 //            se.setLocation((e.x - child.pos.x) / child.scale.x, (e.y - child.pos.y) / child.scale.y)
             val matrixMat = Matrix()
             ce.matrix.invert(matrixMat)
-            val matrixTransform = MatrixTools.matrixTransform(matrixMat, e.viewX, e.viewY)
+            val matrixTransform = MatrixUtil.matrixTransform(matrixMat, e.viewX, e.viewY)
             ce.x = matrixTransform.x
             ce.y = matrixTransform.y
             return ce
@@ -143,7 +154,8 @@ open class SGraphyItem(parent: SGraphyItem? = null) {
     /** 是否进行变形 */
    var isTransform = true;
     /** 放缩反比例 */
-    var _inverseScale = 1f;
+    var _inverseScaleX = 1f;
+    var _inverseScaleY = 1f;
     /** item标志 */
     var flags: EnumSet<SGraphyItemFlag> = EnumSet.noneOf(SGraphyItemFlag::class.java)
 
@@ -282,7 +294,7 @@ open class SGraphyItem(parent: SGraphyItem? = null) {
         val m = this.scene2itemMattrix()
         val matrix = Matrix()
         m.invert(matrix)
-       return MatrixTools.matrixTransform(matrix,x,y)
+       return MatrixUtil.matrixTransform(matrix,x,y)
     } // Function mapFromScene()
 
     /**
@@ -309,7 +321,7 @@ open class SGraphyItem(parent: SGraphyItem? = null) {
             return PointF(x, y)
         }
         val m = this.scene2itemMattrix()
-        return return MatrixTools.matrixTransform(m,x,y)
+        return return MatrixUtil.matrixTransform(m,x,y)
 //        return parent!!.mapToScene(x * scale.x + pos.x, y * scale.y + pos.y)
     } // Function mapToScene()
 
@@ -372,7 +384,9 @@ open class SGraphyItem(parent: SGraphyItem? = null) {
      */
     open fun onPaint(canvas : Canvas, rect: RectF) {
         canvas.save()
+//        val mat1 = SJsonUtil.fromJson(canvas.matrix.toJson(), Matrix::class.java)
         this.onDraw(canvas)
+//        canvas.matrix = mat1
         canvas.restore()
         val src = kotlin.floatArrayOf(0f, 1f, 2f, 3f, 4f, 5f, 6f, 7f, 8f)
         for (i in 1 .. children.size) {        // 倒序依次取item列中的所有item。将所有item的边界做并交处理。
@@ -383,16 +397,28 @@ open class SGraphyItem(parent: SGraphyItem? = null) {
             try {
                 // 保存画布状态
                 canvas.save()
+//                val mat = SJsonUtil.fromJson(canvas.matrix.toJson(), Matrix::class.java)
                 // item位移到指定位置绘制
                 canvas.translate(item.pos.x, item.pos.y)
                 canvas.scale(item.scale.x,item.scale.y)
                 canvas.rotate(item.rotate)
 
                 if (!item.isTransform) {
-                    val matrix = canvas.matrix
-                    matrix.getValues(src)
-                    item._inverseScale = 1.0f/src[0]
-                    canvas.scale(item._inverseScale,item._inverseScale)
+                    canvas.matrix.getValues(src)
+                    val matrix = Matrix()
+                    matrix.preTranslate(src[2], src[5])
+                    matrix.preScale(item.scale.x,item.scale.y)
+                    matrix.preRotate(item.rotate)
+                    canvas.matrix = matrix
+//                    matrix.getValues(src)
+//                    item._inverseScaleX = 1.0f/src[0]
+//                    item._inverseScaleY = 1.0f/src[4]
+//                    canvas.scale(item._inverseScaleX,item._inverseScaleY)
+
+//                    matrix.preTranslate(src[2], src[5])
+//                    matrix.preTranslate(item.scale.x,item.scale.y)
+//                    matrix.preRotate(item.rotate)
+//                    canvas.matrix = matrix
                 }
                 // 设置绘制区域
                 // canvas.clipRect(item.boundingRect())
@@ -400,6 +426,7 @@ open class SGraphyItem(parent: SGraphyItem? = null) {
                 item.onPaint(canvas, rect)
                 // 恢复画布状态
                 canvas.restore()
+//                canvas.matrix = mat;
             } catch (e: Exception) {
                 e.printStackTrace()
             }
@@ -467,18 +494,23 @@ open class SGraphyItem(parent: SGraphyItem? = null) {
     open fun onSingleTapUp(e: SMotionEvent): Boolean {
         Log.d(TAG, "onSingleTapUp: releaseItem")
         releaseItem()
-        Log.e("手势scene",e.toJson())
         for (item in children) {
             if (!item.isVisible) {      // 如果对象不可见
+                Log.e("手势3scene",e.toJson())
                 continue
             }
             val ce = toChildMotionEvent(item, e)
+            Log.e("手势view","${scene?.view?.scale}")
+            Log.e("手势e","${e.x}, ${e.y}")
+            Log.e("手势ce","${ce.x}, ${ce.y}")
+            Log.e("手势1scene",(item.contains(ce.x, ce.y)).toString())
             if (item.contains(ce.x, ce.y)                                   // 如果点在子项目上
                     && item.onSingleTapUp(ce)) {                            // 且子项目处理了事件
+                Log.e("手势4scene",e.toJson())
                 return true
             }
         }
-
+        Log.e("手势2scene",e.toJson())
         return false
     } // Function onSingleTapUp()
 
@@ -623,15 +655,27 @@ open class SGraphyItem(parent: SGraphyItem? = null) {
      * @return 转换矩阵
      */
     fun scene2itemMattrix() : Matrix{
-        val m = Matrix()
+        var m = Matrix()
         val list = this.itemPath()
         for ( item in list) {
-            m.postTranslate(item.pos.x, item.pos.y);
-            m.postScale(item.scale.x, item.scale.y);
-            m.postRotate(item.rotate)
+//            m.postTranslate(item.pos.x, item.pos.y);
+//            m.postScale(item.scale.x, item.scale.y);
+//            m.postRotate(item.rotate)
+            m.preTranslate(item.pos.x, item.pos.y);
+            m.preScale(item.scale.x, item.scale.y);
+            m.preRotate(item.rotate)
+
             // 如果不进行变形处理,则取消 painter 的变型操作
             if (!item.isTransform){
-                m.postScale(item._inverseScale, item._inverseScale);
+//                m.postScale(item._inverseScaleX, item._inverseScaleY);
+                /****************************************** 待确认 ************************************************/
+                val src = kotlin.floatArrayOf(0f, 1f, 2f, 3f, 4f, 5f, 6f, 7f, 8f)
+                m.getValues(src)
+                val matrix = Matrix()
+                matrix.preTranslate(src[2], src[5])
+                matrix.preScale(item.scale.x,item.scale.y)
+                matrix.preRotate(item.rotate)
+                m = matrix
             }
         }
         return m

+ 11 - 7
sybotan-android-graphy/src/main/java/com/sybotan/android/graphy/SGraphyScene.kt

@@ -31,7 +31,7 @@ import com.sybotan.android.graphy.enums.SGraphyItemFlag
 import com.sybotan.android.graphy.items.SGraphyImageItem
 import com.sybotan.android.graphy.items.SGraphyLineItem
 import com.sybotan.android.graphy.items.SGraphyRectItem
-import com.sybotan.android.graphy.utils.MatrixTools
+import com.sybotan.android.graphy.utils.MatrixUtil
 import com.sybotan.base.extensions.toJson
 
 /**
@@ -186,7 +186,7 @@ open class SGraphyScene {
     fun worldRect(): RectF {
         val rect = RectF()
 
-        for (item in rootNode.children) {        // 依次取item列中的所有item。将所有item的边界做并处理。
+        for (item in rootNode.children) {        // 依次取item列中的所有item。将所有item的边界做并处理。
             rect.union(item.boundingRect().adjusted(item.pos))
         }
 
@@ -313,14 +313,18 @@ open class SGraphyScene {
         val se = SMotionEvent(e)
         se.matrix = Matrix()
         if (this.view != null ){
-            se.matrix.postTranslate(this.view!!.pos.x, this.view!!.pos.y);
-            se.matrix.postScale(this.view!!.scale, this.view!!.scale)
-            se.matrix.postRotate(this.view!!.rotate)
+//            se.matrix.postTranslate(this.view!!.pos.x, this.view!!.pos.y);
+//            se.matrix.postScale(this.view!!.scale, this.view!!.scale)
+//            se.matrix.postRotate(this.view!!.rotate)
+            se.matrix.preTranslate(this.view!!.pos.x, this.view!!.pos.y);
+            se.matrix.preScale(this.view!!.scale, this.view!!.scale)
+            se.matrix.preRotate(this.view!!.rotate)
+
         }
-        se.matrix.postConcat(item.scene2itemMattrix())
+        se.matrix.preConcat(item.scene2itemMattrix())
         val matrix = Matrix()
         se.matrix.invert(matrix)
-        val matrixTransform = MatrixTools.matrixTransform(matrix, se.viewX, se.viewY)
+        val matrixTransform = MatrixUtil.matrixTransform(matrix, se.viewX, se.viewY)
         se.x = matrixTransform.x
         se.y = matrixTransform.y
 //        val p = item.mapFromScene(e.x, e.y)

+ 44 - 15
sybotan-android-graphy/src/main/java/com/sybotan/android/graphy/SGraphyView.kt

@@ -28,11 +28,10 @@ import android.graphics.*
 import android.util.AttributeSet
 import android.util.Log
 import android.view.*
-import android.view.MotionEvent
 import com.sybotan.android.graphy.enums.SGraphyViewTouchState
 import com.sybotan.android.graphy.events.SGraphyViewMoveEvent
 import com.sybotan.android.graphy.events.SGraphyViewZoomEvent
-import com.sybotan.android.graphy.utils.MatrixTools
+import com.sybotan.android.graphy.utils.MatrixUtil
 import com.sybotan.base.extensions.toJson
 import org.greenrobot.eventbus.EventBus
 import kotlin.math.max
@@ -125,6 +124,12 @@ open class SGraphyView(context: Context, attrs: AttributeSet? = null)
         initView()
     } // init
 
+    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
+        Log.e("w",widthMeasureSpec.toString())
+        Log.e("h",heightMeasureSpec.toString())
+    }
+
     /**
      * 适配视图到视图
      */
@@ -133,12 +138,25 @@ open class SGraphyView(context: Context, attrs: AttributeSet? = null)
         if (null == scene) {
             return
         }
+//        val w = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)
+//        val h = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)
+//        this.measure(width, height)
+//        val h: Int = this.getMeasuredHeight()
+//        val w: Int = this.getMeasuredWidth()
+
+        this.post {
+            val w = width.toFloat()
+            val h = height.toFloat()
+
+            val rect = scene!!.worldRect()
+            setCenterPoint( PointF(rect.centerX(), rect.centerY()),
+                    min(w / rect.width(), h / rect.height()) * fitrate)
+//            Log.e("w",w.toString())
+//            Log.e("h",h.toString())
+//            Log.e("rect1",rect.toJson())
+//            Log.e("min",(min(w / rect.width(), h / rect.height())).toJson())
+        }
 
-        val w = width.toFloat()
-        val h = height.toFloat()
-        val rect = scene!!.worldRect()
-        setCenterPoint( PointF(rect.centerX(), rect.centerY()),
-                min(w / rect.width(), h / rect.height()) * fitrate)
     } // Function FitView()
 
     /**
@@ -549,19 +567,30 @@ open class SGraphyView(context: Context, attrs: AttributeSet? = null)
         val src1 = kotlin.floatArrayOf(0f, 1f, 2f, 3f, 4f, 5f, 6f, 7f, 8f)
         val src2 = kotlin.floatArrayOf(0f, 1f, 2f, 3f, 4f, 5f, 6f, 7f, 8f)
         val se = SMotionEvent(e)
-        se.matrix.postTranslate(pos.x,pos.y)
-        se.matrix.postScale(this.scale, this.scale);
-        se.matrix.postRotate(this.rotate)
-        se.matrix.getValues(src1)
-        Log.e("src1= ",src1.toJson())
+//        se.matrix.postTranslate(pos.x,pos.y)
+//        se.matrix.postScale(this.scale, this.scale);
+//        se.matrix.postRotate(this.rotate)
+
+        se.matrix.preTranslate(pos.x,pos.y)
+        se.matrix.preScale(this.scale, this.scale);
+        se.matrix.preRotate(this.rotate)
+
 
         val matrixMat = Matrix()
         se.matrix.invert(matrixMat)
+
+        se.matrix.getValues(src1)
+        Log.e("src1= ",src1.toJson())
         matrixMat.getValues(src2)
         Log.e("src2= ",src2.toJson())
-        val matrixTransform = MatrixTools.matrixTransform(matrixMat, e.x, e.y)
-        se.x = matrixTransform.x
-        se.y = matrixTransform.y
+
+        val mp = MatrixUtil.matrixTransform(matrixMat, e.x, e.y)
+        se.x = mp.x
+        se.y = mp.y
+//        Log.e("ex = ",e.x.toString())
+//        Log.e("ey = ",e.y.toString())
+//        Log.e("sex = ",se.x .toString())
+//        Log.e("sey = ",se.y.toString())
 //        se.setLocation((e.x - pos.x) / scale, (e.y - pos.y) / scale)
         return se
     } // Function toSceneMotionEvent()

+ 21 - 0
sybotan-android-graphy/src/main/java/com/sybotan/android/graphy/utils/MatrixUtil.kt

@@ -0,0 +1,21 @@
+package com.sybotan.android.graphy.utils
+
+import android.graphics.Matrix
+import android.graphics.PointF
+
+object MatrixUtil {
+
+    /**
+     *
+     */
+    fun matrixTransform(mat: Matrix,x : Float, y : Float ) : PointF {
+        val pointF = PointF()
+        val src = kotlin.floatArrayOf(0f, 1f, 2f, 3f, 4f, 5f, 6f, 7f, 8f)
+        mat.getValues(src)
+        pointF.x = x * src[0] + y * src[1] + src[2];
+        pointF.y = x * src[3] + y * src[4] + src[5];
+        return pointF;
+    }
+
+
+}