Skip to content

Commit

Permalink
fixed curve bbox bug
Browse files Browse the repository at this point in the history
support to add template layer
support path edit button
  • Loading branch information
easylogic committed Sep 24, 2021
1 parent 4c04a0b commit 52b92db
Show file tree
Hide file tree
Showing 29 changed files with 435 additions and 173 deletions.
6 changes: 3 additions & 3 deletions dist/editor.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/editor.css.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/editor.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/editor.js.map

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions docs/editor.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/editor.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/index.html
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<!doctype html> <html> <head> <meta http-equiv=Pragma content=no-cache> <meta http-equiv=Expires content=-1> <script async src="https://www.googletagmanager.com/gtag/js?id=UA-139740394-1"></script> <link rel=icon href=icon.png sizes=128x128> <script>function gtag(){dataLayer.push(arguments)}window.dataLayer=window.dataLayer||[],gtag("js",new Date),gtag("config","UA-139740394-1")</script> <script>!function(e,n,a,t){e.dmndata=[],e.jenniferFront=function(e){window.dmndata.push(e)},e.dmnaid=t,e.dmnatime=new Date,e.dmnanocookie=!1,e.dmnajennifer="JENNIFER_FRONT@INTG";var d=6e4*Math.floor((new Date).getTime()/6e4),c=n.createElement(a);c.src="https://d-collect.jennifersoft.com/"+t+"/demian.js?"+d,c.async=!0,n.getElementsByTagName(a)[0].parentNode.appendChild(c)}(window,document,"script","cc474308-b29c-af41-7393-409d285dca6e")</script> <meta charset=utf-8 /> <title>Fantastic Web Design Tool</title> <meta name=viewport content="width=device-width,initial-scale=1,user-scalable=no"/> <meta name=description content="You can make simply web with Web editor. "/> <meta name=keywords content=html5,css,svg,editor> <meta name=author content=easylogic> <meta property=og:title content="Fantastic Web Design Tool"/> <meta property=og:type content=website /> <meta property=og:description content="You can make simply web with Web editor. "/> <meta property=og:url content=https://www.easylogic.studio /> <meta property=og:image content=https://www.easylogic.studio/images/editor.png /> <meta property=twitter:card content=summary_large_image> <meta property=twitter:url content=https://www.easylogic.studio> <meta property=twitter:title content="Fantastic Web Design Tool"> <meta property=twitter:description content="You can make simply web with Web editor. "> <meta property=twitter:image content=https://www.easylogic.studio/images/editor.png> <script src=https://unpkg.com/shiki></script> <script src=https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.14.0/beautify.min.js></script> <script src=https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.14.0/beautify-css.min.js></script> <script src=https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.14.0/beautify-html.min.js></script> <meta name="apple-mobile-web-app-title" content="EasyLogic Studio" /><meta name="apple-mobile-web-app-capable" content="yes" /><meta name="apple-mobile-web-app-status-bar-style" content="black" /><link rel="manifest" href="/manifest.e398b874aa6339b677475253fffca031.json" crossorigin="use-credentials" /><link href="/editor.css?b6863fb0acf56129c7ec" rel="stylesheet"></head> <body> <div id=app></div> <script type="text/javascript" src="/editor.js?314345f3cc926f1ac606"></script></body> </html>
<!doctype html> <html> <head> <meta http-equiv=Pragma content=no-cache> <meta http-equiv=Expires content=-1> <script async src="https://www.googletagmanager.com/gtag/js?id=UA-139740394-1"></script> <link rel=icon href=icon.png sizes=128x128> <script>function gtag(){dataLayer.push(arguments)}window.dataLayer=window.dataLayer||[],gtag("js",new Date),gtag("config","UA-139740394-1")</script> <script>!function(e,n,a,t){e.dmndata=[],e.jenniferFront=function(e){window.dmndata.push(e)},e.dmnaid=t,e.dmnatime=new Date,e.dmnanocookie=!1,e.dmnajennifer="JENNIFER_FRONT@INTG";var d=6e4*Math.floor((new Date).getTime()/6e4),c=n.createElement(a);c.src="https://d-collect.jennifersoft.com/"+t+"/demian.js?"+d,c.async=!0,n.getElementsByTagName(a)[0].parentNode.appendChild(c)}(window,document,"script","cc474308-b29c-af41-7393-409d285dca6e")</script> <meta charset=utf-8 /> <title>Fantastic Web Design Tool</title> <meta name=viewport content="width=device-width,initial-scale=1,user-scalable=no"/> <meta name=description content="You can make simply web with Web editor. "/> <meta name=keywords content=html5,css,svg,editor> <meta name=author content=easylogic> <meta property=og:title content="Fantastic Web Design Tool"/> <meta property=og:type content=website /> <meta property=og:description content="You can make simply web with Web editor. "/> <meta property=og:url content=https://www.easylogic.studio /> <meta property=og:image content=https://www.easylogic.studio/images/editor.png /> <meta property=twitter:card content=summary_large_image> <meta property=twitter:url content=https://www.easylogic.studio> <meta property=twitter:title content="Fantastic Web Design Tool"> <meta property=twitter:description content="You can make simply web with Web editor. "> <meta property=twitter:image content=https://www.easylogic.studio/images/editor.png> <script src=https://unpkg.com/shiki></script> <script src=https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.14.0/beautify.min.js></script> <script src=https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.14.0/beautify-css.min.js></script> <script src=https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.14.0/beautify-html.min.js></script> <meta name="apple-mobile-web-app-title" content="EasyLogic Studio" /><meta name="apple-mobile-web-app-capable" content="yes" /><meta name="apple-mobile-web-app-status-bar-style" content="black" /><link rel="manifest" href="/manifest.e398b874aa6339b677475253fffca031.json" crossorigin="use-credentials" /><link href="/editor.css?40b30dd630cff68e20bd" rel="stylesheet"></head> <body> <div id=app></div> <script type="text/javascript" src="/editor.js?eddc9be58c6e962890d2"></script></body> </html>
2 changes: 1 addition & 1 deletion docs/service-worker.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { EditorElement } from "el/editor/ui/common/EditorElement";
import { END, MOVE } from "el/editor/types/event";
import "./LayerAppendView.scss";
import { CSS_TO_STRING } from "el/utils/func";
import PathParser from 'el/editor/parser/PathParser';

export default class LayerAppendView extends EditorElement {

Expand Down Expand Up @@ -126,6 +127,20 @@ export default class LayerAppendView extends EditorElement {
</svg>
</div>
`
case 'svg-path':
const newD = this.state.d.clone().scale(width/this.state.bboxRect.width, height/this.state.bboxRect.height).d;
const options = this.state.options;
return /*html*/`
<div class='draw-item'>
<svg width="${width}" height="${height}" style="width:100%; height:100%;" overflow="visible">
<path d="${newD}"
stroke-width="${options['stroke-width'] || 1}"
stroke="${options['stroke'] || "black"}"
fill="${options['fill'] || 'transparent'}"
/>
</svg>
</div>
`
case 'svg-textpath':
return /*html*/`
<div class='draw-item' style='outline: 1px solid blue;'>
Expand Down Expand Up @@ -302,6 +317,9 @@ export default class LayerAppendView extends EditorElement {
case 'svg-textpath':
delete rect['background-color'];
break;
case "svg-path":
rect['d'] = this.state.d.clone().scale(width/this.state.bboxRect.width, height/this.state.bboxRect.height).d;
break;
default:
delete rect['content'];
break;
Expand Down Expand Up @@ -361,6 +379,11 @@ export default class LayerAppendView extends EditorElement {
"transform-origin": true,
}))

if (options.d) {
this.state.d = new PathParser(options.d);
this.state.bboxRect = this.state.d.rect();
}

this.emit('push.mode.view', 'LayerAppendView');
}

Expand Down
9 changes: 3 additions & 6 deletions src/editor-layouts/designeditor/area/LayerTab.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,10 @@ export default class LayerTab extends EditorElement {
</div>
${this.$injectManager.getTargetMenuItems('leftbar.tab').map(it => {
const { value, title} = it.class;
const { value, title} = it.class;
return /*html*/`
<div class='tab-item' data-value='${value}' data-direction="right" data-tooltip="${title}">
<label>${icon[it.class.icon] || it.class.icon}</label>
<label>${icon[it.class.icon] || it.class.icon || title}</label>
</div>
`
})}
Expand All @@ -76,12 +76,9 @@ export default class LayerTab extends EditorElement {
<object refClass="CustomAssets" />
</div>
${this.$injectManager.getTargetMenuItems('leftbar.tab').map(it => {
const { value, title, loadElements } = it.class;
const { value } = it.class;
return /*html*/`
<div class='tab-content' data-value='${value}'>
${loadElements.map(element => {
return `<object refClass="${element}" />`
}).join('\n')}
${this.$injectManager.generate(`leftbar.tab.${value}`)}
</div>
`
Expand Down
3 changes: 3 additions & 0 deletions src/editor-layouts/designeditor/area/ToolBar.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@ import Redo from "el/editor/ui/menu-items/Redo";
import ExportView from 'el/editor/ui/menu-items/ExportView';
import Download from 'el/editor/ui/menu-items/Download';
import Save from 'el/editor/ui/menu-items/Save';
import OpenPathEditor from "el/editor/ui/menu-items/OpenPathEditor";


export default class ToolBar extends EditorElement {

components() {
return {
OpenPathEditor,
ExportView,
Download,
Save,
Expand All @@ -41,6 +43,7 @@ export default class ToolBar extends EditorElement {
<div class='draw-items'>
<object refClass="Undo" />
<object refClass="Redo" />
<object refClass="OpenPathEditor" />
${this.$injectManager.generate('toolbar.left')}
</div>
</div>
Expand Down
7 changes: 5 additions & 2 deletions src/editor-layouts/designeditor/area/tool-bar/ToolMenu.scss
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
.elf--tool-menu {
color: var(--elf--selected-font-color);
padding: 8px 0px;
// padding: 8px 0px;
width: 100%;

&.center{
text-align: center;
Expand All @@ -19,7 +20,9 @@


.draw-items {

height: 100%;
box-sizing: border-box;
padding: 8px 0px;
&[data-selected-value="svg"] {
[data-item="css"] {
display: none;
Expand Down
3 changes: 1 addition & 2 deletions src/el/editor/commands/newComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,7 @@ export default function newComponent (editor, itemType, obj, isSelected = true,
'background-color': undefined,
fill: `#C4C4C4`,
d: PathStringManager.makeRect(0, 0, obj.width.value, obj.height.value),
}

}
} else if (itemType === 'text') {
obj = {
width: Length.px(300),
Expand Down
2 changes: 1 addition & 1 deletion src/el/editor/icon/shape.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
import _icon_template from "./_icon_template";

export default _icon_template(`<path d="M23 7V1h-6v2H7V1H1v6h2v10H1v6h6v-2h10v2h6v-6h-2V7h2zM3 3h2v2H3V3zm2 18H3v-2h2v2zm12-2H7v-2H5V7h2V5h10v2h2v10h-2v2zm4 2h-2v-2h2v2zM19 5V3h2v2h-2zm-5.27 9h-3.49l-.73 2H7.89l3.4-9h1.4l3.41 9h-1.63l-.74-2zm-3.04-1.26h2.61L12 8.91l-1.31 3.83z"/>`);
export default _icon_template(`<path d="M23 7V1h-6v2H7V1H1v6h2v10H1v6h6v-2h10v2h6v-6h-2V7h2zM3 3h2v2H3V3zm2 18H3v-2h2v2zm12-2H7v-2H5V7h2V5h10v2h2v10h-2v2zm4 2h-2v-2h2v2zM19 5V3h2v2h-2z"/>`);
7 changes: 7 additions & 0 deletions src/el/editor/manager/InjectManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ export class InjectManager {
this.menuItems = {}
}

/**
*
* 특정 영역에 들어갈 메뉴를 추가한다.
*
* @param {string} target
* @param {object} obj
*/
registerMenuItem(target, obj) {

if (!this.menuItems[target]) {
Expand Down
4 changes: 4 additions & 0 deletions src/el/editor/manager/SelectionManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -739,4 +739,8 @@ export class SelectionManager {

return isChanged;
}

is (...args) {
return this.current?.is(...args);
}
}
68 changes: 61 additions & 7 deletions src/el/editor/parser/PathParser.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,16 @@ export default class PathParser {

reset(pathString = '') {
this.segments = [];
this.pathString = pathString;
this.pathString = pathString.trim();

this.parse()
}

resetSegments(segments) {
this.segments = segments || []
this.pathString = this.joinPath()

return this;
}

trim(str = '') {
Expand Down Expand Up @@ -531,13 +533,21 @@ export default class PathParser {
} else if (segment.command === 'C') {
newSegments.push(segment);
} else if (segment.command === 'Q') {
prevSegment.values[0];


newSegments.push({
command: 'C',
values: [
segment.values[0],
segment.values[1],
segment.values[0],
segment.values[1],
// C1 = Q0 + (2/3) (Q1 - Q0)
prevSegment.values[0] + (2/3) (segment.values[0] - prevSegment.values[0]),
prevSegment.values[1] + (2/3) (segment.values[1] - prevSegment.values[1]),

// C2 = Q2 + (2/3) (Q1 - Q2)
segment.values[2] + (2/3) (segment.values[0] - segment.values[2]),
segment.values[3] + (2/3) (segment.values[1] - segment.values[3]),

// C3 = Q2
segment.values[2],
segment.values[3]
]
Expand Down Expand Up @@ -687,7 +697,7 @@ export default class PathParser {
})
break;
case 'Q':

// TODO: 정상적으로 동작하지 않는 듯 하다.
const newPoints = [
[prevSegment.values[prevSegment.values.length - 2], prevSegment.values[prevSegment.values.length - 1], 0],
[v[0], v[1], 0],
Expand All @@ -713,7 +723,6 @@ export default class PathParser {
return segment;
});


return [
[minX, minY, 0],
[maxX, minY, 0],
Expand All @@ -722,6 +731,19 @@ export default class PathParser {
]
}

rect () {
const bbox = this.getBBox();

return {
x: bbox[0][0],
y: bbox[0][1],
width: vec3.distance(bbox[0], bbox[1]),
height: vec3.distance(bbox[0], bbox[3]),
right: bbox[0][0] + vec3.distance(bbox[0], bbox[1]),
bottom: bbox[0][1] + vec3.distance(bbox[0], bbox[3]),
}
}

/**
* x, y 를 기준으로 가장 가까운 점을 찾는다.
*
Expand Down Expand Up @@ -1237,4 +1259,36 @@ export default class PathParser {
}
}

/**
* convert to multi segment path list
*/
toMultiSegmentPathList() {
const paths = []

const group = this.getGroup();
group.forEach((group, index) => {
group.segments.forEach((s, index) => {
const prevSegment = group.segments[index - 1];
const lastValues = prevSegment?.segment?.values || [];
const lastX = lastValues[lastValues.length - 2];
const lastY = lastValues[lastValues.length - 1];
const values = s.segment.values;

if (s.segment.command === 'M') {
// NOOP
} else if (s.segment.command === 'L') {
paths.push(new PathParser(`M ${lastX} ${lastY}L ${values.join(' ')}`));
} else if (s.segment.command === 'C') {
paths.push(new PathParser(`M ${lastX} ${lastY}C ${values.join(' ')}`));
} else if (s.segment.command === 'Q') {
paths.push(new PathParser(`M ${lastX} ${lastY}Q ${values.join(' ')}`));
} else {
// NOOP
}
})
});

return paths;
}

}
7 changes: 7 additions & 0 deletions src/el/editor/parser/PathParser.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,13 @@ test("path bbox for curve", () => {
expect(path.getBBox()).toStrictEqual([[0, 0, 0], [30, 0, 0], [30, 30, 0], [0, 30, 0]]);
})

test("path bbox for multi segment", () => {
const path = new PathParser("M 37.93732341720084 0C 81.2916762789344 0 -5.417029444532609 35.59336238843551 139.0385024508094 72.37594604492188C -5.417029444532609 123.40663761156449 139.0385024508094 155.75717163085938 95.68414958907584 155.75717163085938C 52.32979672734239 155.75717163085938 -40.56267658279916 123.40663761156449 103.89285531254285 72.37594604492188C -40.56267658279916 35.59336238843551 -5.417029444532609 0 37.93732341720084 0Z");
const rect = path.rect();
expect(rect.width).toBe(139.0385024508094);
expect(rect.height).toBe(155.75717163085938);
})

test("path reset", () => {
const path = new PathParser("M0,0 L4,0 L4,4 L0,4");
path.reset("M0,0 L10,10");
Expand Down
30 changes: 30 additions & 0 deletions src/el/editor/ui/menu-items/OpenPathEditor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { DEBOUNCE, SUBSCRIBE } from "el/sapa/Event";
import MenuItem from "./MenuItem";

export default class OpenPathEditor extends MenuItem {
getIconString() {
return 'shape';
}
getTitle() {
return "Edit";
}

isHideTitle() {
return true;
}

clickButton(e) {
this.emit('open.editor');
}

[SUBSCRIBE('refreshSelection') + DEBOUNCE(100)] () {
const enablePathEditing = this.$selection.is("svg-path", "svg-textpath") || this.$selection.current?.cacheClipPathObject?.type === 'path';

if (enablePathEditing) {
this.$el.show('inline-block');
} else {
this.$el.hide();
}

}
}
Loading

0 comments on commit 52b92db

Please sign in to comment.