cxj-react-image 用法以下:css
yarn add cxj-react-image
// npm i cxj-react-image
複製代碼
import ImageModal from 'cxj-react-image';
<ImageModal
src={imageList[currentImageIndex]} {/* 當前圖片路徑 */}
next={() => this.next()} {/* 控制下一張 */}
prev={() => this.prev()} {/* 控制上一張 */}
closeModal={() => this.closeImg()} {/* 控制modal打開關閉 */}
option={{
move: true, {/* 控制拖動 */}
waterMarkText: '多功能圖片組件', {/* 設置水印文字 */}
rotate: true, {/* 控制旋轉 */}
zoom: true {/* 控制放大縮小 */}
}}
/>
複製代碼
更詳細的用法請參考 container.js
文件前端
github地址react
在線例子git
若有幫助,感謝star~~~ 若有問題,歡迎call me~~~github
交流請加wx: c13266836563npm
如下爲相關實現講解canvas
實現拖拽的思路是計算出dom最後的left跟top。bash
未移動前能夠經過clientX跟offsetLeft拿到dom的x座標和左邊距,記爲initX和offLeft
。dom
移動的過程當中能夠經過clientX
拿到元素的x座標,記爲moveX
。post
獲得公式:left = moveX - initX + offLeft
。
核心代碼以下:
const move = (dv) => {
// 獲取元素
let x = 0;
let y = 0;
let l = 0;
let t = 0;
let isDown = false;
// 鼠標按下事件
dv.onmousedown = function(e) {
// 獲取x座標和y座標
x = e.clientX;
y = e.clientY;
// 獲取左部和頂部的偏移量
l = dv.offsetLeft;
t = dv.offsetTop;
handleMove();
};
// 鼠標移動
// 再包一層是爲了方便註冊 避免被替換
function handleMove() {
onmousemove = function(e) {
// 獲取x和y
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';
};
}
};
複製代碼
關於拖拽,有個狀況還須要優化:頁面上有兩個modal,要保證最後點擊的modal要覆蓋以前點擊的modal。
也就是zIndex要控制好,這裏用localStorage來保存這個最大的zIndex
imageModalMaxzIndex = localStorage.getItem('imageModalMaxzIndex');
if (dv.style.zIndex != imageModalMaxzIndex) {
dv.style.zIndex = +imageModalMaxzIndex + 1;
localStorage.setItem('imageModalMaxzIndex', dv.style.zIndex);
}
複製代碼
前端實現水印,避免私密圖片泄露
思路是使用canvas生成文字圖片,而後利用如下的css:
background-image:url('${base64Url}');
background-repeat:repeat;
實現水印類:
/**
* @overview: 水印組件
*/
export default class WaterMark {
constructor(container, option) {
this.container = container;
this.option = {
width: '200px',
height: '150px',
opacity: .7,
fillStyle: 'rgba(47, 205, 227, 0.3)',
font: '20px microsoft yahei',
textBaseline: 'middle',
textAlign: 'center',
fillText: '水印',
...option
};
}
draw() {
const {
container,
option: {
width,
height,
opacity,
fillStyle,
font,
textBaseline,
textAlign,
fillText,
scrollHeight
}
} = this;
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}')`);
if (typeof container === 'object') {
container.style.position = 'relative';
container.insertBefore(watermarkDiv, container.firstChild);
}
}
}
複製代碼
這裏有一篇文章總結了幾種前端水印的方案,推薦給你們 文章
縮放的話,監聽鼠標滾動事件。向上滾動放大,向下滾動縮小;這裏要注意控制最小縮放值。
還要注意的是圖片在邊界的縮放,否則圖片可能會移動在屏幕外。
須要作的處理是判斷左邊界跟圖片的寬度。
代碼實現:
// 控制滾輪縮放
const zoom = (onWheelEvent, dom) => {
let e = onWheelEvent;
let imageModalWidth = parseInt(dom.style.width);
let modalLeft = parseInt(dom.style.left);
// 計算縮放後的大小 每一次滾輪 100px
let calcWidth = imageModalWidth - e.deltaY;
// 限制最小 width = 400
if (calcWidth <= 300) {
return;
}
// 不讓modal因爲縮小消失在視野中
if (modalLeft + calcWidth < 50) {
return;
}
dom.style.width = `${calcWidth}px`;
};
複製代碼