序:
整理了一下開發(fā)的一個React影像組件
由于一些(亂七八糟)的需求伺糠,導(dǎo)致之前的組件影像代碼冗余,不可維護(hù)
看不下去了斥季,是時候出來拯救世界了
于是我上場了
我做的事训桶,就是將各類功能函數(shù)抽離累驮,同時代碼盡可能的少
這個組件的主要功能有:拖拽、水印舵揭、縮放谤专、切換、旋轉(zhuǎn)(更新中)
以及一些小的功能點(diǎn)比如:鍵盤左右切換午绳、移動時增加透明度等一些細(xì)節(jié)的優(yōu)化
不多bb了吧置侍,直接上demo, 自己上來動 傳送門
下面我會寫一下一些功能的實現(xiàn)
<hr />
拖拽:
鼠標(biāo)移動的時候改變modal的位置就可以了
并且要設(shè)置一下透明度
let nx = e.clientX;
let ny = e.clientY;
// 計算移動后的左偏移量和頂部的偏移量
let nl = nx - (x - l);
let nt = ny - (y - t);
dv.style.left = nl + 'px';
dv.style.top = nt + 'px';
// 設(shè)置移動時透明
dv.querySelector('.image-content').style.opacity = .3;
關(guān)于這個移動,有個地方要注意
比如我們頁面上有兩個modal拦焚,要保證最后點(diǎn)擊的modal要覆蓋之前點(diǎn)擊的modal
也就是zIndex要控制好蜡坊,這里用localStorage來保存這個最大的zIndex
imageModalMaxzIndex = localStorage.getItem('imageModalMaxzIndex');
if (dv.style.zIndex != imageModalMaxzIndex) {
dv.style.zIndex = +imageModalMaxzIndex + 1;
localStorage.setItem('imageModalMaxzIndex', dv.style.zIndex);
}
<hr />
水印
前端實現(xiàn)水印,避免私密圖片泄露
其實水印有好幾種解決方案 dom赎败、canvas秕衙、svg等
這里用canvas實現(xiàn)
思路就是將文本用canvas生成圖片,然后將該圖片作為背景repeat
const canvas = document.createElement('canvas');
canvas.setAttribute('width', width);
canvas.setAttribute('height', height);
canvas.setAttribute('opacity', opacity);
const ctx = canvas.getContext('2d');
ctx.textAlign = textAlign;
ctx.textBaseline = textBaseline;
ctx.font = font;
ctx.fillStyle = fillStyle;
ctx.rotate(Math.PI / 180 * 30);
ctx.fillText(fillText, 80, 10);
var base64Url = canvas.toDataURL();
const watermarkDiv = document.createElement('div');
watermarkDiv.setAttribute('style', `
position:absolute;
top:0;
left:0;
width:100%;
height:${scrollHeight || '100%'};
z-index:1000;
pointer-events:none;
background-repeat:repeat;
background-image:url('${base64Url}')
`);
這里有一篇文章總結(jié)了幾種前端水印的方案僵刮,推薦給大家 文章
<hr />
縮放
縮放的話据忘,監(jiān)聽鼠標(biāo)滾動事件
向上滾動放大,向下滾動縮小這樣
這里要注意控制最小縮放值搞糕,不然會比原子還小若河,很危險的
還要注意的是圖片在邊界的縮放,會突然迷失在宇宙中(移除屏幕寞宫,這是可能的)
這里要做的處理是判斷左邊界跟圖片的寬度
// 不讓modal由于縮小消失在視野中
if (modalLeft + calcWidth < 50) {
return;
}
<hr />
切換
切換其實就是改變imageModal的src
prev() {
const { currentImageIndex } = this.state;
if (currentImageIndex > 0) {
this.setState({ currentImageIndex: currentImageIndex - 1 });
}
}
next() {
const { currentImageIndex, imageList } = this.state;
if (currentImageIndex < imageList.length - 1) {
this.setState({ currentImageIndex: currentImageIndex + 1 });
}
}
<hr />
關(guān)于組件的使用
如果你看得起這個組件萧福,剛好你又有這中神奇的需求,需要這么個影像組件辈赋,那以下:
主要的東西就四個鲫忍,一個common文件夾,一個imageModal.js钥屈、一個Container.js悟民、一個index.css
將這四個文件拿出來,自己根據(jù)自己的需求改就行
調(diào)用方法:
<ImageModal
visible={modalVisible}
src={imageList[currentImageIndex]}
next={() => this.next()}
prev={() => this.prev()}
closeModal={() => this.closeImg()}
option={{
move: true,
waterMarkText: '多功能圖片組件',
rotate: true,
zoom: true
}}
/>
交流請加wx: c13266836563