123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254 |
- import baseComponent from '../helpers/baseComponent'
- import classNames from '../helpers/libs/classNames'
- import styleToCssString from '../helpers/libs/styleToCssString'
- import { getSystemInfoSync } from '../helpers/hooks/useNativeAPI'
- import { getCanvasRef, toDataURL, createImage, downloadImage } from '../helpers/hooks/useCanvasAPI'
- baseComponent({
- properties: {
- prefixCls: {
- type: String,
- value: 'wux-water-mark',
- },
- content: {
- optionalTypes: [Array, String],
- type: String,
- value: '',
- },
- fontColor: {
- type: String,
- value: 'rgba(0, 0, 0, .15)',
- },
- fontStyle: {
- type: String,
- value: 'normal',
- },
- fontFamily: {
- type: String,
- value: 'sans-serif',
- },
- fontWeight: {
- type: String,
- value: 'normal',
- },
- fontSize: {
- type: Number,
- value: 14,
- },
- fullPage: {
- type: Boolean,
- value: true,
- },
- gapX: {
- type: Number,
- value: 24,
- },
- gapY: {
- type: Number,
- value: 48,
- },
- width: {
- type: Number,
- value: 120,
- },
- height: {
- type: Number,
- value: 64,
- },
- image: {
- type: String,
- value: '',
- },
- imageHeight: {
- type: Number,
- value: 64,
- },
- imageWidth: {
- type: Number,
- value: 128,
- },
- rotate: {
- type: Number,
- value: -22,
- },
- zIndex: {
- type: Number,
- value: 2000,
- },
- },
- data: {
- wrapStyle: '',
- base64Url: '',
- },
- observers: {
- ['zIndex, gapX, width, base64Url'](...args) {
- this.updateStyle(...args)
- },
- ['prefixCls, gapX, gapY, rotate, fontStyle, fontWeight, width, height, fontFamily, fontColor, image, imageWidth, imageHeight, content, fontSize'](...args) {
- this.setBase64Url(...args)
- },
- },
- computed: {
- classes: ['prefixCls, fullPage', function(prefixCls, fullPage) {
- const wrap = classNames(prefixCls, {
- [`${prefixCls}--full-page`]: fullPage,
- })
- const canvas = `${prefixCls}__canvas`
- return {
- wrap,
- canvas,
- }
- }],
- },
- methods: {
- setBase64Url(...args) {
- const [
- prefixCls,
- gapX,
- gapY,
- rotate,
- fontStyle,
- fontWeight,
- width,
- height,
- fontFamily,
- fontColor,
- image,
- imageWidth,
- imageHeight,
- content,
- fontSize,
- ] = args
- this.createCanvasContext({
- prefixCls,
- gapX,
- gapY,
- rotate,
- fontStyle,
- fontWeight,
- width,
- height,
- fontFamily,
- fontColor,
- image,
- imageWidth,
- imageHeight,
- content,
- fontSize,
- })
- },
- createCanvasContext(props) {
- const {
- prefixCls,
- gapX,
- gapY,
- rotate,
- fontStyle,
- fontWeight,
- width,
- height,
- fontFamily,
- fontColor,
- image,
- imageWidth,
- imageHeight,
- content,
- fontSize,
- } = props
- const setBase64Url = (base64Url) => {
- if (props.base64Url !== base64Url) {
- this.setData({
- base64Url,
- })
- this.triggerEvent('load', { base64Url })
- }
- }
- const canvasId = `${prefixCls}__canvas`
- const renderCanvas = (imageUrl) => getCanvasRef(canvasId, this).then((canvas) => {
- const ctx = canvas.getContext('2d')
- const ratio = getSystemInfoSync(['window']).pixelRatio
- const canvasWidth = (gapX + width) * ratio
- const canvasHeight = (gapY + height) * ratio
- const markWidth = width * ratio
- const markHeight = height * ratio
- canvas.width = canvasWidth
- canvas.height = canvasHeight
- if (imageUrl) {
- ctx.translate(markWidth / 2, markHeight / 2)
- ctx.rotate((Math.PI / 180) * Number(rotate))
- return createImage({
- imageWidth,
- imageHeight,
- imageUrl,
- }, canvas).then(() => (
- toDataURL({ width, height }, canvas)
- .then((base64Url) => {
- ctx.restore()
- return base64Url
- })
- ))
- } 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 = fontColor
- if (Array.isArray(content)) {
- content.forEach((item, index) =>
- ctx.fillText(item, 0, index * markSize)
- )
- } else {
- ctx.fillText(content, 0, 0)
- }
- return toDataURL({ width, height }, canvas)
- .then((base64Url) => {
- ctx.restore()
- return base64Url
- })
- }
- })
- let promise = Promise.resolve()
- if (image) {
- promise = promise.then(() => downloadImage(image))
- }
- promise = promise.then((imageUrl) => {
- return renderCanvas(imageUrl)
- })
- promise = promise.then((base64Url) => {
- setBase64Url(base64Url)
- }, (err) => {
- this.triggerEvent('error', err)
- // console.error(err)
- })
- return promise
- },
- updateStyle(zIndex, gapX, width, base64Url) {
- const wrapStyle = styleToCssString({
- zIndex,
- backgroundSize: `${gapX + width}px`,
- backgroundImage: base64Url ? `url('${base64Url}')` : 'unset',
- })
- this.setData({
- wrapStyle,
- })
- },
- },
- ready() {
- const { zIndex, gapX, width, base64Url } = this.data
- this.updateStyle(zIndex, gapX, width, base64Url)
- this.createCanvasContext(this.data)
- },
- })
|