canvas-editor-engine 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+ }