从
0 => 1
实现一个仿百度的图片预览,操作的组件
实现功能:
- 缩放✔
- 旋转✔
- 拖动✔
- 切换的动画
- 分享
- 可导出多种格式(支持下载)✔
- 二维码扫描到手机观看✔
- 水印
- 待定
ok,先做下准备工作
我们定义一个状态类,这是我们图片的所有属性,后续就是通过js操作这些属性来改变img
外部只需传进来一个图片url,我们即可实现上面的功能。暂时先写这么多,有想加的功能可以加
定义一个方法类,用来写我们的功能方法,这里写了个缩放试了下代码
定义一个渲染dom的类,因为我们的图片节点都是js创建的
这俩方法测试用
最后,写一个Image类暴露给外部
到这已经能跑通了,实现滚轮缩放
百度上的功能先补上
- 图片列表(轮播)
- 放大缩小
- 合适尺寸
- 全屏
- 二维码扫描到手机
- 下载
大概就是这些功能,我们把底下的图标给他们补上
每一个就是一个icon,我们把他们渲染到页面中
我们通过ref来保存持久化变量,也就是这个图片的实例,我们从外部传进来一个唯一的url,然后生成一个img dom
,所以我们的hooks
是随着这个唯一url
来进行刷新的,所以我们使用useCallback
返回对图片render
后的实例,避免在url
未变的情况下,重复渲染 img
。
ahooks
的usePersistFn
可以在操作img dom
的同时拒绝不必要的re render
但其实页面在这边是有问题的 —— 重复渲染了icon组件。
我的设想是icon组件只要渲染一次,改变只是ref指向的img实例,暂时这边还没对这块做处理
会被重复渲染的问题以后再解决。
接下来就是把这些功能都补全
import States from "./state";
import {
canvasToDataURL } from 'util';
import QRCode from 'qrcode';
class Method extends States {
// 缩放
zoomToWheel() {
if (!this.container) return;
// onWheel => 滚轮、触控板事件
this.container.addEventListener("wheel", (e) => {
const _zoom = e.deltaY > 0; // true => 放大 false => 缩小
const width = parseFloat(this.imgDom.style.width);
const height = parseFloat(this.imgDom.style.height);