我正在使用 Making Sense of Multitouch 中的代码示例
用于缩放 ImageView 。在 ScaleListener 上,我添加了 ScaleGestureDetector.getFocusX() 和 getFocusY() 用于缩放手势焦点的内容。它工作正常。
问题是,在第一次多点触控时,整个图像绘制位置正在更改为当前触摸点并从那里缩放。你能帮我解决这个问题吗?
这是我的 TouchImageView 代码示例。
public class TouchImageViewSample extends ImageView {
private Paint borderPaint = null;
private Paint backgroundPaint = null;
private float mPosX = 0f;
private float mPosY = 0f;
private float mLastTouchX;
private float mLastTouchY;
private static final int INVALID_POINTER_ID = -1;
private static final String LOG_TAG = "TouchImageView";
// The ‘active pointer’ is the one currently moving our object.
private int mActivePointerId = INVALID_POINTER_ID;
public TouchImageViewSample(Context context) {
this(context, null, 0);
}
public TouchImageViewSample(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
private ScaleGestureDetector mScaleDetector;
private float mScaleFactor = 1.f;
// Existing code ...
public TouchImageViewSample(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// Create our ScaleGestureDetector
mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
borderPaint = new Paint();
borderPaint.setARGB(255, 255, 128, 0);
borderPaint.setStyle(Paint.Style.STROKE);
borderPaint.setStrokeWidth(4);
backgroundPaint = new Paint();
backgroundPaint.setARGB(32, 255, 255, 255);
backgroundPaint.setStyle(Paint.Style.FILL);
}
@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;
}
}
return true;
}
/*
* (non-Javadoc)
*
* @see android.view.View#draw(android.graphics.Canvas)
*/
@Override
public void draw(Canvas canvas) {
super.draw(canvas);
canvas.drawRect(0, 0, getWidth() - 1, getHeight() - 1, borderPaint);
}
@Override
public void onDraw(Canvas canvas) {
canvas.drawRect(0, 0, getWidth() - 1, getHeight() - 1, backgroundPaint);
if (this.getDrawable() != null) {
canvas.save();
canvas.translate(mPosX, mPosY);
Matrix matrix = new Matrix();
matrix.postScale(mScaleFactor, mScaleFactor, pivotPointX,
pivotPointY);
// canvas.setMatrix(matrix);
canvas.drawBitmap(
((BitmapDrawable) this.getDrawable()).getBitmap(), matrix,
null);
// this.getDrawable().draw(canvas);
canvas.restore();
}
}
/*
* (non-Javadoc)
*
* @see
* android.widget.ImageView#setImageDrawable(android.graphics.drawable.Drawable
* )
*/
@Override
public void setImageDrawable(Drawable drawable) {
// Constrain to given size but keep aspect ratio
int width = drawable.getIntrinsicWidth();
int height = drawable.getIntrinsicHeight();
mLastTouchX = mPosX = 0;
mLastTouchY = mPosY = 0;
int borderWidth = (int) borderPaint.getStrokeWidth();
mScaleFactor = Math.min(((float) getLayoutParams().width - borderWidth)
/ width, ((float) getLayoutParams().height - borderWidth)
/ height);
pivotPointX = (((float) getLayoutParams().width - borderWidth) - (int) (width * mScaleFactor)) / 2;
pivotPointY = (((float) getLayoutParams().height - borderWidth) - (int) (height * mScaleFactor)) / 2;
super.setImageDrawable(drawable);
}
float pivotPointX = 0f;
float pivotPointY = 0f;
private class ScaleListener extends
ScaleGestureDetector.SimpleOnScaleGestureListener {
@Override
public boolean onScale(ScaleGestureDetector detector) {
mScaleFactor *= detector.getScaleFactor();
pivotPointX = detector.getFocusX();
pivotPointY = detector.getFocusY();
Log.d(LOG_TAG, "mScaleFactor " + mScaleFactor);
Log.d(LOG_TAG, "pivotPointY " + pivotPointY + ", pivotPointX= "
+ pivotPointX);
mScaleFactor = Math.max(0.05f, mScaleFactor);
invalidate();
return true;
}
}
这里是我如何在我的 Activity 中使用它。
ImageView imageView = (ImageView) findViewById(R.id.imgView);
int hMargin = (int) (displayMetrics.widthPixels * .10);
int vMargin = (int) (displayMetrics.heightPixels * .10);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(displayMetrics.widthPixels - (hMargin * 2), (int)(displayMetrics.heightPixels - btnCamera.getHeight()) - (vMargin * 2));
params.leftMargin = hMargin;
params.topMargin = vMargin;
imageView.setLayoutParams(params);
imageView.setImageDrawable(drawable);
最佳答案
你可以使用这个类:TouchImageView
关于Android ImageView 捏缩放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10630373/
我正在使用apneadiving/Google-Maps-for-Rails添加googlemaps支持(感谢awesomegem)但是,我发现了一个小故障,这很可能是我的错。当有多个标记时,auto_zoom效果很好。但是,当只有一个标记时,它会放大到不漂亮的最大级别。“缩放”仅在auto_zoom为false时有效,所以这不是我想要的。因此您可以使用“maxZoom”,但现在用户无法手动放大超出该点,这不是我想要的。有解决办法吗?我的解释有道理吗?这是GoogleMapsAPI的限制吗?谢谢... 最佳答案 此行为是由于goog
1.变换1.1什么是变换?变换(Transform)是计算机图形学中非常重要的一部分。变换包含模型变换(Modelingtransform)以及视图变换(Viewtransform)。模型变换指的是变换模型(被拍摄物体)的位置,大小和角度;视图变换指的是变换照相机的位置和角度。从相对运动的角度来看,两种变换是可以相互转化的。1.2模型变换1.2.1二维变换缩放变换缩放变换(Scale)中,如果一个图片以原点(0,0)为中心缩放𝑠倍。那么点(𝑥,𝑦)变换后数学形式可以表示为写成矩阵形式为:当然,我们也可以给x轴和y轴不同的缩放倍数𝑠𝑥和𝑠𝑦。在非均匀情况下,缩放变换的矩阵形式为反射变换反射变换(
为了在svg多边形或圆上有两个笔划和模糊,我创建了一个滤镜来执行此操作,尽管第二个“笔划”(使用滤镜创建)被剪裁或不像一个完美的圆。知道如何以正确的方式解决这个问题吗? 最佳答案 feMorphology在执行扩张时使用方形搜索框,因此它将创建这些裁剪效果。另一种扩大形状并保留原始形状的方法是进行高斯模糊,然后使用feComposite/feFuncA/table将模糊区域转换为完全不透明的形状。像这样: 关于javascript-SVGfeOffset过滤器放大/缩放,我们在Stack
我在使用v4时遇到D3中的缩放功能问题。它抛出一个错误,指出zoom.translate未定义。我主要使用此答案中的以下代码d3focusonnodeonclick,这对v3非常有效。但是,由于我在使用v3时遇到问题,因为它对源和节点采用字符串形式(而不是索引)的数据有限制D3JSONfilewithsourceandindexasstringsratherthanindices,我切换到v4..linksline{stroke:#999;stroke-opacity:0.6;}.nodescircle{stroke:#fff;stroke-width:1.5px;}varsvg=d3
我昨天才开始使用d3.js,但在完成我的工作时遇到了一些麻烦。现在我创建了一个带有两个y轴的图表,每个显示一些值,x轴显示日期。点击y轴上的值,我会显示相应的水平网格线。我的问题是,在放大或缩小或拖动时,网格线(水平和垂直)无法根据轴值正确缩放,它们根本就不动。我今天下午进行了很多搜索,找到了一些如何执行此操作的示例,但它们似乎都不适用于我已有的代码。我想,应该将逻辑添加到缩放行为中,但我不确定//xaxisgridlinesfunctionmake_x_gridlines(){returnd3.axisBottom(x).ticks(5)}//addtheXgridlinesletx
我正在尝试通过两个缩放按钮(+)和(-)放大和缩小图像。问题是当图像为全屏尺寸(宽度100%)时“放大”停止。我需要将图像放大到比屏幕尺寸大得多。只是不知道该怎么做。我是Javascript的初学者,所以我希望有人有动力帮助我解决这个Javascript小问题。我想知道是否有任何简单的放大/缩小/重置插件可以与缩放按钮一起使用?图像抓取也很酷。再次感谢!functionzoomin(){varmyImg=document.getElementById("map");varcurrWidth=myImg.clientWidth;if(currWidth==2500)returnfalse
我在这个场景中有27个网格,每个网格都有一个关联的编号。数字最高的将具有标度1。其余的将依次具有小于1的值。接下来我希望它相应地爬上每个循环。当每个网格的位置发生变化时,就会出现我的问题。确实它被缩放到应有的大小,但它改变了位置。几个屏幕堆叠在一起,我很吃力。我只需要你爬上去,并保持在这个例子中的相同位置:美国各州已按比例缩放,但仍保持其位置。我认为它们会缩放到图的中心。我创建了网格(每个都称为“municipios”)for(vars=0;s 最佳答案 因为网格位置不在它的中心,或者任何你想要的引用:如果你创建一个平均顶点x分量超
我想让访问者使用点击和拖动来缩放图像:是否有可以帮助我的JavaScript库?我注意到Raphaelhasclickanddrag方法,但我仍然需要编写大量JS来:找到图像的Angular使Angular落附近的区域可选为Angular绘制图标,使其明显可见在Angular落添加点击、拖放更新图片的尺寸我可以做到所有这些,但听起来很费时。有没有我应该使用的开源脚本?其他建议? 最佳答案 我在这篇文章中找到了这个解决方案:DraggablesandResizablesinSVG.在答案中,您可以找到一个jsfiddle链接:http
我是使用谷歌地图的新手,正在尝试找出如何限制缩放功能,使其不会缩放到map中心以外的任何地方,也不会缩放到鼠标点。基本上,无论您的鼠标指针在map上的哪个位置,它都会缩放到返回map的中心,而不是缩放鼠标指针在map上的位置。我什至不知道目前是否可行,希望能提供一些帮助。functioninitialize(){varlatlng=newgoogle.maps.LatLng(51.285583,1.091045);varmyOptions={zoom:15,center:latlng,scrollwheel:true,navigationControl:false,mapTypeCon
我希望缩放cyjsView以适合(很好地包含)当前选定的节点。可以手动或以编程方式选择节点。如果只选择了一个小的网络邻居,那么放大效果会非常显着。如果远处的节点在选择中,则放大甚至可能不会引人注意。cy.fit()非常适合在窗口中显示整个网络。但是尽我所能,我找不到cy.fitSelected()或一些等效的功能。有什么建议吗? 最佳答案 这是一个单行代码,因为cy.fit()将eles作为它的第一个参数:例如cy.fit(cy.$(':selected'),50)填充50http://cytoscape.github.io/cyt