UNPKG

@nutui/nutui-react

Version:

京东风格的轻量级移动端 React 组件库,支持一套代码生成 H5 和小程序

63 lines (62 loc) 2.92 kB
import React__default, { useState, useEffect } from "react"; import classNames from "classnames"; import { useConfig } from "./ConfigProvider.js"; import { C as ComponentDefaults } from "./typings.js"; const defaultProps = Object.assign(Object.assign({}, ComponentDefaults), { content: "", fullPage: true, zIndex: 2e3, gapX: 24, gapY: 48, width: 120, height: 64, startX: 0, startY: 0, image: "", imageWidth: 120, imageHeight: 64, rotate: -22, color: "rgba(0,0,0,.15)", fontStyle: "normal", fontWeight: "normal", fontSize: 14 }); const WaterMark = (props) => { const { locale } = useConfig(); const { content, fullPage, zIndex, className, gapX, gapY, startX, startY, width, height, image, imageWidth, imageHeight, rotate, color, fontStyle, fontFamily, fontWeight, fontSize, style } = Object.assign(Object.assign({}, defaultProps), props); const [base64Url, setBase64Url] = useState(""); const classPrefix = "nut-watermark"; const classes = classNames(classPrefix, { [`${classPrefix}-full-page`]: fullPage }); const cls = classNames(classes, className); useEffect(() => { init(); }, []); const init = () => { const canvas = document.createElement("canvas"); const ratio = window.devicePixelRatio; const ctx = canvas.getContext("2d"); const canvasWidth = `${(gapX + width) * ratio}px`; const canvasHeight = `${(gapY + height) * ratio}px`; const markWidth = width * ratio; const markHeight = height * ratio; canvas.setAttribute("width", canvasWidth); canvas.setAttribute("height", canvasHeight); if (ctx) { if (image) { ctx.translate(markWidth / 2, markHeight / 2); ctx.rotate(Math.PI / 180 * Number(rotate)); const img = new Image(); img.crossOrigin = "anonymous"; img.referrerPolicy = "no-referrer"; img.src = image; img.onload = () => { ctx.drawImage(img, -imageWidth * ratio / 2, -imageHeight * ratio / 2, imageWidth * ratio, imageHeight * ratio); ctx.restore(); setBase64Url(canvas.toDataURL()); }; } else if (content) { ctx.textBaseline = "middle"; ctx.textAlign = "center"; ctx.translate(markWidth / 2, markHeight / 2); ctx.rotate(Math.PI / 180 * Number(rotate)); const markSize = Number(fontSize) * ratio; ctx.font = `${fontStyle} normal ${fontWeight} ${markSize}px/${markHeight}px ${fontFamily}`; ctx.fillStyle = color; ctx.fillText(content, startX, startY); ctx.restore(); setBase64Url(canvas.toDataURL()); } } else { throw new Error(locale.watermark.errorCanvasTips); } }; return React__default.createElement("div", { className: cls, style: Object.assign({ zIndex, backgroundSize: `${gapX + width}px`, backgroundImage: `url('${base64Url}')` }, style) }); }; WaterMark.displayName = "NutWaterMark"; export { WaterMark as default };