Merge pull request #12 from idrawjs/dev

Init testing
This commit is contained in:
大深海 2021-06-04 16:45:37 +08:00 committed by GitHub
commit faea696434
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
59 changed files with 691 additions and 126 deletions

69
__tests__/e2e.test.js Normal file
View file

@ -0,0 +1,69 @@
const fs = require('fs');
const path = require('path');
const assert = require('assert');
const jimp = require('jimp');
const pixelmatch = require('pixelmatch');
const pngjs = require('pngjs');
const { delay } = require('./../scripts/util/time');
const { pageList } = require('./../scripts/screen.config');
const { createScreenshot } = require('../scripts/util/screen');
const snapshotDir = path.join(__dirname, 'snapshot');
const diffDir = path.join(__dirname, 'diff');
const { PNG } = pngjs;
async function diff() {
const middlewares = [];
const diffRateList = [];
pageList.forEach((p) => {
middlewares.push(async (ctx = {}, next) => {
const { page, port } = ctx;
const width = p.w;
const height = p.h;
await page.setViewport( { width: p.w, height: p.h } );
const pageUrl = `http://127.0.0.1:${port}/packages/${p.path || ''}`;
await page.goto(pageUrl);
await delay(p.delay || 100);
const buf = await page.screenshot();
const snapshotPicPath = parsePicPath(path.join(snapshotDir, p.path));
const actual = (await jimp.read(buf)).scale(1).quality(100).bitmap;
const expected = (await jimp.read(fs.readFileSync(snapshotPicPath))).bitmap;
const diffBuf = new PNG({ width, height });
const failedPixel = pixelmatch(expected.data, actual.data, diffBuf.data, actual.width, actual.height);
const failRate = failedPixel / (width * height);
if (failRate > 0) {
(await jimp.read(diffBuf)).scale(1).quality(100).write(parsePicPath(path.join(diffDir, p.path)));
}
diffRateList.push(failRate);
await next();
});
});
await createScreenshot(middlewares, { baseDir: path.join(__dirname, '..') });
return diffRateList;
}
function parsePicPath(pagePath) {
// const picPath = pagePath.replace(/\.html$/, '.jpg');
const picPath = pagePath + '.jpg';
return picPath;
}
describe('Screenshot testing', function() {
it('testing...', function(done){
this.timeout(1000 * 60 * 2);
diff().then((rateList) => {
assert.ok(Array.isArray(rateList));
assert.ok(rateList.length > 0);
rateList.forEach((rate) => {
console.log('diff-rate =', rate);
assert.ok(rate < 0.05);
});
done();
}).catch(done);
});
});

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 KiB

32
jest.config.js Normal file
View file

@ -0,0 +1,32 @@
module.exports = {
// "collectCoverage": true,
"coverageDirectory": "reports",
"collectCoverageFrom": [
"packages/**/src/**/*.ts",
"!packages/**/node_modules/**",
"!**/node_modules/**"
],
"coverageReporters": [
// "clover",
// "html",
"text-summary"
],
"coverageThreshold": {
"global": {
"branches": 80,
"functions": 80,
"lines": 80,
"statements": 80
}
},
"moduleFileExtensions": [
"js", "ts"
],
"modulePaths": [
"<rootDir>"
],
"testRegex": "(/packages/([^\/]{1,})/__tests__/.*|\\.test)\\.ts$",
"setupFiles": [
"jest-canvas-mock"
]
}

View file

@ -21,9 +21,11 @@
"@babel/preset-typescript": "^7.13.0",
"@microsoft/api-extractor": "^7.13.2",
"@rollup/plugin-node-resolve": "^11.2.1",
"@types/jest": "^26.0.23",
"@typescript-eslint/eslint-plugin": "^4.25.0",
"@typescript-eslint/parser": "^4.25.0",
"babel-jest": "^26.6.3",
"canvas": "^2.8.0",
"chalk": "^4.1.0",
"eslint": "^7.27.0",
"execa": "^5.0.0",
@ -31,6 +33,7 @@
"http-server": "^0.12.3",
"husky": "^6.0.0",
"jest": "^26.6.3",
"jest-canvas-mock": "^2.3.1",
"jimp": "^0.16.1",
"koa-compose": "^4.1.0",
"lerna": "^3.22.1",

View file

@ -0,0 +1,129 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`testing 1`] = `
Array [
Object {
"props": Object {
"height": 1600,
"width": 2400,
"x": 0,
"y": 0,
},
"transform": Array [
1,
0,
0,
1,
0,
0,
],
"type": "clearRect",
},
Object {
"props": Object {
"height": 1600,
"width": 2400,
"x": 0,
"y": 0,
},
"transform": Array [
1,
0,
0,
1,
0,
0,
],
"type": "clearRect",
},
Object {
"props": Object {
"dHeight": 1600,
"dWidth": 2400,
"dx": 0,
"dy": 0,
"img": <canvas
height="1600"
width="2400"
/>,
"sHeight": 1600,
"sWidth": 2400,
"sx": 0,
"sy": 0,
},
"transform": Array [
1,
0,
0,
1,
0,
0,
],
"type": "drawImage",
},
]
`;
exports[`testing 2`] = `
Array [
Object {
"props": Object {
"height": 1600,
"width": 2400,
"x": 0,
"y": 0,
},
"transform": Array [
1,
0,
0,
1,
0,
0,
],
"type": "clearRect",
},
Object {
"props": Object {
"height": 1600,
"width": 2400,
"x": 0,
"y": 0,
},
"transform": Array [
1,
0,
0,
1,
0,
0,
],
"type": "clearRect",
},
Object {
"props": Object {
"dHeight": 1600,
"dWidth": 2400,
"dx": 0,
"dy": 0,
"img": <canvas
height="1600"
width="2400"
/>,
"sHeight": 1600,
"sWidth": 2400,
"sx": 0,
"sy": 0,
},
"transform": Array [
1,
0,
0,
1,
0,
0,
],
"type": "drawImage",
},
]
`;

View file

@ -0,0 +1,81 @@
import Board from './../src';
test('testing', async () => {
document.body.innerHTML = `
<div id="mount"></div>
`;
const opts = {
width: 600,
height: 400,
devicePixelRatio: 4
}
const mount = document.querySelector('#mount') as HTMLDivElement;
const board = new Board(mount, opts);
const ctx = board.getContext();
const data = {
elements: [
{
x: 10,
y: 10,
w: 200,
h: 120,
type: 'rect',
desc: {
color: '#f0f0f0',
}
},
{
x: 80,
y: 80,
w: 200,
h: 120,
type: 'rect',
desc: {
color: '#cccccc',
}
},
{
x: 160,
y: 160,
w: 200,
h: 120,
type: 'rect',
desc: {
color: '#c0c0c0',
}
},
{
x: 400 - 10,
y: 300 - 10,
w: 200,
h: 100,
type: 'rect',
desc: {
color: '#e0e0e0',
}
}
]
};
board.clear();
ctx.clearRect(0, 0, opts.width, opts.height);
ctx.setFillStyle('#ffffff');
ctx.fillRect(0, 0, opts.width, opts.height);
data.elements.forEach(ele => {
ctx.setFillStyle(ele.desc.color);
ctx.fillRect(ele.x, ele.y, ele.w, ele.h);
});
board.draw();
const originCtx = board.getOriginContext();
// @ts-ignore;
const originCalls = originCtx.__getDrawCalls();
expect(originCalls).toMatchSnapshot();
const displayCtx = board.getDisplayContext();
// @ts-ignore;
const displayCalls = displayCtx.__getDrawCalls();
expect(displayCalls).toMatchSnapshot();
});

View file

@ -26,7 +26,7 @@ function isPointInElement(board, p = {x, y}) {
function moveElement(board, idx, moveX, moveY) {
const data = getData();
const scale = getScale();
const scale = getScale() || 1;
if (data.elements[idx]) {
// data.elements[idx].x += (moveX * scale * opts.devicePixelRatio);
// data.elements[idx].y += (moveY * scale * opts.devicePixelRatio);

View file

@ -3,6 +3,9 @@ let hasInited = false;
export function doScale(board, scale) {
if (hasInited === true) return;
if (!input) {
return;
}
if (scale > 0) {
input.value = scale;
board.scale(scale);
@ -19,6 +22,9 @@ export function doScale(board, scale) {
}
export function getScale() {
if (!input) {
return;
}
let val = 1;
if (input.value * 1 > 0) {
val = input.value * 1;

View file

@ -4,6 +4,9 @@ let hasInited = false;
export function doScroll(board, conf = {}) {
if (hasInited === true) return;
if (!(inputX && inputY)) {
return;
}
if (conf.scrollX >= 0) {
inputX.value = conf.scrollX;

View file

@ -0,0 +1,29 @@
<html>
<head>
<style></style>
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
<style>
html,body {
margin: 0;
padding: 0;
}
#mount canvas {
border-right: 1px solid #aaaaaa40;
border-bottom: 1px solid #aaaaaa40;
background-image:
linear-gradient(#aaaaaa40 1px, transparent 0),
linear-gradient(90deg, #aaaaaa40 1px, transparent 0),
linear-gradient(#aaa 1px, transparent 0),
linear-gradient(90deg, #aaa 1px, transparent 0);
background-size: 10px 10px, 10px 10px, 50px 50px, 50px 50px;
}
</style>
</head>
<body>
<div id="mount"></div>
<script src="./../../dist/index.global.js"></script>
<script type="module" src="./main.js"></script>
</body>
</html>

View file

@ -22,6 +22,7 @@ class Board {
private _hasRendered = false;
private _ctx: Context;
private _displayCtx: CanvasRenderingContext2D;
private _originCtx: CanvasRenderingContext2D;
private _scaleRatio = 1;
private _scrollX = 0;
private _scrollY = 0;
@ -33,15 +34,22 @@ class Board {
this._displayCanvas = document.createElement('canvas');
this._mount.appendChild(this._displayCanvas);
this._opts = this._parsePrivateOptions(opts);
const ctx = this._canvas.getContext('2d') as CanvasRenderingContext2D;
const displayCtx = this._displayCanvas.getContext('2d') as CanvasRenderingContext2D;
this._ctx = new Context(ctx, this._opts);
this._displayCtx = displayCtx;
this._originCtx = this._canvas.getContext('2d') as CanvasRenderingContext2D;
this._displayCtx = this._displayCanvas.getContext('2d') as CanvasRenderingContext2D;
this._ctx = new Context(this._originCtx, this._opts);
this._watcher = new Watcher(this._displayCanvas);
this._render();
}
getDisplayContext(): CanvasRenderingContext2D {
return this._displayCtx;
}
getOriginContext(): CanvasRenderingContext2D {
return this._displayCtx;
}
getContext(): Context {
return this._ctx;
}

View file

@ -38,7 +38,11 @@ class Context implements TypeContext {
}
calcDeviceNum(num: number): number {
return this._opts.devicePixelRatio * num;
return num * this._opts.devicePixelRatio;
}
calcScreenNum(num: number): number {
return num / this._opts.devicePixelRatio;
}
getSize() {

View file

@ -1,17 +0,0 @@
import dataRect from './rect.js';
import dataImage from './image.js';
import dataSVG from './svg.js';
import dataText from './text.js';
const url = new URLSearchParams(window.location.search);
const dataMap = {
'rect': dataRect,
'image': dataImage,
'svg': dataSVG,
'text': dataText
}
export function getData() {
return dataMap[url.get('data')] || dataMap['rect'];
}

View file

@ -1,73 +0,0 @@
const data = {
// bgColor: '#ffffff',
elements: [
{
name: 'text-001',
x: 10,
y: 10,
w: 200,
h: 100,
type: 'text',
borderRadius: 20,
borderWidth: 2,
borderColor: '#bd0b64',
desc: {
fontSize: 20,
color: '#333333',
text: '生活就像海洋,只有意志坚强的人,才能到达彼岸。',
fontFamily: ''
}
},
{
name: 'text-002',
x: 80,
y: 80,
w: 200,
h: 120,
// angle: 30,
type: 'text',
borderRadius: 60,
borderWidth: 10,
borderColor: '#bd0b64',
desc: {
fontSize: 20,
text: 'Hello Text',
color: '#666666',
}
},
// {
// name: 'text-003',
// x: 160,
// y: 160,
// w: 200,
// h: 20,
// type: 'text',
// angle: 80,
// borderRadius: 20,
// borderWidth: 10,
// borderColor: '#bd0b64',
// desc: {
// color: '#c0c0c0',
// }
// },
// {
// name: 'text-004',
// x: 400 - 10,
// y: 300 - 10,
// w: 200,
// h: 100,
// type: 'text',
// borderRadius: 20,
// borderWidth: 10,
// borderColor: '#bd0b64',
// desc: {
// color: '#e0e0e0',
// }
// }
]
}
export default data;

View file

@ -0,0 +1,25 @@
<html>
<head>
<style></style>
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
<link rel="stylesheet" href="./css/index.css" />
<style>
html, body { margin: 0; padding: 0; }
.dashboard .row { margin: 0 }
</style>
</head>
<body>
<div class="dashboard">
<div class="row">
<div class="col">
<div id="mount"></div>
</div>
</div>
</div>
<script src="./../../dist/index.global.js"></script>
<script type="module" src="./lib/main.js"></script>
</body>
</html>

View file

@ -31,7 +31,7 @@
</div>
<script src="./../dist/index.global.js"></script>
<script type="module" src="./main.js"></script>
<script src="./../../dist/index.global.js"></script>
<script type="module" src="./lib/main.js"></script>
</body>
</html>

View file

@ -15,7 +15,7 @@ const data = {
// angle: 30,
// angle: 0,
desc: {
src: './images/computer.png',
src: './../images/computer.png',
}
},
{
@ -30,7 +30,7 @@ const data = {
borderColor: '#bd0b64',
type: 'image',
desc: {
src: './images/chart.png',
src: './../images/chart.png',
}
},
{
@ -42,7 +42,7 @@ const data = {
type: 'image',
angle: 80,
desc: {
src: './images/phone.png',
src: './../images/phone.png',
}
},
{
@ -53,7 +53,7 @@ const data = {
h: 100,
type: 'image',
desc: {
src: './images/building-001.png',
src: './../images/building-001.png',
}
},
{
@ -64,7 +64,7 @@ const data = {
h: 100,
type: 'image',
desc: {
src: './images/building-002.png',
src: './../images/building-002.png',
}
},
{
@ -75,7 +75,7 @@ const data = {
h: 100,
type: 'image',
desc: {
src: './images/building-003.png',
src: './../images/building-003.png',
}
}
]

View file

@ -0,0 +1,42 @@
import dataRect from './rect.js';
import dataImage from './image.js';
import dataSVG from './svg.js';
import dataText from './text.js';
const url = new URLSearchParams(window.location.search);
const dataMap = {
'rect': dataRect,
'image': dataImage,
'svg': dataSVG,
'text': dataText
}
export function getData() {
return dataMap[getPageName()] || dataMap[url.get('data')] || dataMap['rect'];
}
function getPageName() {
// const pathname = window.location.pathname || '';
// const reg = /(?<pageName>[\w+]{1,})\.html$/;
// const page = reg.exec(pathname)?.groups?.pageName || '';
// return page;
const pathname = window.location.pathname || '';
const list = pathname.split('/');
let pageName = list.pop() || '';
pageName = pageName.replace(/\.html$/ig, '');
return pageName;
// return getQueryString('data') || 'rect';
}
// function getQueryString(name) {
// let reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
// let r = window.location.search.substr(1).match(reg);
// if (r != null) {
// return decodeURIComponent(r[2]);
// };
// return null;
// }

View file

@ -0,0 +1,80 @@
const data = {
// bgColor: '#ffffff',
elements: [
{
name: 'text-001',
x: 10,
y: 10,
w: 200,
h: 100,
type: 'text',
borderRadius: 20,
borderWidth: 2,
borderColor: '#bd0b64',
desc: {
fontSize: 20,
color: '#333333',
text: '生活就像海洋,只有意志坚强的人,才能到达彼岸。',
fontFamily: ''
}
},
{
name: 'text-002',
x: 80,
y: 80,
w: 200,
h: 120,
// angle: 30,
type: 'text',
borderRadius: 60,
borderWidth: 10,
borderColor: '#bd0b64',
desc: {
fontSize: 20,
text: 'Hello Text',
color: '#666666',
}
},
{
name: 'text-003',
x: 160,
y: 160,
w: 200,
h: 100,
type: 'text',
borderRadius: 20,
borderWidth: 2,
borderColor: '#bd0b64',
desc: {
fontSize: 20,
color: '#333333',
text: '生活就像海洋,只有意志坚强的人,才能到达彼岸。',
fontFamily: '',
textAlign: 'right',
}
},
{
name: 'text-004',
x: 400 - 10,
y: 300 - 10,
w: 200,
h: 100,
type: 'text',
borderRadius: 20,
borderWidth: 2,
borderColor: '#bd0b64',
desc: {
fontSize: 20,
color: '#333333',
text: '生活就像海洋,只有意志坚强的人,才能到达彼岸。',
fontFamily: '',
textAlign: 'left',
}
}
]
}
export default data;

View file

@ -5,6 +5,7 @@ let hasInited = false;
export function doElemens(core) {
if (hasInited === true) return;
if (!dom) return;
renderElemens(core);
listenElements(core);
}

View file

@ -1,16 +1,11 @@
import { getData } from './lib/data/index.js';
import { doScale } from './lib/scale.js';
import { doScroll } from './lib/scroll.js';
import { doElemens } from './lib/element.js';
import { getData } from './data/index.js';
import { doScale } from './scale.js';
import { doScroll } from './scroll.js';
import { doElemens } from './element.js';
const { Core } = window.iDraw;
const data = getData();
const mount = document.querySelector('#mount');
// const defaultConf = {
// scale: 0.8,
// scrollX: 100,
// scrollY: 50,
// }
const defaultConf = {
scale: 1,
@ -23,9 +18,11 @@ const core = new Core(mount, {
devicePixelRatio: 4
});
console.log('core ===', core);
core.setData(data);
core.draw();
doScale(core, defaultConf.scale);
doScroll(core, defaultConf);
doElemens(core);

View file

@ -3,6 +3,7 @@ let hasInited = false;
export function doScale(core, scale) {
if (hasInited === true) return;
if (!input) return;
if (scale > 0) {
input.value = scale;
core.scale(scale);

View file

@ -3,7 +3,8 @@ const inputY = document.querySelector('#scrollY');
let hasInited = false;
export function doScroll(core, conf = {}) {
if (hasInited === true) return;
if (hasInited === true) return;
if (!(inputY && inputX)) return;
if (conf.scrollX >= 0) {
inputX.value = conf.scrollX;

View file

@ -0,0 +1,25 @@
<html>
<head>
<style></style>
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
<link rel="stylesheet" href="./css/index.css" />
<style>
html, body { margin: 0; padding: 0; }
.dashboard .row { margin: 0 }
</style>
</head>
<body>
<div class="dashboard">
<div class="row">
<div class="col">
<div id="mount"></div>
</div>
</div>
</div>
<script src="./../../dist/index.global.js"></script>
<script type="module" src="./lib/main.js"></script>
</body>
</html>

View file

@ -0,0 +1,25 @@
<html>
<head>
<style></style>
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
<link rel="stylesheet" href="./css/index.css" />
<style>
html, body { margin: 0; padding: 0; }
.dashboard .row { margin: 0 }
</style>
</head>
<body>
<div class="dashboard">
<div class="row">
<div class="col">
<div id="mount"></div>
</div>
</div>
</div>
<script src="./../../dist/index.global.js"></script>
<script type="module" src="./lib/main.js"></script>
</body>
</html>

View file

@ -0,0 +1,25 @@
<html>
<head>
<style></style>
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
<link rel="stylesheet" href="./css/index.css" />
<style>
html, body { margin: 0; padding: 0; }
.dashboard .row { margin: 0 }
</style>
</head>
<body>
<div class="dashboard">
<div class="row">
<div class="col">
<div id="mount"></div>
</div>
</div>
</div>
<script src="./../../dist/index.global.js"></script>
<script type="module" src="./lib/main.js"></script>
</body>
</html>

View file

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View file

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View file

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View file

Before

Width:  |  Height:  |  Size: 222 KiB

After

Width:  |  Height:  |  Size: 222 KiB

View file

Before

Width:  |  Height:  |  Size: 142 KiB

After

Width:  |  Height:  |  Size: 142 KiB

View file

Before

Width:  |  Height:  |  Size: 124 KiB

After

Width:  |  Height:  |  Size: 124 KiB

View file

@ -1,10 +1,13 @@
import { TypeData, TypePoint, TypeHelperWrapperDotDirection, TypeConfig, TypeConfigStrict } from '@idraw/types';
import Board from '@idraw/board';
import util from '@idraw/util';
import { Renderer } from './lib/renderer';
import { Element } from './lib/element';
import { Helper } from './lib/helper';
import { mergeConfig } from './lib/config';
const { time } = util;
type Options = {
width: number;
height: number;
@ -130,7 +133,7 @@ class Core {
}
this[_board].on('point', this._handlePoint.bind(this));
this[_board].on('moveStart', this._handleMoveStart.bind(this));
this[_board].on('move', this._handleMove.bind(this));
this[_board].on('move', time.throttle(this._handleMove.bind(this), 16));
this[_board].on('moveEnd', this._handleMoveEnd.bind(this));
}

View file

@ -34,18 +34,23 @@ export function drawContext(
switch (elem.type) {
case 'rect': {
drawRect(ctx, elem as TypeElement<'rect'>);
break;
}
case 'text': {
drawText(ctx, elem as TypeElement<'text'>, loader, helperConfig);
break;
}
case 'image': {
drawImage(ctx, elem as TypeElement<'image'>, loader, helperConfig);
break;
}
case 'svg': {
drawSVG(ctx, elem as TypeElement<'svg'>, loader, helperConfig);
break;
}
default: {
// nothing
break;
}
}
}

View file

@ -22,6 +22,7 @@ export function drawText(
...{
fontSize: 12,
fontFamily: 'sans-serif',
textAlign: 'center',
},
...elem.desc
};
@ -32,7 +33,7 @@ export function drawText(
fontFamily: desc.fontFamily
});
const fontHeight = desc.lineHeight || desc.fontSize;
const lines: {text: string, width: number}[] = [];
let lineText = '';
let lineNum = 0;
for (let i = 0; i < desc.text.length; i++) {
@ -40,7 +41,10 @@ export function drawText(
if (ctx.measureText(lineText + (desc.text[i] || '')).width < ctx.calcDeviceNum(elem.w)) {
lineText += (desc.text[i] || '');
} else {
ctx.fillText(lineText, elem.x, elem.y + lineNum * fontHeight);
lines.push({
text: lineText,
width: ctx.calcScreenNum(ctx.measureText(lineText).width),
});
lineText = (desc.text[i] || '');
lineNum ++;
}
@ -49,15 +53,35 @@ export function drawText(
}
if (lineText && desc.text.length - 1 === i) {
if ((lineNum + 1) * fontHeight < elem.h) {
ctx.fillText(lineText, elem.x, elem.y + lineNum * fontHeight);
lines.push({
text: lineText,
width: ctx.calcScreenNum(ctx.measureText(lineText).width),
});
break;
}
}
}
// draw text lines
let _y = elem.y;
if (lines.length * fontHeight < elem.h) {
_y += ((elem.h - lines.length * fontHeight) / 2);
}
lines.forEach((line, i) => {
let _x = elem.x;
if (desc.textAlign === 'center') {
_x = elem.x + (elem.w - line.width) / 2
} else if (desc.textAlign === 'right') {
_x = elem.x + (elem.w - line.width);
}
ctx.fillText(line.text, _x, _y + fontHeight * i);
});
});
}
// export function createTextSVG(elem: TypeElement<'text'>): string {
// const svg = `
// <svg xmlns="http://www.w3.org/2000/svg" width="${elem.w}" height = "${elem.h}">

View file

@ -15,6 +15,7 @@ interface TypeContext {
devicePixelRatio: number;
};
calcDeviceNum(num: number): number;
calcScreenNum(num: number): number;
setFillStyle(color: string | CanvasPattern): void;
fill(fillRule?: CanvasFillRule | undefined): void;

View file

@ -35,7 +35,8 @@ type TypeElemDescText = {
lineHeight?: number;
fontWeight?: string;
fontFamily?: string;
backgroundColor?: string;
textAlign?: 'center' | 'left' | 'right'
// backgroundColor?: string;
}
type TypeElemDescCircle = {

View file

@ -51,7 +51,7 @@ function createConfigItem(params) {
format,
name: name,
esModule: esModule === true,
sourcemap: true,
// sourcemap: true,
exports
},
plugins: [

View file

@ -1,7 +1,10 @@
const pageList = [
// { path: 'paint/examples/path/draw.html', w: 600, h: 600, delay: 200 },
// { path: 'paint/examples/path/play.html', w: 600, h: 600, delay: 8000 },
{ path: 'drag-core/examples/demo.html', w: 500, h: 1000, delay: 2000 },
{ path: 'board/examples/features/test.html', w: 600, h: 400, delay: 1000 },
{ path: 'core/examples/features/rect.html', w: 600, h: 400, delay: 1000 },
{ path: 'core/examples/features/text.html', w: 600, h: 400, delay: 1000 },
{ path: 'core/examples/features/svg.html', w: 600, h: 400, delay: 1000 },
{ path: 'core/examples/features/image.html', w: 600, h: 400, delay: 1000 },
// { path: 'core/examples/test.html', w: 600, h: 600, delay: 8000 },
]
module.exports = {

View file

@ -2,6 +2,7 @@ const jimp = require('jimp');
const path = require('path');
const { delay } = require('./util/time');
const { createScreenshot } = require('./util/screen');
const { removeFullDir } = require('./util/file');
const { pageList } = require('./screen.config');
const snapshotDir = path.join(__dirname, '..', '__tests__', 'snapshot');
@ -9,13 +10,18 @@ const snapshotDir = path.join(__dirname, '..', '__tests__', 'snapshot');
main();
async function main() {
removeFullDir(snapshotDir);
const middlewares = [];
pageList.forEach((p) => {
middlewares.push(async (ctx = {}, next) => {
const { page, port } = ctx;
await page.setViewport( { width: p.w, height: p.h } );
const pageUrl = `http://127.0.0.1:${port}/packages/${p.path || ''}`;
await page.goto(pageUrl);
const result = await page.goto(pageUrl);
if (result.status() === 404) {
console.error(`404 Not Found: ${pageUrl}`)
throw Error('404 status code found in result')
}
await delay(p.delay || 100);
const buf = await page.screenshot();
(await jimp.read(buf)).scale(1).quality(100).write(createPicPath(p.path));
@ -28,7 +34,7 @@ async function main() {
function createPicPath(pagePath) {
let picPath = path.join(snapshotDir, pagePath);
picPath = picPath.replace(/\.html$/, '.jpg');
picPath = picPath + '.jpg'; // picPath.replace(/\.html$/, '.jpg');
return picPath;
}

26
scripts/util/file.js Normal file
View file

@ -0,0 +1,26 @@
const fs = require('fs');
const path = require('path');
function removeFullDir(dirPath) {
let files = [];
if (fs.existsSync(dirPath)) {
files = fs.readdirSync(dirPath);
files.forEach((filename) => {
let curPath = path.join(dirPath, filename);
const stat = fs.statSync(curPath);
if(stat.isDirectory()) {
removeFullDir(curPath);
} else if (stat.isFile()) {
// fs.unlinkSync(curPath);
fs.rmSync(curPath);
} else {
fs.unlinkSync(curPath);
}
});
fs.rmdirSync(dirPath);
}
}
module.exports = {
removeFullDir,
}