-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* chore: init type define * fix: badge typo in readme * feat: plugin watermark * feat: add watmermark plugin * test: add tc for watermark, but should skip it * docs: add demos for watermark * test: add tc for mock * chore: fix cr * test: use jest-canvas-mock make ci works * chore: update demo * docs: add case panel * refactor: render watermark into div * chore: update
- Loading branch information
Showing
21 changed files
with
509 additions
and
101 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import { Graph } from '@/src'; | ||
import data from '@@/dataset/cluster.json'; | ||
import type { STDTestCase } from '../types'; | ||
|
||
export const pluginWatermarkImage: STDTestCase = async (context) => { | ||
const graph = new Graph({ | ||
...context, | ||
autoResize: true, | ||
data, | ||
layout: { type: 'd3force' }, | ||
plugins: [ | ||
{ | ||
type: 'watermark', | ||
width: 100, | ||
height: 100, | ||
imageURL: 'https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*7svFR6wkPMoAAAAAAAAAAAAADmJ7AQ/original', | ||
}, | ||
], | ||
}); | ||
|
||
await graph.render(); | ||
|
||
pluginWatermarkImage.form = (panel) => { | ||
const config = { | ||
width: 200, | ||
height: 100, | ||
fontSize: 20, | ||
textFill: 'red', | ||
}; | ||
return [ | ||
panel | ||
.add(config, 'width', 150, 400, 10) | ||
.name('Width') | ||
.onChange(() => {}), | ||
panel | ||
.add(config, 'height', 100, 200, 10) | ||
.name('Width') | ||
.onChange(() => {}), | ||
panel | ||
.add(config, 'fontSize', 10, 32, 1) | ||
.name('FontSize') | ||
.onChange(() => {}), | ||
]; | ||
}; | ||
|
||
return graph; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import { Graph, PluginOptions } from '@/src'; | ||
import data from '@@/dataset/cluster.json'; | ||
import { isObject } from '@antv/util'; | ||
import type { STDTestCase } from '../types'; | ||
|
||
export const pluginWatermark: STDTestCase = async (context) => { | ||
const graph = new Graph({ | ||
...context, | ||
autoResize: true, | ||
data, | ||
layout: { type: 'd3force' }, | ||
plugins: [ | ||
{ | ||
type: 'watermark', | ||
text: 'hello, \na watermark.', | ||
textFontSize: 12, | ||
}, | ||
], | ||
}); | ||
|
||
await graph.render(); | ||
|
||
function updatePlugin(type: string, config: object) { | ||
return (plugins: PluginOptions) => { | ||
return plugins.map((plugin) => { | ||
if (isObject(plugin) && plugin.type === type) return { ...plugin, ...config }; | ||
return plugin; | ||
}); | ||
}; | ||
} | ||
pluginWatermark.form = (panel) => { | ||
const config = { | ||
width: 200, | ||
height: 100, | ||
textFontSize: 12, | ||
}; | ||
return [ | ||
panel | ||
.add(config, 'width', 150, 400, 10) | ||
.name('Width') | ||
.onChange((width: number) => { | ||
graph.setPlugins(updatePlugin('watermark', { width })); | ||
}), | ||
panel | ||
.add(config, 'height', 100, 200, 10) | ||
.name('Height') | ||
.onChange((height: number) => { | ||
graph.setPlugins(updatePlugin('watermark', { height })); | ||
}), | ||
panel | ||
.add(config, 'textFontSize', 10, 32, 1) | ||
.name('TextFontSize') | ||
.onChange((textFontSize: number) => { | ||
graph.setPlugins(updatePlugin('watermark', { textFontSize })); | ||
}), | ||
]; | ||
}; | ||
|
||
return graph; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
import '@/src/preset'; | ||
import 'jest-canvas-mock'; | ||
import './utils/to-be-close-to'; | ||
import './utils/use-snapshot-matchers'; |
33 changes: 33 additions & 0 deletions
33
packages/g6/__tests__/unit/plugins/plugin-watermark.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import { pluginWatermark, pluginWatermarkImage } from '@@/demo/case'; | ||
import { createDemoGraph } from '@@/utils'; | ||
|
||
describe('plugin watermark', () => { | ||
it('watermark text', async () => { | ||
const graph = await createDemoGraph(pluginWatermark); | ||
const container = graph.getCanvas().getContainer()!; | ||
|
||
const el = container.querySelector('.g6-watermark') as HTMLDivElement; | ||
|
||
expect(graph.getPlugins()).toEqual([{ type: 'watermark', text: 'hello, \na watermark.', textFontSize: 12 }]); | ||
expect(el.style.backgroundImage).toContain('data:image/png;base64'); | ||
|
||
await graph.destroy(); | ||
expect(container.querySelector('.g6-watermark')).toBeFalsy(); | ||
}); | ||
|
||
it('watermark image', async () => { | ||
const graph = await createDemoGraph(pluginWatermarkImage); | ||
const container = graph.getCanvas().getContainer()!; | ||
|
||
expect(graph.getPlugins()).toEqual([ | ||
{ | ||
type: 'watermark', | ||
width: 100, | ||
height: 100, | ||
imageURL: 'https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*7svFR6wkPMoAAAAAAAAAAAAADmJ7AQ/original', | ||
}, | ||
]); | ||
await graph.destroy(); | ||
expect(container.querySelector('.g6-watermark')).toBeFalsy(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,7 @@ | ||
export { BasePlugin } from './base-plugin'; | ||
export { GridLine } from './grid-line'; | ||
export { Watermark } from './watermark'; | ||
|
||
export type { BasePluginOptions } from './base-plugin'; | ||
export type { GridLineOptions } from './grid-line'; | ||
export type { WatermarkOptions } from './watermark'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
import type { RuntimeContext } from '../runtime/types'; | ||
import { createPluginContainer } from '../utils/dom'; | ||
import { getImageWatermark, getTextWateramrk } from '../utils/watermark'; | ||
import type { BasePluginOptions } from './base-plugin'; | ||
import { BasePlugin } from './base-plugin'; | ||
|
||
export type WatermarkOptions = BasePluginOptions & { | ||
/** 单独一个水印的大小,这个水印最终会用来填充整个大小,所以 repeat 后的间距大小,通过这个 width height 设置 */ | ||
width?: number; | ||
height?: number; | ||
/** 透明度 */ | ||
opacity?: number; | ||
/** 旋转角度 */ | ||
rotate?: number; | ||
/** 图片地址,如果有值,则使用,否则使用文本 */ | ||
imageURL?: string; | ||
/** 水印文本 */ | ||
text?: string; | ||
/** 文本水印的文本样式 */ | ||
textFill: string; | ||
textFontSize: number; | ||
textFontFamily: string; | ||
textFontWeight: string; | ||
textFontVariant: string; | ||
textAlign: CanvasTextAlign; | ||
textBaseline: CanvasTextBaseline; | ||
/** 背景的 CSS 样式 */ | ||
backgroundAttachment: string; | ||
backgroundBlendMode: string; | ||
backgroundClip: string; | ||
backgroundColor: string; | ||
backgroundImage: string; | ||
backgroundOrigin: string; | ||
backgroundPosition: string; | ||
backgroundPositionX: string; | ||
backgroundPositionY: string; | ||
backgroundRepeat: string; | ||
backgroundSize: string; | ||
}; | ||
|
||
/** | ||
* <zh/> 支持使用文本和图片作为水印,实现原理是在 Graph 容器的 div 上加上 background-image 属性,然后就可以通过 css 来控制水印的位置和样式。 | ||
* 对于文本,会使用隐藏 canvas 转成图片的方式来实现。 | ||
* <en/> Support using text and images as watermarks. | ||
* The principle is to add the background-image property to the div of the Graph container, | ||
* and then you can control the position and style of the watermark through css. For text, | ||
* it will be converted to an image using a hidden canvas. | ||
*/ | ||
export class Watermark extends BasePlugin<WatermarkOptions> { | ||
static defaultOptions: Partial<WatermarkOptions> = { | ||
width: 200, | ||
height: 100, | ||
opacity: 0.2, | ||
rotate: Math.PI / 12, | ||
textFill: '#000', | ||
textFontSize: 16, | ||
textAlign: 'center', | ||
textBaseline: 'middle', | ||
backgroundRepeat: 'repeat', | ||
}; | ||
|
||
private $element: HTMLElement = createPluginContainer('watermark'); | ||
|
||
constructor(context: RuntimeContext, options: WatermarkOptions) { | ||
super(context, Object.assign({}, Watermark.defaultOptions, options)); | ||
|
||
const $container = this.context.canvas.getContainer(); | ||
$container!.appendChild(this.$element); | ||
|
||
this.update(options); | ||
} | ||
|
||
public async update(options: Partial<WatermarkOptions>) { | ||
super.update(options); | ||
|
||
const { width, height, text, imageURL, ...rest } = this.options; | ||
|
||
// Set the background style. | ||
Object.keys(rest).forEach((key) => { | ||
if (key.startsWith('background')) { | ||
// @ts-expect-error ignore | ||
this.$element.style[key] = options[key]; | ||
} | ||
}); | ||
|
||
// Set the background image. | ||
const base64 = imageURL | ||
? await getImageWatermark(width, height, imageURL, rest) | ||
: await getTextWateramrk(width, height, text, rest); | ||
this.$element.style.backgroundImage = `url(${base64})`; | ||
} | ||
|
||
public destroy(): void { | ||
super.destroy(); | ||
// Remove the background dom. | ||
this.$element.remove(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.