오윤석

Merge branch 'feat/component' into develop

This diff could not be displayed because it is too large.
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
21 "dependencies": { 21 "dependencies": {
22 "@babel/plugin-proposal-class-properties": "^7.13.0", 22 "@babel/plugin-proposal-class-properties": "^7.13.0",
23 "gifencoder": "^2.0.1", 23 "gifencoder": "^2.0.1",
24 + "hangul-js": "^0.2.6",
24 "stream": "0.0.2" 25 "stream": "0.0.2"
25 } 26 }
26 } 27 }
......
1 +import ComponentInterface from "./ComponentInterface";
2 +import Color from "./Color";
3 +import { fabric } from "fabric";
4 +
5 +class Brush extends ComponentInterface {
6 + constructor(fabricObj) {
7 + super(fabricObj.path.length);
8 + this.color = new Color(fabricObj.stroke);
9 + this.paths = fabricObj.path;
10 + this.size = fabricObj.strokeWidth;
11 + this.position = {
12 + top: fabricObj.top,
13 + left: fabricObj.left,
14 + };
15 + }
16 +
17 + getCurrentFabricObject() {
18 + const paths = this.paths.filter((_, i) => i < this.state.current);
19 + if (paths.length > 0) {
20 + const popCount = paths[paths.length - 1].length - 3;
21 + for (let i = 0; i < popCount; i++) {
22 + paths[paths.length - 1].pop();
23 + }
24 + paths[paths.length - 1][0] = "L";
25 + }
26 + return new fabric.Path(paths, {
27 + top: this.position.top,
28 + left: this.position.left,
29 + stroke: this.color.getRgba(),
30 + strokeWidth: this.size,
31 + });
32 + }
33 +
34 + next() {
35 + return this.addState(10);
36 + }
37 +}
38 +
39 +export default Brush;
1 +class Color {
2 + constructor(colorData) {
3 + if (colorData[0] == "#") {
4 + this.r = parseInt(colorData.substring(1, 3), 16);
5 + this.g = parseInt(colorData.substring(3, 5), 16);
6 + this.b = parseInt(colorData.substring(5, 7), 16);
7 + this.a = 1;
8 + } else {
9 + const rgba = colorData.substring(5, colorData.length - 1).split(",");
10 + this.r = parseInt(rgba[0]);
11 + this.g = parseInt(rgba[1]);
12 + this.b = parseInt(rgba[2]);
13 + this.a = parseFloat(rgba[3]);
14 + }
15 + }
16 +
17 + getColorCode() {
18 + return `#${this.r.toString(16)}${this.g.toString(16)}${this.b.toString(
19 + 16
20 + )}`;
21 + }
22 +
23 + getRgba() {
24 + return `rgba(${this.r},${this.g},${this.b},${this.a})`;
25 + }
26 +}
27 +
28 +export default Color;
1 +class ComponentInterface {
2 + constructor(maxState) {
3 + this.state = {
4 + current: 0,
5 + max: maxState,
6 + };
7 + }
8 +
9 + getCurrentFabricObject() {}
10 +
11 + addState(count = 1) {
12 + if (this.state.current == this.state.max) {
13 + this.state.current++;
14 + } else {
15 + this.state.current = Math.min(this.state.current + count, this.state.max);
16 + }
17 + }
18 +
19 + end() {
20 + return this.state.current == this.state.max + 1;
21 + }
22 +}
23 +
24 +export default ComponentInterface;
1 +import ComponentInterface from "./ComponentInterface";
2 +import Color from "./Color";
3 +import Hangul from "hangul-js";
4 +import { fabric } from "fabric";
5 +
6 +class Text extends ComponentInterface {
7 + constructor(fabricObj) {
8 + const textSplited = Hangul.disassemble(fabricObj.text);
9 +
10 + super(textSplited.length);
11 + this.color = new Color(fabricObj.fill);
12 + this.text = {
13 + plain: fabricObj.text,
14 + splited: textSplited,
15 + };
16 + this.position = {
17 + top: fabricObj.top,
18 + left: fabricObj.left,
19 + };
20 + this.font = {
21 + size: fabricObj.fontSize,
22 + style: fabricObj.fontStyle,
23 + weight: fabricObj.fontWeight,
24 + family: fabricObj.fontFamily,
25 + };
26 + }
27 +
28 + getCurrentFabricObject() {
29 + return new fabric.Text(
30 + Hangul.assemble(
31 + this.text.splited.filter((_, i) => i < this.state.current)
32 + ),
33 + {
34 + top: this.position.top,
35 + left: this.position.left,
36 + fontFamily: this.font.family,
37 + fontSize: this.font.size,
38 + fontWeight: this.font.weight,
39 + fontStyle: this.font.style,
40 + fill: this.color.getColorCode(),
41 + }
42 + );
43 + }
44 +
45 + next() {
46 + return this.addState();
47 + }
48 +}
49 +
50 +export default Text;
1 +import Brush from "./Brush";
2 +import Text from "./Text";
3 +
4 +const Component = {
5 + Brush,
6 + Text,
7 +};
8 +
9 +export default Component;
1 import GIF from "gifencoder"; 1 import GIF from "gifencoder";
2 +import { fabric } from "fabric";
3 +import Component from "./components";
2 4
3 class GifGenerator { 5 class GifGenerator {
4 constructor(canvas) { 6 constructor(canvas) {
...@@ -13,17 +15,39 @@ class GifGenerator { ...@@ -13,17 +15,39 @@ class GifGenerator {
13 this.gif.setQuality(10); 15 this.gif.setQuality(10);
14 } 16 }
15 17
16 - addFrame(delay = 0) { 18 + _addFrame(delay = 0) {
17 this.gif.setDelay(delay); 19 this.gif.setDelay(delay);
18 this.gif.addFrame(this.canvas.getContext()); 20 this.gif.addFrame(this.canvas.getContext());
19 } 21 }
20 22
21 - render() { 23 + _render() {
22 this.gif.finish(); 24 this.gif.finish();
23 const byte = new Uint8Array(this.gif.out.data); 25 const byte = new Uint8Array(this.gif.out.data);
24 26
25 return new Blob([byte], { type: "image/gif" }); 27 return new Blob([byte], { type: "image/gif" });
26 } 28 }
29 +
30 + make() {
31 + const fabricObjs = this.canvas.getObjects();
32 + const objs = [];
33 +
34 + fabricObjs.map((fabricObj) => {
35 + if (fabricObj instanceof fabric.Path) {
36 + objs.push(new Component.Brush(fabricObj));
37 + } else if (fabricObj.text !== undefined) {
38 + objs.push(new Component.Text(fabricObj));
39 + }
40 + });
41 +
42 + objs.map((obj) => {
43 + while (!obj.end()) {
44 + console.log(obj.getCurrentFabricObject());
45 + obj.next();
46 + }
47 + });
48 +
49 + console.log(objs);
50 + }
27 } 51 }
28 52
29 window.GifGenerator = GifGenerator; 53 window.GifGenerator = GifGenerator;
......