canvas-editor-engine 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. package/Readme.md +118 -0
  2. package/dist/components/canvas.component.d.ts +21 -0
  3. package/dist/components/canvas.component.js +75 -0
  4. package/dist/components/excretions.component.d.ts +24 -0
  5. package/dist/components/excretions.component.js +192 -0
  6. package/dist/components/pipette.component.d.ts +23 -0
  7. package/dist/components/pipette.component.js +138 -0
  8. package/dist/components/slot.component.d.ts +10 -0
  9. package/dist/components/slot.component.js +20 -0
  10. package/dist/config.d.ts +9 -0
  11. package/dist/config.js +29 -0
  12. package/dist/filters/collection/vague.d.ts +12 -0
  13. package/dist/filters/collection/vague.js +107 -0
  14. package/dist/filters/index.d.ts +2 -0
  15. package/dist/filters/index.js +5 -0
  16. package/dist/images/image.png +0 -0
  17. package/dist/images/sample.png +0 -0
  18. package/dist/index.d.ts +25 -0
  19. package/dist/index.js +49 -0
  20. package/dist/services/component.service.d.ts +5 -0
  21. package/dist/services/component.service.js +37 -0
  22. package/dist/services/draw.service.d.ts +13 -0
  23. package/dist/services/draw.service.js +71 -0
  24. package/dist/services/tool.service.d.ts +10 -0
  25. package/dist/services/tool.service.js +58 -0
  26. package/dist/types/canvas.d.ts +10 -0
  27. package/dist/types/canvas.js +3 -0
  28. package/dist/types/cursor.d.ts +9 -0
  29. package/dist/types/cursor.js +3 -0
  30. package/dist/types/excreation.d.ts +24 -0
  31. package/dist/types/excreation.js +5 -0
  32. package/dist/types/excretion.d.ts +26 -0
  33. package/dist/types/excretion.js +5 -0
  34. package/dist/types/general.d.ts +14 -0
  35. package/dist/types/general.js +4 -0
  36. package/dist/types/image.d.ts +36 -0
  37. package/dist/types/image.js +7 -0
  38. package/dist/types/pipette.d.ts +1 -0
  39. package/dist/types/pipette.js +2 -0
  40. package/dist/utils/convert.d.ts +12 -0
  41. package/dist/utils/convert.js +27 -0
  42. package/dist/utils/filter.d.ts +16 -0
  43. package/dist/utils/filter.js +61 -0
  44. package/dist/web-component.d.ts +10 -0
  45. package/dist/web-component.js +60 -0
  46. package/package.json +30 -0
package/Readme.md ADDED
@@ -0,0 +1,118 @@
1
+ # Lib
2
+
3
+ Canvas 2D library use: [`typescript`] [`canvas`];
4
+
5
+ For: [vue3] [native-js];
6
+
7
+ # Vue3 example
8
+
9
+ input:
10
+ ```jsx
11
+ <script lang="ts" setup>
12
+ import { ref, onMounted } from 'vue';
13
+ import type { Ref } from 'vue';
14
+
15
+ import { VueCanvasEditorEngine, DrawService, ToolService, AppConfig } from 'sprite-creator'
16
+ import type { IDrawImageArgs } from 'sprite-creator/dist/types/image';
17
+ import ExecutionDelay from 'execution-delay';
18
+
19
+ const editor: Ref<HTMLElement | null> = ref(null);
20
+
21
+ AppConfig.CANVAS_SIZE.width = 700;
22
+ AppConfig.CANVAS_SIZE.height = 450;
23
+ const sc = new VueCanvasEditorEngine();
24
+ const initial = sc.getInitial();
25
+ customElements.define(initial.tag, initial.component);
26
+
27
+ const ctx: Ref<CanvasRenderingContext2D | null> = ref(null);
28
+
29
+ const quality: Ref<number> = ref(0);
30
+ const src: Ref<string | null> = ref(null);
31
+
32
+ onMounted(() => {
33
+ //@ts-ignore
34
+ editor.value?.addEventListener('get-editor-element', (e: CustomEvent) => {
35
+ const { editorElement, canvasSelector } = e.detail;
36
+ const canvas: HTMLCanvasElement = editorElement.querySelector(canvasSelector);
37
+ ctx.value = canvas.getContext("2d");
38
+ });
39
+ editor.value?.dispatchEvent(new Event('initial'));
40
+ });
41
+
42
+ function setImage(event: Event) {
43
+ const file: Ref<File | null> = ref(null);
44
+ const target = event.target as HTMLInputElement;
45
+
46
+ if (target && target.files) {
47
+ file.value = target.files[0];
48
+ }
49
+
50
+ if (!!file.value) {
51
+ src.value = window.URL.createObjectURL(file.value);
52
+ }
53
+ }
54
+
55
+ function inputQuality(event: Event) {
56
+ const target = event.target as HTMLInputElement;
57
+ quality.value = +target.value;
58
+ ExecutionDelay.add('draw', () => draw(quality.value), 500);
59
+ }
60
+
61
+ function draw(qualityValue: number) {
62
+ console.log('qualityValue', qualityValue);
63
+ if (!!ctx.value && !!src.value) {
64
+ const options: IDrawImageArgs = {
65
+ position: {
66
+ x: 0,
67
+ y: 0,
68
+ }
69
+ };
70
+ DrawService.drawSmoothImage(ctx.value, src.value, options, { quality: qualityValue });
71
+ }
72
+ }
73
+
74
+ function takePipette() {
75
+ console.log('ToolService.registry', ToolService.registry);
76
+ const pipetteToolId = ToolService.registry.find((tool) => tool.name === "pipette")?.id;
77
+ if (pipetteToolId !== undefined) {
78
+ console.log('pipetteToolId');
79
+ ToolService.setActive(pipetteToolId);
80
+ }
81
+ }
82
+ </script>
83
+
84
+ <template>
85
+ <div class="editor">
86
+ <canvas-editor-engine class="editor" ref="editor">
87
+ <div slot="tools">
88
+ <div>
89
+ <input
90
+ id="Image"
91
+ class="editor__image-input_input"
92
+ name="image"
93
+ type="file"
94
+ accept="image/*"
95
+ @change="setImage"
96
+ capture
97
+ />
98
+ </div>
99
+ <div>
100
+ <input type="range" name="quality" id="Quality" min="0" max="10" @change="inputQuality">
101
+ <span>Quality: {{ quality }}</span>
102
+ </div>
103
+ <button @click="takePipette">pipette</button>
104
+ </div>
105
+ </canvas-editor-engine>
106
+ </div>
107
+ </template>
108
+ ```
109
+
110
+ simple output:
111
+ ```jsx
112
+ <canvas-editor-engine>
113
+ #shadow-root (open)
114
+ <div>
115
+ <canvas id="sc-canvas"></canvas>
116
+ </div>
117
+ </canvas-editor-engine>
118
+ ```
@@ -0,0 +1,21 @@
1
+ import { TSubscribeAction, TSubscriptionTypes } from "../types/canvas";
2
+ import { ICursorPosition, TCursorStyleName } from "../types/cursor";
3
+ import ComponentService from "../services/component.service";
4
+ export default class CanvasComponent extends ComponentService {
5
+ private static template;
6
+ private static css;
7
+ static eventListener: HTMLDivElement;
8
+ static canvas: HTMLCanvasElement;
9
+ static ctx: CanvasRenderingContext2D | null;
10
+ private static subscriptions;
11
+ private static _cursorStyle;
12
+ static getComponent(): {
13
+ canvasTemplate: HTMLElement;
14
+ canvasStyle: HTMLStyleElement;
15
+ };
16
+ static getCanvasSelector(): string;
17
+ static set cursorStyle(styleName: TCursorStyleName | undefined | null);
18
+ static getCursorPosition(event: MouseEvent): ICursorPosition;
19
+ static subscribe(eventName: TSubscriptionTypes, action: TSubscribeAction): void;
20
+ static simulateSubscriptions(): void;
21
+ }
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const config_1 = require("../config");
4
+ const component_service_1 = require("../services/component.service");
5
+ class CanvasComponent extends component_service_1.default {
6
+ static getComponent() {
7
+ const canvasTemplate = CanvasComponent.getTemplate(CanvasComponent.template);
8
+ const canvasStyle = CanvasComponent.getStyle(CanvasComponent.css);
9
+ CanvasComponent.canvas = canvasTemplate.getElementsByTagName('canvas')[0];
10
+ CanvasComponent.canvas.width = config_1.default.CANVAS_SIZE.width;
11
+ CanvasComponent.canvas.height = config_1.default.CANVAS_SIZE.height;
12
+ CanvasComponent.ctx = CanvasComponent.canvas.getContext("2d", { willReadFrequently: true });
13
+ CanvasComponent.eventListener = canvasTemplate.querySelector('#event-listener');
14
+ CanvasComponent.eventListener.style.width = config_1.default.CANVAS_SIZE.width + 'px';
15
+ CanvasComponent.eventListener.style.height = config_1.default.CANVAS_SIZE.height + 'px';
16
+ return { canvasTemplate, canvasStyle };
17
+ }
18
+ static getCanvasSelector() {
19
+ return '#sc-canvas';
20
+ }
21
+ static set cursorStyle(styleName) {
22
+ if (!!styleName) {
23
+ CanvasComponent._cursorStyle.before = CanvasComponent._cursorStyle.current;
24
+ CanvasComponent._cursorStyle.current = styleName;
25
+ CanvasComponent.eventListener.style.cursor = styleName;
26
+ }
27
+ else {
28
+ CanvasComponent.eventListener.style.cursor = 'default';
29
+ }
30
+ }
31
+ static getCursorPosition(event) {
32
+ const rect = CanvasComponent.canvas.getBoundingClientRect();
33
+ const x = event.clientX - rect.left;
34
+ const y = event.clientY - rect.top;
35
+ return { x, y };
36
+ }
37
+ static subscribe(eventName, action) {
38
+ CanvasComponent.subscriptions[eventName].push(action);
39
+ }
40
+ static simulateSubscriptions() {
41
+ const eventNames = Object.keys(CanvasComponent.subscriptions);
42
+ eventNames.forEach((eventName) => {
43
+ const actionsList = CanvasComponent.subscriptions[eventName];
44
+ if (!!actionsList.length) {
45
+ CanvasComponent.eventListener.addEventListener(eventName, (event) => {
46
+ const cursorPosition = CanvasComponent.getCursorPosition(event);
47
+ actionsList.forEach((action) => {
48
+ action(event, cursorPosition);
49
+ });
50
+ });
51
+ }
52
+ });
53
+ }
54
+ }
55
+ CanvasComponent.template = `
56
+ <div id="event-listener"></div>
57
+ <canvas id="sc-canvas"></canvas>
58
+ `;
59
+ CanvasComponent.css = `
60
+ #event-listener {
61
+ position: absolute;
62
+ z-index: 10000;
63
+ }
64
+ `;
65
+ CanvasComponent.subscriptions = {
66
+ click: [],
67
+ mousemove: [],
68
+ mousedown: [],
69
+ mouseup: [],
70
+ };
71
+ CanvasComponent._cursorStyle = {
72
+ before: null,
73
+ current: 'default',
74
+ };
75
+ exports.default = CanvasComponent;
@@ -0,0 +1,24 @@
1
+ import ComponentService from "../services/component.service";
2
+ import type { IExcretionsCoords, TExcretionToolState } from "../types/excretion";
3
+ export default class ExcretionsComponent extends ComponentService {
4
+ private static template;
5
+ private static css;
6
+ static excretionWrap: HTMLElement;
7
+ private static _excretions;
8
+ private static _excretionState;
9
+ private static _excretionActivity;
10
+ private static _excretionToolState;
11
+ private static _tempCoords;
12
+ static excretionsCoords: IExcretionsCoords[];
13
+ private static tool;
14
+ static getComponent(): {
15
+ excretionsTemplate: HTMLElement;
16
+ excretionsStyle: HTMLStyleElement;
17
+ };
18
+ private static set excretionState(value);
19
+ static setToolState(toolState: TExcretionToolState): void;
20
+ static clearExcretionsCoords(): void;
21
+ private static getTempCoords;
22
+ private static endExcretion;
23
+ private static emmit;
24
+ }
@@ -0,0 +1,192 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const component_service_1 = require("../services/component.service");
4
+ const tool_service_1 = require("../services/tool.service");
5
+ const canvas_component_1 = require("./canvas.component");
6
+ class ExcretionsComponent extends component_service_1.default {
7
+ static getComponent() {
8
+ const wrapOptions = {
9
+ className: 'excretions-wrap',
10
+ };
11
+ const excretionsTemplate = ExcretionsComponent.getTemplate(ExcretionsComponent.template, wrapOptions);
12
+ const excretionsStyle = ExcretionsComponent.getStyle(ExcretionsComponent.css);
13
+ ExcretionsComponent.excretionWrap = excretionsTemplate;
14
+ ExcretionsComponent.emmit();
15
+ return { excretionsTemplate, excretionsStyle };
16
+ }
17
+ static set excretionState(state) {
18
+ ExcretionsComponent._excretionState = state;
19
+ switch (state) {
20
+ case 'abandoned':
21
+ canvas_component_1.default.cursorStyle = 'default';
22
+ break;
23
+ case 'create':
24
+ canvas_component_1.default.cursorStyle = 'crosshair';
25
+ break;
26
+ case 'add':
27
+ canvas_component_1.default.cursorStyle = 'copy';
28
+ break;
29
+ case 'remove':
30
+ canvas_component_1.default.cursorStyle = 'alias';
31
+ break;
32
+ default:
33
+ canvas_component_1.default.cursorStyle = 'default';
34
+ break;
35
+ }
36
+ }
37
+ static setToolState(toolState) {
38
+ ExcretionsComponent._excretionToolState = toolState;
39
+ switch (toolState) {
40
+ case 'abandoned':
41
+ ExcretionsComponent.excretionState = 'abandoned';
42
+ ExcretionsComponent._excretionActivity = 'abandoned';
43
+ break;
44
+ case 'taken':
45
+ ExcretionsComponent.excretionState = 'create';
46
+ break;
47
+ default:
48
+ ExcretionsComponent.excretionState = 'abandoned';
49
+ ExcretionsComponent._excretionActivity = 'abandoned';
50
+ break;
51
+ }
52
+ }
53
+ static clearExcretionsCoords() {
54
+ console.log('clear!');
55
+ ExcretionsComponent._excretions.forEach((excretion) => excretion.remove());
56
+ ExcretionsComponent._excretions = [];
57
+ ExcretionsComponent.excretionsCoords = [];
58
+ }
59
+ static getTempCoords() {
60
+ const startCoords = ExcretionsComponent._tempCoords[0];
61
+ const endCoords = ExcretionsComponent._tempCoords[1];
62
+ const coords = Object.assign(startCoords, endCoords);
63
+ ExcretionsComponent._tempCoords = [];
64
+ return coords;
65
+ }
66
+ static endExcretion() {
67
+ const coords = ExcretionsComponent.getTempCoords();
68
+ ExcretionsComponent.excretionsCoords.push(coords);
69
+ ExcretionsComponent._excretionActivity = 'end';
70
+ console.log('ExcretionsComponent.excretionsCoords', ExcretionsComponent.excretionsCoords);
71
+ }
72
+ static emmit() {
73
+ canvas_component_1.default.subscribe('mousedown', (event, cursorPosition) => {
74
+ const toolState = ExcretionsComponent._excretionToolState;
75
+ if (toolState === 'abandoned')
76
+ return;
77
+ const state = ExcretionsComponent._excretionState;
78
+ if (state === 'create') {
79
+ const wrapOptions = {
80
+ className: 'excretion',
81
+ };
82
+ const excretionTemplate = ExcretionsComponent.getTemplate('', wrapOptions);
83
+ ExcretionsComponent.clearExcretionsCoords();
84
+ const tempStart = {
85
+ start: cursorPosition,
86
+ };
87
+ excretionTemplate.style.left = `${tempStart.start.x}px`;
88
+ excretionTemplate.style.top = `${tempStart.start.y}px`;
89
+ const excretionElement = ExcretionsComponent.excretionWrap.appendChild(excretionTemplate);
90
+ ExcretionsComponent._excretions.push(excretionElement);
91
+ ExcretionsComponent._tempCoords.push(tempStart);
92
+ }
93
+ if (state === 'add') {
94
+ const tempStart = {
95
+ start: cursorPosition,
96
+ };
97
+ ExcretionsComponent._tempCoords.push(tempStart);
98
+ }
99
+ ExcretionsComponent._excretionActivity = 'active';
100
+ });
101
+ canvas_component_1.default.subscribe('mousemove', (event, cursorPosition) => {
102
+ const toolState = ExcretionsComponent._excretionToolState;
103
+ if (toolState === 'abandoned')
104
+ return;
105
+ const activity = ExcretionsComponent._excretionActivity;
106
+ if (event.altKey && ExcretionsComponent._excretionState !== 'abandoned') {
107
+ ExcretionsComponent._excretionState = 'add';
108
+ }
109
+ if (activity === 'abandoned')
110
+ return;
111
+ if (activity === 'active') {
112
+ const excretionLastIndex = ExcretionsComponent._excretions.length - 1;
113
+ const excretion = ExcretionsComponent._excretions[excretionLastIndex];
114
+ const excretionX = +(excretion.style.left.split('px')[0]);
115
+ const excretionY = +(excretion.style.top.split('px')[0]);
116
+ const width = Math.abs(cursorPosition.x - excretionX);
117
+ const height = Math.abs(cursorPosition.y - excretionY);
118
+ excretion.style.width = width + 'px';
119
+ excretion.style.height = height + 'px';
120
+ const isRightBottom = cursorPosition.x > excretionX && cursorPosition.y > excretionY;
121
+ const isLeftBottom = cursorPosition.x < excretionX && cursorPosition.y > excretionY;
122
+ const isLeftTop = cursorPosition.x < excretionX && cursorPosition.y < excretionY;
123
+ const isRightTop = cursorPosition.x > excretionX && cursorPosition.y < excretionY;
124
+ if (isRightBottom) {
125
+ excretion.style.transform = `translateX(0px) translateY(0px)`;
126
+ }
127
+ else if (isLeftBottom) {
128
+ excretion.style.transform = `translateX(-${width}px) translateY(0px)`;
129
+ }
130
+ else if (isLeftTop) {
131
+ excretion.style.transform = `translateX(-${width}px) translateY(-${height}px)`;
132
+ }
133
+ else if (isRightTop) {
134
+ excretion.style.transform = `translateX(0px) translateY(-${height}px)`;
135
+ }
136
+ }
137
+ });
138
+ canvas_component_1.default.subscribe('mouseup', (event, cursorPosition) => {
139
+ const toolState = ExcretionsComponent._excretionToolState;
140
+ if (toolState === 'abandoned')
141
+ return;
142
+ const state = ExcretionsComponent._excretionState;
143
+ if (state === 'abandoned')
144
+ return;
145
+ if (state === 'create' || state === 'add') {
146
+ const tempEnd = {
147
+ end: cursorPosition,
148
+ };
149
+ ExcretionsComponent._tempCoords.push(tempEnd);
150
+ ExcretionsComponent.endExcretion();
151
+ }
152
+ });
153
+ }
154
+ }
155
+ ExcretionsComponent.template = ``;
156
+ ExcretionsComponent.css = `
157
+ .excretion {
158
+ display: flex;
159
+ position: absolute;
160
+ background-image: linear-gradient(90deg, silver 50%, transparent 50%), linear-gradient(90deg, silver 50%, transparent 50%), linear-gradient(0deg, silver 50%, transparent 50%), linear-gradient(0deg, silver 50%, transparent 50%);
161
+ background-repeat: repeat-x, repeat-x, repeat-y, repeat-y;
162
+ background-size: 8px 1px, 8px 1px, 1px 8px, 1px 8px;
163
+ background-position: left top, right bottom, left bottom, right top;
164
+ animation: border-dance 1s infinite linear;
165
+ }
166
+
167
+ @keyframes border-dance {
168
+ 0% {
169
+ background-position: left top, right bottom, left bottom, right top;
170
+ }
171
+ 100% {
172
+ background-position: left 8px top, right 8px bottom, left bottom 8px, right top 8px;
173
+ }
174
+ }
175
+ `;
176
+ ExcretionsComponent._excretions = [];
177
+ ExcretionsComponent._excretionState = 'abandoned';
178
+ ExcretionsComponent._excretionActivity = 'abandoned';
179
+ ExcretionsComponent._excretionToolState = 'abandoned';
180
+ ExcretionsComponent._tempCoords = [];
181
+ ExcretionsComponent.excretionsCoords = [];
182
+ ExcretionsComponent.tool = {
183
+ id: 1,
184
+ name: 'excretion',
185
+ onAction: () => ExcretionsComponent.setToolState('taken'),
186
+ offAction: () => ExcretionsComponent.setToolState('abandoned'),
187
+ support: () => ExcretionsComponent.clearExcretionsCoords(),
188
+ };
189
+ (() => {
190
+ tool_service_1.default.add(ExcretionsComponent.tool);
191
+ })();
192
+ exports.default = ExcretionsComponent;
@@ -0,0 +1,23 @@
1
+ import { TPipetteState } from "../types/pipette";
2
+ import { THEXColor } from "../types/general";
3
+ import ComponentService from "../services/component.service";
4
+ export default class PipetteComponent extends ComponentService {
5
+ static template: string;
6
+ static css: string;
7
+ static pipette: HTMLElement;
8
+ private static _pipetteColor;
9
+ static set pipetteColor(color: THEXColor);
10
+ static get pipetteColor(): THEXColor;
11
+ private static _pipetteColorElement;
12
+ private static _pipetteState;
13
+ private static tool;
14
+ static getComponent(): {
15
+ pipetteTemplate: HTMLElement;
16
+ pipetteStyle: HTMLStyleElement;
17
+ };
18
+ static setState(state: TPipetteState): void;
19
+ static emmit(): void;
20
+ private static setColorFromChoosenPixel;
21
+ private static show;
22
+ private static hide;
23
+ }
@@ -0,0 +1,138 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const convert_1 = require("../utils/convert");
4
+ const canvas_component_1 = require("./canvas.component");
5
+ const component_service_1 = require("../services/component.service");
6
+ const tool_service_1 = require("../services/tool.service");
7
+ class PipetteComponent extends component_service_1.default {
8
+ static set pipetteColor(color) {
9
+ PipetteComponent._pipetteColor = color;
10
+ PipetteComponent._pipetteColorElement.style.borderColor = PipetteComponent._pipetteColor;
11
+ }
12
+ static get pipetteColor() {
13
+ return PipetteComponent._pipetteColor;
14
+ }
15
+ static getComponent() {
16
+ const wrapOptions = {
17
+ className: 'pipette',
18
+ };
19
+ const pipetteTemplate = PipetteComponent.getTemplate(PipetteComponent.template, wrapOptions);
20
+ const pipetteStyle = PipetteComponent.getStyle(PipetteComponent.css);
21
+ PipetteComponent.pipette = pipetteTemplate;
22
+ PipetteComponent._pipetteColorElement = pipetteTemplate.querySelector('.pipette_color');
23
+ PipetteComponent.emmit();
24
+ return { pipetteTemplate, pipetteStyle };
25
+ }
26
+ static setState(state) {
27
+ PipetteComponent._pipetteState = state;
28
+ switch (state) {
29
+ case 'abandoned':
30
+ return PipetteComponent.hide();
31
+ case 'taken':
32
+ return PipetteComponent.show();
33
+ case 'selected-color':
34
+ return PipetteComponent.show();
35
+ default:
36
+ return PipetteComponent.hide();
37
+ }
38
+ }
39
+ static emmit() {
40
+ canvas_component_1.default.subscribe('mousemove', (event, cursorPosition) => {
41
+ const state = PipetteComponent._pipetteState;
42
+ if (state === 'taken' || state === 'selected-color') {
43
+ const { x, y } = cursorPosition;
44
+ PipetteComponent.pipette.style.left = `${x + 10}px`;
45
+ PipetteComponent.pipette.style.top = `${y + 10}px`;
46
+ }
47
+ });
48
+ canvas_component_1.default.subscribe('click', (event, cursorPosition) => {
49
+ const state = PipetteComponent._pipetteState;
50
+ if (state === 'taken' || state === 'selected-color') {
51
+ console.log('pipetteState', state);
52
+ if (state === 'taken') {
53
+ PipetteComponent.setColorFromChoosenPixel(cursorPosition);
54
+ PipetteComponent.setState('selected-color');
55
+ }
56
+ if (state === 'selected-color') {
57
+ PipetteComponent.setColorFromChoosenPixel(cursorPosition);
58
+ }
59
+ }
60
+ });
61
+ }
62
+ static setColorFromChoosenPixel(cursorPosition) {
63
+ const { x, y } = cursorPosition;
64
+ const pixel = canvas_component_1.default.ctx.getImageData(x, y, 1, 1).data;
65
+ const hexPixel = convert_1.Convert.rgbToHex(pixel[0], pixel[1], pixel[2]);
66
+ PipetteComponent.pipetteColor = hexPixel;
67
+ }
68
+ static show() {
69
+ PipetteComponent.pipette.style.display = 'flex';
70
+ canvas_component_1.default.cursorStyle = 'default';
71
+ }
72
+ static hide() {
73
+ PipetteComponent.pipette.style.display = 'none';
74
+ canvas_component_1.default.cursorStyle = 'default';
75
+ }
76
+ }
77
+ PipetteComponent.template = `
78
+ <div class="pipette_border-out">
79
+ <div class="pipette_color">
80
+ <div class="pipette_border-in">
81
+ <svg width="24px" height="24px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"><path d="M17 12C17 14.7614 14.7614 17 12 17M17 12C17 9.23858 14.7614 7 12 7M17 12H19M12 17C9.23858 17 7 14.7614 7 12M12 17V19M7 12C7 9.23858 9.23858 7 12 7M7 12H5M12 7V5M14 12C14 13.1046 13.1046 14 12 14C10.8954 14 10 13.1046 10 12C10 10.8954 10.8954 10 12 10C13.1046 10 14 10.8954 14 12Z" stroke="#d9d9d9" stroke-linecap="round" stroke-linejoin="round"></path></g></svg>
82
+ </div>
83
+ </div>
84
+ </div>
85
+ `;
86
+ PipetteComponent.css = `
87
+ .pipette {
88
+ position: absolute;
89
+ display: none;
90
+ justify-content: center;
91
+ align-items: center;
92
+ width: 48px;
93
+ height: 48px;
94
+ }
95
+
96
+ .pipette_border-out {
97
+ display: flex;
98
+ justify-content: center;
99
+ align-items: center;
100
+ border-radius: 100px;
101
+ border: solid 2px #d9d9d9;
102
+ width: 44px;
103
+ height: 44px;
104
+ }
105
+
106
+ .pipette_border-in {
107
+ display: flex;
108
+ justify-content: center;
109
+ align-items: center;
110
+ border-radius: 100px;
111
+ border: solid 1px #d9d9d9;
112
+ width: 32px;
113
+ height: 32px;
114
+ }
115
+
116
+ .pipette_color {
117
+ display: flex;
118
+ justify-content: center;
119
+ align-items: center;
120
+ width: 34px;
121
+ height: 34px;
122
+ border-radius: 100px;
123
+ border-color: blue;
124
+ border-style: solid;
125
+ border-width: 5px;
126
+ }
127
+ `;
128
+ PipetteComponent._pipetteState = 'abandoned';
129
+ PipetteComponent.tool = {
130
+ id: 0,
131
+ name: 'pipette',
132
+ onAction: () => PipetteComponent.setState('taken'),
133
+ offAction: () => PipetteComponent.setState('abandoned'),
134
+ };
135
+ (() => {
136
+ tool_service_1.default.add(PipetteComponent.tool);
137
+ })();
138
+ exports.default = PipetteComponent;
@@ -0,0 +1,10 @@
1
+ import ComponentService from "../services/component.service";
2
+ export default class SlotComponent extends ComponentService {
3
+ private static template;
4
+ private static css;
5
+ static slot: HTMLSlotElement;
6
+ static getComponent(slotName: string): {
7
+ slotTemplate: HTMLElement;
8
+ slotStyle: HTMLStyleElement;
9
+ };
10
+ }
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const component_service_1 = require("../services/component.service");
4
+ class SlotComponent extends component_service_1.default {
5
+ static getComponent(slotName) {
6
+ const wrapOptions = {
7
+ className: 'slot-wrapper',
8
+ };
9
+ const slotTemplate = SlotComponent.getTemplate(SlotComponent.template, wrapOptions);
10
+ const slotStyle = SlotComponent.getStyle(SlotComponent.css);
11
+ SlotComponent.slot = slotTemplate.querySelector('slot');
12
+ SlotComponent.slot.name = slotName;
13
+ return { slotTemplate, slotStyle };
14
+ }
15
+ }
16
+ SlotComponent.template = `
17
+ <slot class="slot"></slot>
18
+ `;
19
+ SlotComponent.css = ``;
20
+ exports.default = SlotComponent;
@@ -0,0 +1,9 @@
1
+ import { ICanvasSize } from "./types/canvas";
2
+ export default class AppConfig {
3
+ private static _WEB_COMPONENT_TAG_NAME;
4
+ private static _CANVAS_SIZE;
5
+ static get WEB_COMPONENT_TAG_NAME(): string;
6
+ static set WEB_COMPONENT_TAG_NAME(value: string | undefined);
7
+ static get CANVAS_SIZE(): ICanvasSize;
8
+ static set CANVAS_SIZE(value: ICanvasSize | undefined);
9
+ }
package/dist/config.js ADDED
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ class AppConfig {
4
+ static get WEB_COMPONENT_TAG_NAME() {
5
+ return AppConfig._WEB_COMPONENT_TAG_NAME;
6
+ }
7
+ static set WEB_COMPONENT_TAG_NAME(value) {
8
+ if (!!value && typeof value === 'string') {
9
+ AppConfig._WEB_COMPONENT_TAG_NAME = value;
10
+ }
11
+ }
12
+ static get CANVAS_SIZE() {
13
+ return AppConfig._CANVAS_SIZE;
14
+ }
15
+ static set CANVAS_SIZE(value) {
16
+ if (!!value && !!(value === null || value === void 0 ? void 0 : value.width) && !!(value === null || value === void 0 ? void 0 : value.height)) {
17
+ AppConfig._CANVAS_SIZE = value;
18
+ }
19
+ else {
20
+ console.warn('CANVAS_SIZE denied');
21
+ }
22
+ }
23
+ }
24
+ AppConfig._WEB_COMPONENT_TAG_NAME = 'canvas-editor-engine';
25
+ AppConfig._CANVAS_SIZE = {
26
+ width: 300,
27
+ height: 150,
28
+ };
29
+ exports.default = AppConfig;
@@ -0,0 +1,12 @@
1
+ import type { IFilterOptions, IImageOptions, TFilterMethod } from "../../types/image";
2
+ import { Filter } from "../../utils/filter";
3
+ export default class VagueFilter extends Filter {
4
+ options: IImageOptions;
5
+ filterList: TFilterMethod[];
6
+ constructor(ctx: CanvasRenderingContext2D, options: IImageOptions);
7
+ on(action: TFilterMethod, filterOptions: IFilterOptions): void;
8
+ pixel(imageData: ImageData, filterOptions: IFilterOptions): ImageData;
9
+ private getQualityBuff;
10
+ private getMostCommonQuanlityBuff;
11
+ private getMostCommonElement;
12
+ }