# Zoomable
**Repository Path**: zhan-weisong/zoomable
## Basic Information
- **Project Name**: Zoomable
- **Description**: OpenHarmony自定义组件——可缩放的图片组件
- **Primary Language**: JavaScript
- **License**: Apache-2.0
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2022-07-13
- **Last Updated**: 2022-07-13
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
## 局部放大图片组件
### 1、项目介绍
使用JS语言开发的基于OpenHarmony的局部放大图片组件,在显示图片这一基础功能上增加局部放大功能。
### 2、作品效果图或视频展示

### 3、实现原理
#### 3.1、使用canvas组件的drawImage方法实现图片显示。
drawImage(image: Image, sx: number, sy: number, sWidth: number, sHeight: number, dx: number, dy: number, dWidth: number, dHeight: number):void
该方法需要输入9个参数,分别是图片对象,原图的X轴裁剪起点,原图的Y轴裁剪起点,裁剪的宽度,裁剪的高度,画布X轴画图的起点,画布Y轴画图的起点,画布的宽度,画布的高度。
```
ctx0.drawImage(changeview,
this.initwidth / 2 - this.initwidth / this.scale / 2,
this.initheight / 2 - this.initheight / this.scale / 2,
changeview.width / this.scale,
changeview.height / this.scale,
0, 0,
this.setwidth, this.setheight);
```

#### 3.2、给canvas组件绑定ondoubleclick双击事件,变化zoom_flag标识变量的值,用于切换局部放大模式和原始视图。
```
// 切换镜头远近
zoomswitch() {
this.zoom_flag = !this.zoom_flag;
console.info("切换镜头远近");
var changeview = new Image();
changeview.src = this.img.src;
if(true == this.zoom_flag) {
console.info("拉近镜头");
changeview.onload = ()=> {
ctx0.drawImage(changeview,
this.initwidth / 2 - this.initwidth / this.scale / 2,
this.initheight / 2 - this.initheight / this.scale / 2,
changeview.width / this.scale,
changeview.height / this.scale,
0, 0,
this.setwidth, this.setheight);
};
}
else {
console.info("恢复全局视角");
changeview.onload = ()=> {
ctx0.drawImage(changeview,
0, 0,
this.initwidth, this.initheight,
0, 0,
this.setwidth, this.setheight);
console.info(JSON.stringify(changeview));
console.info("当前视图——宽:" + changeview.width + ",高:" + changeview.height);
};
}
},
```
#### 3.3、给canvas组件绑定touchmove事件,获取touchmove事件的触点坐标,经过计算得出drawImage方法中的几个关键参数值,并添加判断条件,当触点坐标过于接近边缘时设置极限值。
```
// 在图片区域内移动可视区域
getmove(event) {
if(false == this.zoom_flag) {
console.info("未进入放大模式,无法移动");
return;
}
this.points.x = (event.touches[0].localX - this.setwidth / this.scale / 2) / this.setwidth * this.initwidth;
this.points.y = (event.touches[0].localY - this.setheight / this.scale / 2) / this.setheight * this.initheight;
if(((this.setwidth / this.scale / 2) > event.touches[0].localX)
|| ((this.setwidth - this.setwidth / this.scale / 2) < event.touches[0].localX)) {
console.info("视角横坐标太靠近边缘");
if((this.setwidth / this.scale / 2) > event.touches[0].localX) {
console.info("太靠近左边");
this.points.x = 0;
}
else {
console.info("太靠近右边");
this.points.x = this.initwidth - this.initwidth / this.scale;
}
}
if(((this.setheight / this.scale / 2) > event.touches[0].localY)
|| ((this.setheight - this.setheight / this.scale / 2) < event.touches[0].localY)) {
console.info("视角纵坐标太靠近边缘");
if((this.setheight / this.scale / 2) > event.touches[0].localY) {
console.info("太靠近上边");
this.points.y = 0;
}
else {
console.info("太靠近下边");
this.points.y = this.initheight - this.initheight / this.scale;
}
}
var newview = new Image();
newview.src = this.img.src;
newview.onload = ()=> {
ctx0.drawImage(newview,
this.points.x, this.points.y,
newview.width / this.scale, newview.height / this.scale,
0, 0,
this.setwidth, this.setheight);
};
},
```
#### 3.4、4个属性参数设置
| 参数名 | 描述 | 参数类型 | 默认值 |
| ----------- | ---------------| -------- | ------ |
| setwidth | 设置图片宽度 | Number | 0 |
| setheight | 设置图片高度 | Number | 0 |
| setsrc | 设置图片地址 | String | 无 |
| scale | 图片放大的比例 | Number | 2 |
#### 3.5、组件调用
```