实现放大镜效果

1、布局文件

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/frameLayout1"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
   
</FrameLayout>

2、在MainActivity中创建MyView的内部类,继承android.view.View类,并添加构造方法和重写onDraw(Canvas canvas)方法,然后在onCreate()方法中获取布局文件中添加的帧布局管理器,并将MyView视图添加到该帧布局管理器中

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        FrameLayout ll = (FrameLayout)findViewById(R.id.frameLayout1);
        ll.addView(new MyView(this));
    }
    public class MyView extends View{
		public MyView(Context context) {
			super(context);
		}
		@Override
		protected void onDraw(Canvas canvas) {
			super.onDraw(canvas);
		}
    }
}


3、在内部类MyView中,定义源图像、放大镜图像、放大镜的半径、放大倍数、放大镜的左边距和顶边距

private Bitmap bitmap;//源图像,也就是背景图像
    	private ShapeDrawable drawable;
    	private final int RADIUS = 57 ;//放大镜的半径
    	private final int FACTOR = 2;//放大倍数
    	private Matrix matrix = new Matrix();
    	private Bitmap bitmap_magnifier;//放大镜位图
    	private int m_left = 0;//放大镜的左边距
    	private int m_top = 0;//放大镜的顶边距


4、在内部类MyView的构造方法中

Bitmap bitmap_source = BitmapFactory.decodeResource(getResources(),
<span style="white-space:pre">					</span>R.drawable.source);//获取要显示的源图像
<span style="white-space:pre">			</span>bitmap = bitmap_source;
<span style="white-space:pre">			</span>BitmapShader shader = new BitmapShader(Bitmap.createScaledBitmap(
<span style="white-space:pre">					</span>bitmap_source,bitmap_source.getWidth()*FACTOR, 
<span style="white-space:pre">					</span>bitmap_source.getHeight()*FACTOR, true),TileMode.CLAMP , TileMode.CLAMP);//创建BitmapShader对象
<span style="white-space:pre">			</span>//圆形的drawable
<span style="white-space:pre">			</span>drawable = new ShapeDrawable(new OvalShape());
<span style="white-space:pre">			</span>drawable.getPaint().setShader(shader);
<span style="white-space:pre">			</span>drawable.setBounds(0, 0, RADIUS*2, RADIUS*2);//设置圆的外切矩形
<span style="white-space:pre">			</span>bitmap_magnifier = BitmapFactory.decodeResource(getResources(), R.drawable.magnifier);//获取放大镜图像
<span style="white-space:pre">			</span>m_left = RADIUS - bitmap_magnifier.getWidth()/2;//计算放大镜的默认左边距
<span style="white-space:pre">			</span>m_top = RADIUS - bitmap_magnifier.getHeight()/2;//计算放大镜的默认右边距

5、在MyView的onDraw()方法中,分别绘制背景图像、放大镜图像和放大后的图像

canvas.drawBitmap(bitmap, 0, 0, null);//绘制背景图像
			canvas.drawBitmap(bitmap_magnifier, m_left, m_top, null);//绘制放大镜图像
			drawable.draw(canvas);//绘制放大后的图像

6、在MyView类中,重写onTouchEvent()方法,实现党用户触摸屏幕时,放大触摸点附近的图像

@Override
<span style="white-space:pre">		</span>public boolean onTouchEvent(MotionEvent event) {
<span style="white-space:pre">			</span>final int x = (int)event.getX();//获取当前触摸点的X轴左边
<span style="white-space:pre">			</span>final int y = (int)event.getY();//获取当前触摸点的Y轴左边
<span style="white-space:pre">			</span>matrix.setTranslate(RADIUS-x*FACTOR, RADIUS-y*FACTOR);//平移到绘制shader的起始位置
<span style="white-space:pre">			</span>drawable.getPaint().getShader().setLocalMatrix(matrix);
<span style="white-space:pre">			</span>drawable.setBounds(x-RADIUS, y-RADIUS, x+RADIUS, y+RADIUS);//设置圆的外切距离
<span style="white-space:pre">			</span>m_left = x-bitmap_magnifier.getWidth()/2;//计算放大镜的左边距
<span style="white-space:pre">			</span>m_top = y-bitmap_magnifier.getHeight()/2;//计算放大镜的右边距
<span style="white-space:pre">			</span>invalidate();//重置画布
<span style="white-space:pre">			</span>return true;
<span style="white-space:pre">		</span>}





  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Magnifier</title> <style type="text/css"> #magnifier{ width:320px; height:280px; position:absolute; border:1px solid #000; text-align:center; line-height:280px; overflow:hidden; } #img{ width:300px; height:260px; } #Browser{ border:1px solid #000; z-index:100; position:absolute; background:#555; } #mag{ border:1px solid #000; overflow:hidden; z-index:100; } </style> [removed] function getEventObject(W3CEvent) { //事件标准化函数 return W3CEvent || window.event; } function getPointerPosition(e) { //兼容浏览器的鼠标x,y获得函数 e = e || getEventObject(e); var x = e.pageX || (e.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft)); var y = e.pageY || (e.clientY + (document.documentElement.scrollTop || document.body.scrollTop)); return { 'x':x,'y':y }; } function setOpacity(elem,level) { //兼容浏览器设置透明值 if(elem.filters) { elem.style.filter = 'alpha(opacity=' + level * 100 + ')'; } else { elem.style.opacity = level; } } function css(elem,prop) { //css设置函数,可以方便设置css值,并且兼容设置透明值 for(var i in prop) { if(i == 'opacity') { setOpacity(elem,prop[i]); } else { elem.style[i] = prop[i]; } } return elem; } var magnifier = { m : null, init:function(magni){ var m = this.m = magni || { cont : null, //装载原始图像的div img : null, //放大图像 mag : null, //放大框 scale : 15 //比例值,设置的值越大放大越大,但是这里有个问题就是如果不可以整除时,会产生些很小的白边,目前不知道如何解决 } css(m.img,{ 'position' : 'absolute', 'width' : (m.cont.clientWidth * m.scale) + 'px', //原始图像的宽*比例值 'height' : (m.cont.clientHeight * m.scale) + 'px' //原始图像的高*比例值 }) css(m.mag,{ 'display' : 'none', 'width' : m.cont.clientWidth +90 + 'px', //m.cont为原始图像,与原始图像等宽 'height' : m.cont.clientHeight + 'px', 'position' : 'absolute', 'left' : m.cont.offsetLeft + m.cont.offsetWidth + 10 + 'px', //放大框的位置为原始图像的右方远10px 'top' : m.cont.offsetTop + 'px' }) var borderWid = m.cont.getElementsByTagName('div')[0].offsetWidth - m.cont.getElementsByTagName('div')[0].clientWidth; //获取border的宽 css(m.cont.getElementsByTagName('div')[0],{ //m.cont.getElementsByTagName('div')[0]为浏览框 'display' : 'none', //开始设置为不可见 'width' : m.cont.clientWidth / m.scale - borderWid + 'px', //原始图片的宽/比例值 - border的宽度 'height' : m.cont.clientHeight / m.scale - borderWid + 'px', //原始图片的高/比例值 - border的宽度 'opacity' : 0.5 //设置透明度 }) m.img.src = m.cont.getElementsByTagName('img')[0].src; //让原始图像的src值给予放大图像 m.cont.style.cursor = 'crosshair'; m.cont.onmouseover = magnifier.start; }, start:function(e){ if(document.all){ //只在IE下执行,主要避免IE6的select无法覆盖 magnifier.createIframe(magnifier.m.img); } this.onmousemove = magnifier.move; //this指向m.cont this.onmouseout = magnifier.end; }, move:function(e){ var pos = getPointerPosition(e); //事件标准化 this.getElementsByTagName('div')[0].style.display = ''; css(this.getElementsByTagName('div')[0],{ 'top' : Math.min(Math.max(pos.y - this.offsetTop - parseInt(this.getElementsByTagName('div')[0].style.height) / 2,0),this.clientHeight - this.getElementsByTagName('div')[0].offsetHeight) + 'px', 'left' : Math.min(Math.max(pos.x - this.offsetLeft - parseInt(this.getElementsByTagName('div')[0].style.width) / 2,0),this.clientWidth - this.getElementsByTagName('div')[0].offsetWidth) + 'px' //left=鼠标x - this.offsetLeft - 浏览框宽/2,Math.max和Math.min让浏览框不会超出图像 }) magnifier.m.mag.style.display = ''; css(magnifier.m.img,{ 'top' : - (parseInt(this.getElementsByTagName('div')[0].style.top) * magnifier.m.scale) + 'px', 'left' : - (parseInt(this.getElementsByTagName('div')[0].style.left) * magnifier.m.scale) + 'px' }) }, end:function(e){ this.getElementsByTagName('div')[0].style.display = 'none'; magnifier.removeIframe(magnifier.m.img); //销毁iframe magnifier.m.mag.style.display = 'none'; }, createIframe:function(elem){ var layer = document.createElement('iframe'); layer.tabIndex = '-1'; layer.src = '[removed]false;'; elem[removed].appendChild(layer); layer.style.width = elem.offsetWidth + 'px'; layer.style.height = elem.offsetHeight + 'px'; }, removeIframe:function(elem){ var layers = elem[removed].getElementsByTagName('iframe'); while(layers.length >0){ layers[0][removed].removeChild(layers[0]); } } } window.onload = function(){ magnifier.init({ cont : document.getElementById('magnifier'), img : document.getElementById('magnifierImg'), mag : document.getElementById('mag'), scale : 3 }); } [removed] </head>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值