mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
feat(Watermark): add new Watermark component (#11721)
* feat(watermark): add watermark component * docs(watermark): i18n * feat(watermark): revoke useless url * feat(watermark): add opacity, replace fullPage default to true, replace Zindex default to 100, replace fontColor default to #dedee0 * test(watermark): add watermark snap test * docs(watermark): fix opacity and default value
This commit is contained in:
parent
cac003cef5
commit
69b113717f
119
packages/vant/src/watermark/README.md
Normal file
119
packages/vant/src/watermark/README.md
Normal file
@ -0,0 +1,119 @@
|
||||
# Watermark
|
||||
|
||||
### Intro
|
||||
|
||||
Add watermark for page.
|
||||
|
||||
### Install
|
||||
|
||||
Register component globally via `app.use`, refer to [Component Registration](#/en-US/advanced-usage#zu-jian-zhu-ce) for more registration ways.
|
||||
|
||||
```js
|
||||
import { createApp } from 'vue';
|
||||
import { Watermark } from 'vant';
|
||||
|
||||
const app = createApp();
|
||||
app.use(Watermark);
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Basic Usage
|
||||
|
||||
```html
|
||||
<!-- text watermark -->
|
||||
<van-watermark content="Vant" />
|
||||
|
||||
<!-- image watermark -->
|
||||
<van-watermark image="https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg" />
|
||||
```
|
||||
|
||||
### Custom Gap
|
||||
|
||||
Use `gapX` `gapY` attributes to control the gap between two watermark slice.
|
||||
|
||||
```html
|
||||
<van-watermark
|
||||
image="https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg"
|
||||
:gap-x="20"
|
||||
:gap-y="10"
|
||||
/>
|
||||
```
|
||||
|
||||
### Custom Opacity
|
||||
|
||||
Use `opacity` attribute to control the entirety opacity.
|
||||
|
||||
```html
|
||||
<van-watermark
|
||||
image="https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg"
|
||||
:opacity="0.5"
|
||||
/>
|
||||
```
|
||||
|
||||
### Custom Rotate
|
||||
|
||||
Use `rotate` attribute to control the rotate of watermark. Default value is `-22`.
|
||||
|
||||
```html
|
||||
<van-watermark
|
||||
image="https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg"
|
||||
rotate="22"
|
||||
/>
|
||||
```
|
||||
|
||||
### Display Range
|
||||
|
||||
Use the `fullPage` attribute to control the display range of the watermark.
|
||||
|
||||
```html
|
||||
<van-watermark
|
||||
:full-page="true"
|
||||
content="vant watermark"
|
||||
font-color="rgba(0, 0, 0, 0.15)"
|
||||
>
|
||||
</van-watermark>
|
||||
```
|
||||
|
||||
### HTML Watermark
|
||||
|
||||
Use the `default slot` to pass HTML directly. Inline styles are supported, and self-closing tags are not supported.
|
||||
|
||||
```html
|
||||
<van-watermark :width="150">
|
||||
<div style="background: linear-gradient(45deg, #000 0, #000 50%, #fff 50%)">
|
||||
<p style="mix-blend-mode: difference; color: #fff">Vant watermark</p>
|
||||
</div>
|
||||
</van-watermark>
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### Props
|
||||
|
||||
| Attribute | Description | Type | Default |
|
||||
| --- | --- | --- | --- |
|
||||
| width | Watermark width | _number_ | 100 |
|
||||
| height | Watermark height | _number_ | 100 |
|
||||
| zIndex | Watermark's z-index | _number_ | 100 |
|
||||
| content | Text watermark content | _string_ | - |
|
||||
| image | Image watermark content. If `content` and `image` are passed at the same time, use the `image` watermark first | _string_ | - |
|
||||
| fullPage | Whether to display the watermark in full screen | _boolean_ | true |
|
||||
| gapX | Horizontal spacing between watermarks | _number_ | 0 |
|
||||
| gapY | Vertical spacing between watermarks | _number_ | 0 |
|
||||
| fontColor | Color of text watermark | _string_ | #dcdee0 |
|
||||
| opacity | opacity of watermark | _number_ | 1 |
|
||||
|
||||
### Slots
|
||||
|
||||
| Attribute | Description |
|
||||
| --- | --- |
|
||||
| default | Content of HTML watermark. Inline styles are supported, and self-closing tags are not supported. This slot is invalid if `content` or `image` is passed |
|
||||
|
||||
### Types
|
||||
|
||||
The component exports the following type definitions:
|
||||
|
||||
```ts
|
||||
import type { WaterProps } from 'vant';
|
||||
```
|
119
packages/vant/src/watermark/README.zh-CN.md
Normal file
119
packages/vant/src/watermark/README.zh-CN.md
Normal file
@ -0,0 +1,119 @@
|
||||
# Watermark 水印
|
||||
|
||||
### 介绍
|
||||
|
||||
页面上添加特定的文字或图案,可用于防止信息盗用
|
||||
|
||||
### 引入
|
||||
|
||||
通过以下方式来全局注册组件,更多注册方式请参考[组件注册](#/zh-CN/advanced-usage#zu-jian-zhu-ce)。
|
||||
|
||||
```js
|
||||
import { createApp } from 'vue';
|
||||
import { Watermark } from 'vant';
|
||||
|
||||
const app = createApp();
|
||||
app.use(Watermark);
|
||||
```
|
||||
|
||||
## 代码演示
|
||||
|
||||
### 基础用法
|
||||
|
||||
```html
|
||||
<!-- 文字水印 -->
|
||||
<van-watermark content="Vant" />
|
||||
|
||||
<!-- 图片水印 -->
|
||||
<van-watermark image="https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg" />
|
||||
```
|
||||
|
||||
### 自定义间隔
|
||||
|
||||
通过 `gapX` `gapY` 属性来控制重复水印之间的间隔。
|
||||
|
||||
```html
|
||||
<van-watermark
|
||||
image="https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg"
|
||||
:gap-x="20"
|
||||
:gap-y="10"
|
||||
/>
|
||||
```
|
||||
|
||||
### 自定义透明度
|
||||
|
||||
通过 `opacity` 属性来控制水印的整体透明度。
|
||||
|
||||
```html
|
||||
<van-watermark
|
||||
image="https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg"
|
||||
:opacity="0.5"
|
||||
/>
|
||||
```
|
||||
|
||||
### 自定义倾斜角度
|
||||
|
||||
通过 `rotate` 属性来控制水印的倾斜角度,默认值为`-22`。
|
||||
|
||||
```html
|
||||
<van-watermark
|
||||
image="https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg"
|
||||
rotate="22"
|
||||
/>
|
||||
```
|
||||
|
||||
### 显示范围
|
||||
|
||||
通过 `fullPage` 属性来控制水印的显示范围。
|
||||
|
||||
```html
|
||||
<van-watermark
|
||||
:full-page="true"
|
||||
content="vant watermark"
|
||||
font-color="rgba(0, 0, 0, 0.15)"
|
||||
>
|
||||
</van-watermark>
|
||||
```
|
||||
|
||||
### HTML 水印
|
||||
|
||||
通过默认插槽可以直接传入 HTML,HTML 样式仅支持行内样式同时不支持传入自闭合标签。
|
||||
|
||||
```html
|
||||
<van-watermark :width="150">
|
||||
<div style="background: linear-gradient(45deg, #000 0, #000 50%, #fff 50%)">
|
||||
<p style="mix-blend-mode: difference; color: #fff">Vant watermark</p>
|
||||
</div>
|
||||
</van-watermark>
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### Props
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
| --- | --- | --- | --- |
|
||||
| width | 水印宽度 | _number_ | 100 |
|
||||
| height | 水印高度 | _number_ | 100 |
|
||||
| zIndex | 水印的 z-index | _number_ | 100 |
|
||||
| content | 文字水印的内容 | _string_ | - |
|
||||
| image | 图片水印的内容,如果与 content 同时传入,优先使用图片水印 | _string_ | - |
|
||||
| fullPage | 水印是否全屏显示 | _boolean_ | false |
|
||||
| gapX | 水印水平间隔 | _number_ | 0 |
|
||||
| gapY | 水印垂直间隔 | _number_ | 0 |
|
||||
| fontColor | 文字水印的颜色 | _string_ | #dcdee0 |
|
||||
| opacity | 水印的透明度 | _number_ | 1 |
|
||||
|
||||
### Slots
|
||||
|
||||
| 名称 | 说明 |
|
||||
| --- | --- |
|
||||
| default | HTML 水印的内容,仅支持行内样式同时不支持传入自闭合标签,存在 content 或 image 时此插槽无效 |
|
||||
|
||||
### 类型定义
|
||||
|
||||
组件导出以下类型定义:
|
||||
|
||||
```ts
|
||||
import type { WaterProps } from 'vant';
|
||||
```
|
184
packages/vant/src/watermark/Watermark.tsx
Normal file
184
packages/vant/src/watermark/Watermark.tsx
Normal file
@ -0,0 +1,184 @@
|
||||
import {
|
||||
defineComponent,
|
||||
nextTick,
|
||||
onUnmounted,
|
||||
ref,
|
||||
watch,
|
||||
watchEffect,
|
||||
type ExtractPropTypes,
|
||||
} from 'vue';
|
||||
import {
|
||||
createNamespace,
|
||||
makeNumberProp,
|
||||
makeNumericProp,
|
||||
makeStringProp,
|
||||
truthProp,
|
||||
} from '../utils';
|
||||
|
||||
const [name, bem] = createNamespace('watermark');
|
||||
|
||||
export const watermarkProps = {
|
||||
width: makeNumberProp(100),
|
||||
height: makeNumberProp(100),
|
||||
rotate: makeNumericProp(-22),
|
||||
zIndex: makeNumberProp(100),
|
||||
content: String,
|
||||
image: String,
|
||||
fullPage: truthProp,
|
||||
gapX: makeNumberProp(0),
|
||||
gapY: makeNumberProp(0),
|
||||
fontColor: makeStringProp('#dcdee0'),
|
||||
opacity: makeNumberProp(1),
|
||||
};
|
||||
|
||||
export type WatermarkProps = ExtractPropTypes<typeof watermarkProps>;
|
||||
|
||||
export default defineComponent({
|
||||
name,
|
||||
|
||||
props: watermarkProps,
|
||||
|
||||
setup(props, { slots }) {
|
||||
const svgElRef = ref<HTMLDivElement>();
|
||||
|
||||
const watermarkUrl = ref('');
|
||||
const imageBase64 = ref('');
|
||||
const renderWatermark = () => {
|
||||
const svgInner = () => {
|
||||
if (props.image) {
|
||||
return (
|
||||
<image
|
||||
href={imageBase64.value}
|
||||
x="0"
|
||||
y="0"
|
||||
width={props.width}
|
||||
height={props.height}
|
||||
style={{
|
||||
transformOrigin: 'center',
|
||||
transform: `rotate(${props.rotate}deg)`,
|
||||
}}
|
||||
></image>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<foreignObject x="0" y="0" width={props.width} height={props.height}>
|
||||
<div
|
||||
// @ts-ignore
|
||||
xmlns="http://www.w3.org/1999/xhtml"
|
||||
style={{
|
||||
transform: `rotate(${props.rotate}deg)`,
|
||||
}}
|
||||
>
|
||||
{props.content ? (
|
||||
<span
|
||||
style={{
|
||||
color: props.fontColor,
|
||||
}}
|
||||
>
|
||||
{props.content}
|
||||
</span>
|
||||
) : (
|
||||
slots?.default?.()
|
||||
)}
|
||||
</div>
|
||||
</foreignObject>
|
||||
);
|
||||
};
|
||||
|
||||
const svgWidth = props.width + props.gapX;
|
||||
const svgHeight = props.height + props.gapY;
|
||||
|
||||
return (
|
||||
<svg
|
||||
viewBox={`0 0 ${svgWidth} ${svgHeight}`}
|
||||
width={svgWidth}
|
||||
height={svgHeight}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
style={{
|
||||
padding: `0 ${props.gapX}px ${props.gapY}px 0`,
|
||||
opacity: props.opacity,
|
||||
}}
|
||||
>
|
||||
{svgInner()}
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
const makeImageToBase64 = (url: string) => {
|
||||
const canvas = document.createElement('canvas');
|
||||
const image = new Image();
|
||||
image.crossOrigin = 'anonymous';
|
||||
image.referrerPolicy = 'no-referrer';
|
||||
image.onload = () => {
|
||||
canvas.width = image.naturalWidth;
|
||||
canvas.height = image.naturalHeight;
|
||||
const ctx = canvas.getContext('2d');
|
||||
ctx?.drawImage(image, 0, 0);
|
||||
imageBase64.value = canvas.toDataURL();
|
||||
};
|
||||
image.src = url;
|
||||
};
|
||||
|
||||
const makeSvgToBlobUrl = (svgStr: string) => {
|
||||
const svgBlob = new Blob([svgStr], {
|
||||
type: 'image/svg+xml;charset=utf-8',
|
||||
});
|
||||
return URL.createObjectURL(svgBlob);
|
||||
};
|
||||
|
||||
watchEffect(() => {
|
||||
if (props.image) {
|
||||
makeImageToBase64(props.image);
|
||||
}
|
||||
});
|
||||
|
||||
watch(
|
||||
() => [
|
||||
imageBase64.value,
|
||||
props.content,
|
||||
props.fontColor,
|
||||
props.height,
|
||||
props.width,
|
||||
props.rotate,
|
||||
props.gapX,
|
||||
props.gapY,
|
||||
],
|
||||
() => {
|
||||
// 路径为 renderWatermark渲染的实际HTML => SVG字符串转换为blob图片 => 放到background-image中。
|
||||
nextTick(() => {
|
||||
if (svgElRef.value) {
|
||||
if (watermarkUrl.value) {
|
||||
URL.revokeObjectURL(watermarkUrl.value);
|
||||
}
|
||||
watermarkUrl.value = makeSvgToBlobUrl(svgElRef.value.innerHTML);
|
||||
}
|
||||
});
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
}
|
||||
);
|
||||
|
||||
onUnmounted(() => {
|
||||
if (watermarkUrl.value) {
|
||||
URL.revokeObjectURL(watermarkUrl.value);
|
||||
}
|
||||
});
|
||||
|
||||
return () => (
|
||||
<div
|
||||
class={bem()}
|
||||
style={{
|
||||
position: props.fullPage ? 'fixed' : 'absolute',
|
||||
backgroundImage: `url(${watermarkUrl.value})`,
|
||||
zIndex: props.zIndex,
|
||||
}}
|
||||
>
|
||||
<div style={{ display: 'none' }} ref={svgElRef}>
|
||||
{renderWatermark()}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
});
|
141
packages/vant/src/watermark/demo/index.vue
Normal file
141
packages/vant/src/watermark/demo/index.vue
Normal file
@ -0,0 +1,141 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import VanButton from '../../button';
|
||||
import VanWatermark from '..';
|
||||
import { useTranslate } from '../../../docs/site';
|
||||
|
||||
const t = useTranslate({
|
||||
'zh-CN': {
|
||||
customOpacity: '自定义透明度',
|
||||
customGap: '自定义间隔',
|
||||
customImage: '自定义图片',
|
||||
customRotate: '自定义倾斜角度',
|
||||
displayRange: '显示范围',
|
||||
htmlWatermark: 'HTML 水印',
|
||||
textWatermark: '文字水印',
|
||||
imageWatermark: '图片水印',
|
||||
switch: '切换',
|
||||
},
|
||||
'en-US': {
|
||||
customOpacity: 'Custom opacity',
|
||||
customGap: 'Custom Gap',
|
||||
customRotate: 'Custom Rotate',
|
||||
displayRange: 'Display Range',
|
||||
htmlWatermark: 'HTML Watermark',
|
||||
textWatermark: 'Text Watermark',
|
||||
imageWatermark: 'Image Watermark',
|
||||
switch: 'Swtich',
|
||||
},
|
||||
});
|
||||
const baseWatermarkFlag = ref<'text' | 'image'>('text');
|
||||
const fullPage = ref(false);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<demo-block :title="t('basicUsage')">
|
||||
<div class="demo-watermark-wrapper">
|
||||
<div style="position: relative; z-index: 9999">
|
||||
<van-button
|
||||
@click="
|
||||
() => {
|
||||
baseWatermarkFlag = 'text';
|
||||
}
|
||||
"
|
||||
>{{ t('textWatermark') }}</van-button
|
||||
>
|
||||
<van-button
|
||||
@click="
|
||||
() => {
|
||||
baseWatermarkFlag = 'image';
|
||||
}
|
||||
"
|
||||
style="margin: 0 var(--van-padding-md)"
|
||||
>{{ t('imageWatermark') }}</van-button
|
||||
>
|
||||
</div>
|
||||
<van-watermark
|
||||
content="Vant"
|
||||
v-if="baseWatermarkFlag === 'text'"
|
||||
:full-page="false"
|
||||
></van-watermark>
|
||||
<van-watermark
|
||||
image="https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg"
|
||||
v-if="baseWatermarkFlag === 'image'"
|
||||
:full-page="false"
|
||||
></van-watermark>
|
||||
</div>
|
||||
</demo-block>
|
||||
|
||||
<demo-block :title="t('customGap')">
|
||||
<div class="demo-watermark-wrapper">
|
||||
<van-watermark
|
||||
image="https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg"
|
||||
:gap-x="20"
|
||||
:gap-y="10"
|
||||
:full-page="false"
|
||||
/>
|
||||
</div>
|
||||
</demo-block>
|
||||
|
||||
<demo-block :title="t('customOpacity')">
|
||||
<div class="demo-watermark-wrapper">
|
||||
<van-watermark
|
||||
:full-page="false"
|
||||
:opacity="0.5"
|
||||
image="https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg"
|
||||
>
|
||||
</van-watermark>
|
||||
</div>
|
||||
</demo-block>
|
||||
|
||||
<demo-block :title="t('customRotate')">
|
||||
<div class="demo-watermark-wrapper">
|
||||
<van-watermark
|
||||
image="https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg"
|
||||
rotate="22"
|
||||
:full-page="false"
|
||||
/>
|
||||
</div>
|
||||
</demo-block>
|
||||
|
||||
<demo-block :title="t('displayRange')">
|
||||
<div class="demo-watermark-wrapper">
|
||||
<van-button
|
||||
@click="
|
||||
() => {
|
||||
fullPage = !fullPage;
|
||||
}
|
||||
"
|
||||
>
|
||||
{{ t('switch') }}
|
||||
</van-button>
|
||||
<van-watermark
|
||||
:full-page="fullPage"
|
||||
content="vant watermark"
|
||||
font-color="rgba(0, 0, 0, 0.15)"
|
||||
>
|
||||
</van-watermark>
|
||||
</div>
|
||||
</demo-block>
|
||||
|
||||
<demo-block :title="t('htmlWatermark')">
|
||||
<div class="demo-watermark-wrapper">
|
||||
<van-watermark :width="150" :full-page="false">
|
||||
<div
|
||||
style="background: linear-gradient(45deg, #000 0, #000 50%, #fff 50%)"
|
||||
>
|
||||
<p style="mix-blend-mode: difference; color: #fff">Vant watermark</p>
|
||||
</div>
|
||||
</van-watermark>
|
||||
</div>
|
||||
</demo-block>
|
||||
</template>
|
||||
|
||||
<style lang="less">
|
||||
.demo-watermark-wrapper {
|
||||
position: relative;
|
||||
height: 150px;
|
||||
background-color: var(--van-background-2);
|
||||
padding: var(--van-padding-md);
|
||||
}
|
||||
</style>
|
8
packages/vant/src/watermark/index.less
Normal file
8
packages/vant/src/watermark/index.less
Normal file
@ -0,0 +1,8 @@
|
||||
.van-watermark {
|
||||
background-repeat: repeat;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
pointer-events: none;
|
||||
}
|
13
packages/vant/src/watermark/index.ts
Normal file
13
packages/vant/src/watermark/index.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import { withInstall } from '../utils';
|
||||
import _Watermark from './Watermark';
|
||||
|
||||
export const Watermark = withInstall(_Watermark);
|
||||
export default Watermark;
|
||||
export { watermarkProps } from './Watermark';
|
||||
export type { WatermarkProps } from './Watermark';
|
||||
|
||||
declare module 'vue' {
|
||||
export interface GlobalComponents {
|
||||
VanWatermark: typeof Watermark;
|
||||
}
|
||||
}
|
@ -0,0 +1,135 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`watermark should render content 1`] = `
|
||||
<div class="van-watermark"
|
||||
style="position: fixed; background-image: url(); z-index: 100;"
|
||||
>
|
||||
<div style="display: none;">
|
||||
<svg viewbox="0 0 100 100"
|
||||
width="100"
|
||||
height="100"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
style="padding: 0px 0px 0px 0px; opacity: 1;"
|
||||
>
|
||||
<foreignObject x="0"
|
||||
y="0"
|
||||
width="100"
|
||||
height="100"
|
||||
>
|
||||
<div xmlns="http://www.w3.org/1999/xhtml"
|
||||
style="transform: rotate(-22deg);"
|
||||
>
|
||||
<span style="color: red;">
|
||||
Vant
|
||||
</span>
|
||||
</div>
|
||||
</foreignObject>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`watermark should render html 1`] = `
|
||||
<div class="van-watermark"
|
||||
style="position: fixed; background-image: url(); z-index: 100;"
|
||||
>
|
||||
<div style="display: none;">
|
||||
<svg viewbox="0 0 100 100"
|
||||
width="100"
|
||||
height="100"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
style="padding: 0px 0px 0px 0px; opacity: 1;"
|
||||
>
|
||||
<foreignObject x="0"
|
||||
y="0"
|
||||
width="100"
|
||||
height="100"
|
||||
>
|
||||
<div xmlns="http://www.w3.org/1999/xhtml"
|
||||
style="transform: rotate(-22deg);"
|
||||
>
|
||||
vant watermark test
|
||||
</div>
|
||||
</foreignObject>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`watermark should render image 1`] = `
|
||||
<div class="van-watermark"
|
||||
style="position: fixed; background-image: url(); z-index: 100;"
|
||||
>
|
||||
<div style="display: none;">
|
||||
<svg viewbox="0 0 100 100"
|
||||
width="100"
|
||||
height="100"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
style="padding: 0px 0px 0px 0px; opacity: 0.5;"
|
||||
>
|
||||
<image href="base64Url"
|
||||
x="0"
|
||||
y="0"
|
||||
width="100"
|
||||
height="100"
|
||||
style="transform-origin: center; transform: rotate(-22deg);"
|
||||
>
|
||||
</image>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`watermark test false value fullPage 1`] = `
|
||||
<div class="van-watermark"
|
||||
style="position: absolute; background-image: url(); z-index: 100;"
|
||||
>
|
||||
<div style="display: none;">
|
||||
<svg viewbox="0 0 100 100"
|
||||
width="100"
|
||||
height="100"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
style="padding: 0px 0px 0px 0px; opacity: 1;"
|
||||
>
|
||||
<foreignObject x="0"
|
||||
y="0"
|
||||
width="100"
|
||||
height="100"
|
||||
>
|
||||
<div xmlns="http://www.w3.org/1999/xhtml"
|
||||
style="transform: rotate(-22deg);"
|
||||
>
|
||||
vant watermark test
|
||||
</div>
|
||||
</foreignObject>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`watermark test width, height, rotate, zIndex 1`] = `
|
||||
<div class="van-watermark"
|
||||
style="position: fixed; background-image: url(); z-index: 200;"
|
||||
>
|
||||
<div style="display: none;">
|
||||
<svg viewbox="0 0 20 20"
|
||||
width="20"
|
||||
height="20"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
style="padding: 0px 0px 0px 0px; opacity: 1;"
|
||||
>
|
||||
<foreignObject x="0"
|
||||
y="0"
|
||||
width="20"
|
||||
height="20"
|
||||
>
|
||||
<div xmlns="http://www.w3.org/1999/xhtml"
|
||||
style="transform: rotate(20deg);"
|
||||
>
|
||||
vant watermark test
|
||||
</div>
|
||||
</foreignObject>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
107
packages/vant/src/watermark/test/index.spec.ts
Normal file
107
packages/vant/src/watermark/test/index.spec.ts
Normal file
@ -0,0 +1,107 @@
|
||||
// @ts-nocheck
|
||||
import { Watermark } from '..';
|
||||
import { mount } from '../../../test';
|
||||
|
||||
describe('watermark', () => {
|
||||
beforeEach(() => {
|
||||
const createElement = document.createElement.bind(document);
|
||||
document.createElement = (tagName: string) => {
|
||||
if (tagName === 'canvas') {
|
||||
return {
|
||||
...createElement(tagName),
|
||||
getContext: () => {
|
||||
() => {};
|
||||
},
|
||||
toDataURL: () => 'base64Url',
|
||||
};
|
||||
}
|
||||
return createElement(tagName);
|
||||
};
|
||||
global.URL.createObjectURL = jest.fn(() => 'run to here');
|
||||
global.Image = class {
|
||||
crossOrigin = 'anonymous';
|
||||
|
||||
referrerPolicy = 'no-referrer';
|
||||
|
||||
naturalWidth = 800;
|
||||
|
||||
naturalHeight = 550;
|
||||
|
||||
onload: () => void = () => {};
|
||||
|
||||
// just mock to trigge onload
|
||||
_src = '';
|
||||
|
||||
get src() {
|
||||
return this._src;
|
||||
}
|
||||
|
||||
set src(val) {
|
||||
this._src = val;
|
||||
this.onload();
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
test('should render content', () => {
|
||||
const wrapper = mount(Watermark, {
|
||||
props: {
|
||||
content: 'Vant',
|
||||
fontColor: 'red',
|
||||
},
|
||||
});
|
||||
|
||||
expect(wrapper.html()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should render image', () => {
|
||||
const wrapper = mount(Watermark, {
|
||||
props: {
|
||||
content: 'Vant',
|
||||
image: 'https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg',
|
||||
opacity: 0.5,
|
||||
},
|
||||
});
|
||||
|
||||
expect(wrapper.html()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should render html', () => {
|
||||
const wrapper = mount(Watermark, {
|
||||
slots: {
|
||||
default: () => 'vant watermark test',
|
||||
},
|
||||
});
|
||||
|
||||
expect(wrapper.html()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('test width, height, rotate, zIndex', () => {
|
||||
const wrapper = mount(Watermark, {
|
||||
props: {
|
||||
width: 20,
|
||||
height: 20,
|
||||
rotate: 20,
|
||||
zIndex: 200,
|
||||
},
|
||||
slots: {
|
||||
default: () => 'vant watermark test',
|
||||
},
|
||||
});
|
||||
|
||||
expect(wrapper.html()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('test false value fullPage', () => {
|
||||
const wrapper = mount(Watermark, {
|
||||
props: {
|
||||
fullPage: false,
|
||||
},
|
||||
slots: {
|
||||
default: () => 'vant watermark test',
|
||||
},
|
||||
});
|
||||
|
||||
expect(wrapper.html()).toMatchSnapshot();
|
||||
});
|
||||
});
|
@ -344,6 +344,10 @@ location.href = location.href.replace('youzan.github.io', 'vant-ui.github.io');
|
||||
path: 'text-ellipsis',
|
||||
title: 'TextEllipsis 文本省略',
|
||||
},
|
||||
{
|
||||
path: 'watermark',
|
||||
title: 'Watermark 水印',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
@ -784,6 +788,10 @@ location.href = location.href.replace('youzan.github.io', 'vant-ui.github.io');
|
||||
path: 'text-ellipsis',
|
||||
title: 'TextEllipsis',
|
||||
},
|
||||
{
|
||||
path: 'watermark',
|
||||
title: 'Watermark',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user