提交 5c0cf1ec 编辑于 作者: wenxiangdong's avatar wenxiangdong
浏览文件

init

上级
.DS_Store
node_modules/
/dist/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="dist/main.js"></script>
<style>
#app {
margin: auto;
text-align: center;
}
button {
margin: 5px;
padding: 10px;
border: 1px solid #dcdee2;
border-radius: 5px;
cursor: pointer;
outline: none;
background-color: white;
color: #515a6e;
}
.side {
position: absolute;
top: 70px;
left: 5%;
border: 1px solid #dcdee2;
padding: 20px;
text-align: left;
box-shadow: rgba(0, 0, 0, 0.1) 0 0 5px;
max-height: 80%;
overflow-y: auto;
background-color: white;
z-index: 900;
}
.state-item {
margin: 5px auto;
}
.state-item:hover {
color: #19be6b;
}
.default-button:hover {
box-shadow: rgba(0, 0, 0, 0.1) 0 0 5px;
}
.default-button:active {
box-shadow: none;
}
.primary-button {
background-color: #19be6b;
color: white;
}
.primary-button:hover {
background-color: #10e090;
}
.primary-button:active {
background-color: #19be6b;
}
.title-text {
color: #17233d;
}
.primary-text {
color: #515a6e;
}
.accent {
color: #2db7f5;
}
input {
padding: 5px;
}
.menu-bar {
height: 70px;
}
body {
padding: 0;
margin: 0;
}
</style>
</head>
<body>
<div id="app">
<div class="menu-bar">
<button class="default-button" id="new-btn">新建</button>
<button class="default-button" id="save-btn">保存</button>
<!--<button class="default-button" id="undoBtn">撤销</button>-->
</div>
<div id="container">
</div>
<div class="side">
<h3>快照</h3>
<ul id="state-list"></ul>
</div>
</div>
</body>
</html>
\ No newline at end of file
此差异已折叠。
{
"name": "drawing-panel",
"version": "1.0.0",
"description": "",
"main": "main.js",
"scripts": {
"build": "webpack",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"devDependencies": {
"ts-loader": "^5.1.0",
"typescript": "^3.0.3",
"webpack": "^4.18.0",
"webpack-cli": "^3.1.0"
},
"dependencies": {
"@types/jquery": "^3.3.6",
"jquery": "^3.3.1"
}
}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var logger_1 = require("../utils/logger");
var PanelState = /** @class */ (function () {
function PanelState(id, data) {
this.id = id;
this.data = data;
}
return PanelState;
}());
exports.PanelState = PanelState;
var PanelStore = /** @class */ (function () {
function PanelStore(states) {
this.states = states;
}
return PanelStore;
}());
exports.PanelStore = PanelStore;
var DrawingPanel = /** @class */ (function () {
function DrawingPanel(containerID, options) {
if (containerID === void 0) { containerID = 'container'; }
var _this = this;
this.onDrawingEnd = function (shape) {
logger_1.default.info(DrawingPanel.TAG, '画完了', shape);
var ctx = _this.canvas.getContext('2d');
ctx.save();
ctx.fillStyle = DrawingPanel.labelColor;
ctx.font = DrawingPanel.labelFont;
ctx.fillText('未定义', shape.startPoint.x, shape.startPoint.y);
ctx.restore();
};
this.container = document.getElementById(containerID);
this.drawing = false;
// 准备options
options = options || {};
for (var key in DrawingPanel.defaultOptions) {
options[key] = options[key] || DrawingPanel.defaultOptions[key];
}
for (var key in options.style) {
options.style[key] = options.style[key] || DrawingPanel.defaultOptions.style[key];
}
this.initCanvas(options);
}
// 切换画图工具
DrawingPanel.prototype.setDrawingTool = function (tool) {
if (this.drawingTool) {
this.drawingTool.stop();
}
this.drawingTool = tool;
this.drawingTool.init(this.onDrawingEnd);
};
DrawingPanel.prototype.getCanvas = function () {
return this.canvas;
};
/**
* 保存当前画面
* @return {PanelState[]} 目前状态列表
*/
DrawingPanel.prototype.saveCanvas = function () {
var ctx = this.canvas.getContext('2d');
var data = this.canvas.toDataURL();
// let data = ctx.getImageData(0, 0, this.canvas.width, this.canvas.height);
var store = DrawingPanel.getPanelStore();
var id = new Date().getTime().toString() + 'state';
store.states.push(new PanelState(id, data));
DrawingPanel.savePanelStore(store);
return store.states;
};
/**
* 恢复某个画面
* @param {PanelState} state
*/
DrawingPanel.prototype.restoreCanvas = function (state) {
this.resetCanvas();
var ctx = this.canvas.getContext('2d');
var pic = new Image();
pic.src = state.data.toString();
pic.onload = function () {
ctx.drawImage(pic, 0, 0);
};
};
DrawingPanel.prototype.getPanelStates = function () {
return DrawingPanel.getPanelStore().states;
};
/**
* 新一个canvas
* 这里实现用的是清除画布内容
*/
DrawingPanel.prototype.resetCanvas = function () {
if (!this.canvas) {
this.initCanvas(DrawingPanel.defaultOptions);
}
var ctx = this.canvas.getContext('2d');
ctx.clearRect(0, 0, this.options.width, this.options.height);
};
DrawingPanel.getPanelStore = function () {
var store;
var temp = localStorage.getItem(DrawingPanel.PANEL_STORE);
if (temp) {
store = JSON.parse(temp);
}
else {
store = new PanelStore([]);
}
return store;
};
DrawingPanel.savePanelStore = function (store) {
var json = JSON.stringify(store);
logger_1.default.info(DrawingPanel.TAG, '', json);
localStorage.setItem(DrawingPanel.PANEL_STORE, json);
};
DrawingPanel.prototype.initCanvas = function (options) {
var container = this.container;
var errorMsg = '创建画板失败';
if (!container) {
throw new Error(errorMsg);
}
this.canvas = document.createElement('canvas');
if (!this.canvas) {
throw new Error(errorMsg);
}
var canvas = this.canvas;
canvas.width = options.width;
canvas.height = options.height;
for (var key in options.style) {
canvas.style[key] = options.style[key];
}
this.options = options;
container.appendChild(canvas);
};
DrawingPanel.PANEL_STORE = 'panel-store';
DrawingPanel.TAG = 'DrawingPanel';
DrawingPanel.defaultOptions = { width: 500, height: 500, style: { backgroundColor: 'white', border: '1px solid #dcdee2' } };
DrawingPanel.labelColor = 'tomato';
DrawingPanel.labelFont = 'bold 20px Arial';
return DrawingPanel;
}());
exports.DrawingPanel = DrawingPanel;
//# sourceMappingURL=drawing-panel.js.map
\ No newline at end of file
{"version":3,"file":"drawing-panel.js","sourceRoot":"","sources":["drawing-panel.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
import logger from '../utils/logger';
import { DrawingTool } from './drawing-tool';
import { Shape } from './shape';
export interface DrawingPanelOptions {
width: number;
height: number;
style?: {
backgroundColor?: string;
border?: string;
};
}
export class PanelState {
constructor(
public id: string,
public data: ImageData | string
) {}
}
export class PanelStore {
constructor(
public states: PanelState[]
) {}
}
export class DrawingPanel {
private static PANEL_STORE = 'panel-store';
private canvas: HTMLCanvasElement;
private readonly container: HTMLElement;
private drawingTool: DrawingTool;
private drawing: boolean;
private options: DrawingPanelOptions;
private static TAG = 'DrawingPanel';
private static defaultOptions: DrawingPanelOptions = {width: 500, height: 500, style: {backgroundColor: 'white', border:'1px solid #dcdee2'}};
private static labelColor = 'tomato';
private static labelFont = 'bold 20px Arial';
constructor(
containerID = 'container',
options?: DrawingPanelOptions) {
this.container = document.getElementById(containerID);
this.drawing = false;
// 准备options
options = options || <DrawingPanelOptions>{};
for (let key in DrawingPanel.defaultOptions) {
options[key] = options[key] || DrawingPanel.defaultOptions[key];
}
for (let key in options.style) {
options.style[key] = options.style[key] || DrawingPanel.defaultOptions.style[key];
}
this.initCanvas(options);
}
// 切换画图工具
public setDrawingTool(tool: DrawingTool) {
if (this.drawingTool) {
this.drawingTool.stop();
}
this.drawingTool = tool;
this.drawingTool.init(this.onDrawingEnd);
}
public getCanvas(): HTMLCanvasElement {
return this.canvas;
}
/**
* 保存当前画面
* @return {PanelState[]} 目前状态列表
*/
public saveCanvas(): PanelState[] {
const ctx = this.canvas.getContext('2d');
let data = this.canvas.toDataURL();
// let data = ctx.getImageData(0, 0, this.canvas.width, this.canvas.height);
let store: PanelStore = DrawingPanel.getPanelStore();
const id = new Date().getTime().toString() + 'state';
store.states.push(new PanelState(id, data));
DrawingPanel.savePanelStore(store);
return store.states;
}
/**
* 恢复某个画面
* @param {PanelState} state
*/
public restoreCanvas(state: PanelState) {
this.resetCanvas();
const ctx = this.canvas.getContext('2d');
const pic = new Image();
pic.src = state.data.toString();
pic.onload = () => {
ctx.drawImage(pic, 0, 0);
}
}
public getPanelStates(): PanelState[] {
return DrawingPanel.getPanelStore().states;
}
/**
* 新一个canvas
* 这里实现用的是清除画布内容
*/
public resetCanvas() {
if (!this.canvas) {
this.initCanvas(DrawingPanel.defaultOptions);
}
const ctx = this.canvas.getContext('2d');
ctx.clearRect(0, 0, this.options.width, this.options.height);
}
private static getPanelStore(): PanelStore {
let store: PanelStore;
const temp = localStorage.getItem(DrawingPanel.PANEL_STORE);
if (temp) {
store = JSON.parse(temp);
} else {
store = new PanelStore([]);
}
return store;
}
private static savePanelStore(store: PanelStore) {
const json = JSON.stringify(store);
logger.info(DrawingPanel.TAG, '', json);
localStorage.setItem(DrawingPanel.PANEL_STORE, json);
}
private onDrawingEnd = (shape: Shape) => {
logger.info(DrawingPanel.TAG, '画完了', shape);
const ctx = this.canvas.getContext('2d');
ctx.save();
ctx.fillStyle = DrawingPanel.labelColor;
ctx.font = DrawingPanel.labelFont;
ctx.fillText('未定义', shape.startPoint.x, shape.startPoint.y);
ctx.restore();
}
private initCanvas(options: DrawingPanelOptions) {
const container: HTMLElement = this.container;
const errorMsg = '创建画板失败';
if (!container) {
throw new Error(errorMsg);
}
this.canvas = document.createElement('canvas');
if (!this.canvas) {
throw new Error(errorMsg);
}
const canvas = this.canvas;
canvas.width = options.width;
canvas.height = options.height;
for (let key in options.style) {
canvas.style[key] = options.style[key];
}
this.options = options;
container.appendChild(canvas);
}
}
\ No newline at end of file
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var logger_1 = require("../utils/logger");
var DrawingToolCustom = /** @class */ (function () {
function DrawingToolCustom(canvas) {
this.canvas = canvas;
this.drawing = false;
this.shapeStack = [];
}
DrawingToolCustom.prototype.init = function (onDrawingEnd) {
var _this = this;
var ctx = this.canvas.getContext('2d');
ctx.save();
var canvas = this.canvas;
// 监听事件
canvas.onmousedown = function (e) {
logger_1.default.info(DrawingToolCustom.tag, '开始画');
if (_this.drawing) {
return;
}
_this.drawing = true;
// 坐标计算
var x = e.clientX - canvas.offsetLeft;
var y = e.clientY - canvas.offsetTop;
// 准备画
ctx.beginPath();
ctx.moveTo(x, y);
// shape保存图形
var shape = { id: '', coordinates: [], label: '未识别', startPoint: { x: x, y: y } };
// 鼠标移动,边动边画
canvas.onmousemove = function (e) {
var x = e.clientX - canvas.offsetLeft;
var y = e.clientY - canvas.offsetTop;
ctx.lineTo(x, y);
ctx.stroke();
shape.coordinates.push({ x: x, y: y });
};
canvas.onmouseup = function (e) {
// 取消监听
canvas.onmousemove = null;
if (onDrawingEnd) {
shape.id = DrawingToolCustom.tag + DrawingToolCustom.counter;
DrawingToolCustom.counter++;
_this.drawing = false;
// 推入状态栈
_this.shapeStack.push(shape);
onDrawingEnd(shape);
}
};
};
};
DrawingToolCustom.prototype.stop = function () {
this.canvas.onmousedown = null;
};
DrawingToolCustom.counter = 0;
DrawingToolCustom.tag = 'custom';
return DrawingToolCustom;
}());
exports.DrawingToolCustom = DrawingToolCustom;
//# sourceMappingURL=drawing-tool-custom.js.map
\ No newline at end of file
{"version":3,"file":"drawing-tool-custom.js","sourceRoot":"","sources":["drawing-tool-custom.ts"],"names":[],"mappings":";;AAEA,0CAAqC;AAErC;IAQE,2BAAY,MAAyB;QACnC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QACrB,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC;IACvB,CAAC;IAED,gCAAI,GAAJ,UAAK,YAAqC;QAA1C,iBAwCC;QAvCC,IAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACzC,GAAG,CAAC,IAAI,EAAE,CAAA;QACV,IAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC3B,OAAO;QACP,MAAM,CAAC,WAAW,GAAG,UAAC,CAAC;YACrB,gBAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YAC1C,IAAI,KAAI,CAAC,OAAO,EAAE;gBAChB,OAAO;aACR;YACD,KAAI,CAAC,OAAO,GAAG,IAAI,CAAC;YACpB,OAAO;YACP,IAAM,CAAC,GAAG,CAAC,CAAC,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC;YACxC,IAAM,CAAC,GAAG,CAAC,CAAC,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC;YACvC,MAAM;YACN,GAAG,CAAC,SAAS,EAAE,CAAC;YAChB,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YACjB,YAAY;YACZ,IAAI,KAAK,GAAU,EAAC,EAAE,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,EAAC,CAAC,GAAA,EAAE,CAAC,GAAA,EAAC,EAAC,CAAC;YAC/E,YAAY;YACZ,MAAM,CAAC,WAAW,GAAG,UAAA,CAAC;gBACpB,IAAM,CAAC,GAAG,CAAC,CAAC,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC;gBACxC,IAAM,CAAC,GAAG,CAAC,CAAC,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC;gBACvC,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;gBACjB,GAAG,CAAC,MAAM,EAAE,CAAC;gBACb,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,EAAC,CAAC,GAAA,EAAE,CAAC,GAAA,EAAC,CAAC,CAAC;YACjC,CAAC,CAAC;YACF,MAAM,CAAC,SAAS,GAAG,UAAA,CAAC;gBAClB,OAAO;gBACP,MAAM,CAAC,WAAW,GAAG,IAAI,CAAC;gBAC1B,IAAI,YAAY,EAAE;oBAChB,KAAK,CAAC,EAAE,GAAG,iBAAiB,CAAC,GAAG,GAAG,iBAAiB,CAAC,OAAO,CAAC;oBAC7D,iBAAiB,CAAC,OAAO,EAAE,CAAC;oBAC5B,KAAI,CAAC,OAAO,GAAG,KAAK,CAAC;oBACrB,QAAQ;oBACR,KAAI,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;oBAC5B,YAAY,CAAC,KAAK,CAAC,CAAC;iBACrB;YACH,CAAC,CAAC;QACJ,CAAC,CAAA;IACH,CAAC;IAED,gCAAI,GAAJ;QACE,IAAI,CAAC,MAAM,CAAC,WAAW,GAAG,IAAI,CAAC;IACjC,CAAC;IAvDM,yBAAO,GAAW,CAAC,CAAC;IACpB,qBAAG,GAAG,QAAQ,CAAC;IAwDxB,wBAAC;CAAA,AA5DD,IA4DC;AA5DY,8CAAiB"}
\ No newline at end of file
import { DrawingTool } from './drawing-tool';
import { Shape } from './shape';
import logger from '../utils/logger';
export class DrawingToolCustom implements DrawingTool{
drawing: boolean;
static counter: number = 0;
static tag = 'custom';
canvas: HTMLCanvasElement;
shapeStack: Shape[];
constructor(canvas: HTMLCanvasElement) {
this.canvas = canvas;
this.drawing = false;
this.shapeStack = [];
}
init(onDrawingEnd?: (shape: Shape) => void): void {
const ctx = this.canvas.getContext('2d');
ctx.save()
const canvas = this.canvas;
// 监听事件
canvas.onmousedown = (e) => {
logger.info(DrawingToolCustom.tag, '开始画');
if (this.drawing) {
return;
}
this.drawing = true;
// 坐标计算
const x = e.clientX - canvas.offsetLeft;
const y = e.clientY - canvas.offsetTop;
// 准备画
ctx.beginPath();
ctx.moveTo(x, y);
// shape保存图形
let shape: Shape = {id: '', coordinates: [], label: '未识别', startPoint: {x, y}};
// 鼠标移动,边动边画
canvas.onmousemove = e => {
const x = e.clientX - canvas.offsetLeft;
const y = e.clientY - canvas.offsetTop;
ctx.lineTo(x, y);
ctx.stroke();
shape.coordinates.push({x, y});
};
canvas.onmouseup = e => {
// 取消监听
canvas.onmousemove = null;
if (onDrawingEnd) {
shape.id = DrawingToolCustom.tag + DrawingToolCustom.counter;
DrawingToolCustom.counter++;
this.drawing = false;
// 推入状态栈
this.shapeStack.push(shape);
onDrawingEnd(shape);
}
};
}
}
stop() {
this.canvas.onmousedown = null;
}
}
\ No newline at end of file