Merge branch 'master' of https://github.com/SVG-Edit/svgedit into V7-preview
22
.eslintrc.js
@@ -21,10 +21,26 @@ module.exports = {
|
|||||||
es6: true
|
es6: true
|
||||||
},
|
},
|
||||||
rules: {
|
rules: {
|
||||||
|
/** @todo len should probably more 120-150 */
|
||||||
|
"max-len": [ "warn", { "code": 250 } ],
|
||||||
|
/** @todo jsdoc should be made warn or error */
|
||||||
|
"valid-jsdoc": "off",
|
||||||
|
/** @todo cognitive complexity should be much lower (25-50?) */
|
||||||
|
"sonarjs/cognitive-complexity": [ "warn", 200 ],
|
||||||
"node/no-unsupported-features/es-syntax": 0,
|
"node/no-unsupported-features/es-syntax": 0,
|
||||||
"no-unused-vars": [ "error", { "argsIgnorePattern": "^_" } ],
|
"no-unused-vars": [ "error", { "argsIgnorePattern": "^_" } ],
|
||||||
"sonarjs/cognitive-complexity": ["warn", 40],
|
|
||||||
"sonarjs/no-duplicate-string": 0,
|
"sonarjs/no-duplicate-string": 0,
|
||||||
|
"semi" : "error",
|
||||||
|
"no-trailing-spaces": "error",
|
||||||
|
"array-bracket-spacing": [ "error", "always" ],
|
||||||
|
"comma-spacing": "error",
|
||||||
|
"object-curly-spacing": [ "error", "always" ],
|
||||||
|
"no-console": [
|
||||||
|
"warn",
|
||||||
|
{ "allow": [ "warn", "error", "info", "table" ] }
|
||||||
|
],
|
||||||
|
"no-param-reassign": [ "warn", { "props": false } ],
|
||||||
|
"arrow-parens": [ "error", "always" ],
|
||||||
},
|
},
|
||||||
overrides: [
|
overrides: [
|
||||||
{
|
{
|
||||||
@@ -36,9 +52,7 @@ module.exports = {
|
|||||||
mocha: true,
|
mocha: true,
|
||||||
node: true
|
node: true
|
||||||
},
|
},
|
||||||
globals: {
|
globals: { "assert": true },
|
||||||
"assert": true
|
|
||||||
},
|
|
||||||
rules: {
|
rules: {
|
||||||
// with ci, instrumented is not created before linter
|
// with ci, instrumented is not created before linter
|
||||||
"import/no-unresolved": [ 2, { ignore: [ 'instrumented' ] } ],
|
"import/no-unresolved": [ 2, { ignore: [ 'instrumented' ] } ],
|
||||||
|
|||||||
30
README.md
@@ -1,4 +1,6 @@
|
|||||||
#  SVG-edit
|
<img src="https://svg-edit.github.io/svgedit/src/editor/images/logo.svg" width="50" height="50" />
|
||||||
|
|
||||||
|
# SVG-Edit
|
||||||
|
|
||||||
[](https://www.npmjs.com/package/svgedit)
|
[](https://www.npmjs.com/package/svgedit)
|
||||||
[](https://david-dm.org/SVG-Edit/svgedit)
|
[](https://david-dm.org/SVG-Edit/svgedit)
|
||||||
@@ -18,14 +20,6 @@
|
|||||||
|
|
||||||
(see also [licenses for dev. deps.](https://raw.githubusercontent.com/SVG-Edit/svgedit/master/badges/licenses-badge-dev.svg?sanitize=true))
|
(see also [licenses for dev. deps.](https://raw.githubusercontent.com/SVG-Edit/svgedit/master/badges/licenses-badge-dev.svg?sanitize=true))
|
||||||
|
|
||||||
(Note: The license provenance of the images in `/editor/images` may not be
|
|
||||||
fully clear, even with the origin of some of the images listed as being from <http://tango.freedesktop.org/static/cvs/tango-art-libre/22x22/>. We would like to
|
|
||||||
replace these images if their provenance cannot be determined or is found to
|
|
||||||
be under a protective license. If you know of the original terms, or can help
|
|
||||||
create SVG replacement images, please let us know at:
|
|
||||||
[#377](https://github.com/SVG-Edit/svgedit/issues/377).)
|
|
||||||
<!-- [](LICENSE-MIT) -->
|
|
||||||
|
|
||||||
[](https://issuehunt.io/r/SVG-Edit/svgedit)
|
[](https://issuehunt.io/r/SVG-Edit/svgedit)
|
||||||
|
|
||||||
SVG-edit is a fast, web-based, JavaScript-driven SVG drawing editor that
|
SVG-edit is a fast, web-based, JavaScript-driven SVG drawing editor that
|
||||||
@@ -36,25 +30,21 @@ works in any modern browser.
|
|||||||
|
|
||||||
## Help wanted
|
## Help wanted
|
||||||
|
|
||||||
While we have made some recent releases to SVG-edit for bug fixes,
|
We need more maintainers for SVG-Edit
|
||||||
refactoring and documentation to make the codebase more maintainable, the
|
|
||||||
core developers responsible for the bulk of the drawing features are no
|
|
||||||
longer active with the project, so we would love others familiar with SVG
|
|
||||||
to join the project.
|
|
||||||
|
|
||||||
## Demo
|
## Demo
|
||||||
|
|
||||||
### [Try SVG-edit here](https://svg-edit.github.io/svgedit/dist/editor/index.html)
|
### [Try SVG-edit here](https://svgedit.netlify.app/editor/index.html)
|
||||||
|
|
||||||
We also build a systemJS version at [`master`](https://svg-edit.github.io/svgedit/dist/editor/system/index.html)
|
Thanks to netlify, you can test the following builds:
|
||||||
|
|
||||||
You may also obtain URLs for specific [releases](https://github.com/SVG-Edit/svgedit/releases).
|
[Try SVG-edit 5.1.0 here](https://6098683962bf91702907ee33--svgedit.netlify.app/editor/svg-editor.html)
|
||||||
|
|
||||||
Thanks to netlify, you can test the following versions:
|
[Try SVG-edit 6.1.0 here](https://60a0000fc9900b0008fd268d--svgedit.netlify.app/editor/index.html)
|
||||||
|
|
||||||
|
/
|
||||||
|
|
||||||
latest master build (V6): https://svgedit.netlify.app/editor/index.html
|
|
||||||
|
|
||||||
V7 preview (under development): https://deploy-preview-465--svgedit.netlify.app/editor/index.html
|
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ Current Tasks
|
|||||||
|
|
||||||
1) I introduced the concept of a Drawing earlier on that would encapsulate the state of a single open SVG document. The SVG editor has a handle to the current drawing and uses that instead of accessing svg DOM elements directly. Eventually all code that deals with layers, current editing context, document history and more will be moved into draw.js but for now, much of that code still lives in svgcanvas.js.
|
1) I introduced the concept of a Drawing earlier on that would encapsulate the state of a single open SVG document. The SVG editor has a handle to the current drawing and uses that instead of accessing svg DOM elements directly. Eventually all code that deals with layers, current editing context, document history and more will be moved into draw.js but for now, much of that code still lives in svgcanvas.js.
|
||||||
|
|
||||||
2) I'm in the process of migrating a large chunk of svgcanvas.js called "pathActions" into its own module (path.js). This piece of code did have a lot of dependencies so moving it piece-by-piece seemed like the right way to go. Currently it's about half-way migrated, with most of the 'public API' still living in svgcanvas.js.
|
1) I'm in the process of migrating a large chunk of svgcanvas.js called "pathActions" into its own module (path.js). This piece of code did have a lot of dependencies so moving it piece-by-piece seemed like the right way to go. Currently it's about half-way migrated, with most of the 'public API' still living in svgcanvas.js.
|
||||||
TODOs
|
TODOs
|
||||||
|
|
||||||
Finish moving layers functionality into the Drawing class
|
Finish moving layers functionality into the Drawing class
|
||||||
|
|||||||
@@ -623,12 +623,12 @@ exports[`use various parts of svg-edit > check tool_star #0`] = `
|
|||||||
point="5"
|
point="5"
|
||||||
r="66.66666666666667"
|
r="66.66666666666667"
|
||||||
radialshift="0"
|
radialshift="0"
|
||||||
r2="13.333333333333334"
|
r2="22.222222222222225"
|
||||||
orient="point"
|
orient="point"
|
||||||
fill="#ffff00"
|
fill="#ffff00"
|
||||||
strokecolor="#000000"
|
strokecolor="#000000"
|
||||||
strokewidth="0"
|
strokewidth="0"
|
||||||
points="370,135.33333333333331 377.83713669723295,191.21310674166736 433.40376775301024,181.39886704167017 382.68075355060205,206.12022659166595 409.18568348616486,255.93446629166317 370,215.33333333333334 330.81431651383514,255.93446629166317 357.31924644939795,206.12022659166595 306.59623224698976,181.39886704167017 362.16286330276705,191.21310674166736 370,135.33333333333331 377.83713669723295,191.21310674166736 "
|
points="370,135.33333333333331 383.0618944953883,184.02184456944562 433.40376775301024,181.39886704167017 391.13458925100343,208.86704431944327 409.18568348616486,255.93446629166317 370,224.22222222222223 330.81431651383514,255.93446629166317 348.86541074899657,208.86704431944327 306.59623224698976,181.39886704167017 356.9381055046117,184.02184456944562 370,135.33333333333331 383.0618944953883,184.02184456944562 "
|
||||||
stroke="#000000"
|
stroke="#000000"
|
||||||
stroke-width="0"
|
stroke-width="0"
|
||||||
>
|
>
|
||||||
@@ -713,12 +713,12 @@ exports[`use various parts of svg-edit > check tool_polygon #0`] = `
|
|||||||
point="5"
|
point="5"
|
||||||
r="66.66666666666667"
|
r="66.66666666666667"
|
||||||
radialshift="0"
|
radialshift="0"
|
||||||
r2="13.333333333333334"
|
r2="22.222222222222225"
|
||||||
orient="point"
|
orient="point"
|
||||||
fill="#ffff00"
|
fill="#ffff00"
|
||||||
strokecolor="#000000"
|
strokecolor="#000000"
|
||||||
strokewidth="0"
|
strokewidth="0"
|
||||||
points="370,135.33333333333331 377.83713669723295,191.21310674166736 433.40376775301024,181.39886704167017 382.68075355060205,206.12022659166595 409.18568348616486,255.93446629166317 370,215.33333333333334 330.81431651383514,255.93446629166317 357.31924644939795,206.12022659166595 306.59623224698976,181.39886704167017 362.16286330276705,191.21310674166736 370,135.33333333333331 377.83713669723295,191.21310674166736 "
|
points="370,135.33333333333331 383.0618944953883,184.02184456944562 433.40376775301024,181.39886704167017 391.13458925100343,208.86704431944327 409.18568348616486,255.93446629166317 370,224.22222222222223 330.81431651383514,255.93446629166317 348.86541074899657,208.86704431944327 306.59623224698976,181.39886704167017 356.9381055046117,184.02184456944562 370,135.33333333333331 383.0618944953883,184.02184456944562 "
|
||||||
stroke="#000000"
|
stroke="#000000"
|
||||||
stroke-width="0"
|
stroke-width="0"
|
||||||
fill-opacity="1"
|
fill-opacity="1"
|
||||||
|
|||||||
@@ -105,4 +105,22 @@ describe('use various parts of svg-edit', function () {
|
|||||||
.trigger('mouseup', { force: true });
|
.trigger('mouseup', { force: true });
|
||||||
testSnapshot();
|
testSnapshot();
|
||||||
});
|
});
|
||||||
|
it('check tool_star', function () {
|
||||||
|
cy.get('#tool_star')
|
||||||
|
.click({force: true});
|
||||||
|
cy.get('#svgcontent')
|
||||||
|
.trigger('mousedown', 300, 150, {force: true})
|
||||||
|
.trigger('mousemove', 300, 250, {force: true})
|
||||||
|
.trigger('mouseup', {force: true});
|
||||||
|
testSnapshot();
|
||||||
|
});
|
||||||
|
it('check tool_polygon', function () {
|
||||||
|
cy.get('#tool_polygon')
|
||||||
|
.click({force: true});
|
||||||
|
cy.get('#svgcontent')
|
||||||
|
.trigger('mousedown', 350, 250, {force: true})
|
||||||
|
.trigger('mousemove', 350, 370, {force: true})
|
||||||
|
.trigger('mouseup', {force: true});
|
||||||
|
testSnapshot();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -727,7 +727,6 @@ describe('draw.Drawing', function () {
|
|||||||
drawing.setLayerOpacity(LAYER3, -1.4);
|
drawing.setLayerOpacity(LAYER3, -1.4);
|
||||||
|
|
||||||
assert.strictEqual(drawing.getLayerOpacity(LAYER1), 0.4);
|
assert.strictEqual(drawing.getLayerOpacity(LAYER1), 0.4);
|
||||||
// console.log('layer2 opacity ' + drawing.getLayerOpacity(LAYER2));
|
|
||||||
assert.strictEqual(drawing.getLayerOpacity(LAYER2), 1.0);
|
assert.strictEqual(drawing.getLayerOpacity(LAYER2), 1.0);
|
||||||
assert.strictEqual(drawing.getLayerOpacity(LAYER3), 1.0);
|
assert.strictEqual(drawing.getLayerOpacity(LAYER3), 1.0);
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,28 @@ describe('select', function () {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
const dataStorage = {
|
||||||
|
_storage: new WeakMap(),
|
||||||
|
put: function (element, key, obj) {
|
||||||
|
if (!this._storage.has(element)) {
|
||||||
|
this._storage.set(element, new Map());
|
||||||
|
}
|
||||||
|
this._storage.get(element).set(key, obj);
|
||||||
|
},
|
||||||
|
get: function (element, key) {
|
||||||
|
return this._storage.get(element).get(key);
|
||||||
|
},
|
||||||
|
has: function (element, key) {
|
||||||
|
return this._storage.has(element) && this._storage.get(element).has(key);
|
||||||
|
},
|
||||||
|
remove: function (element, key) {
|
||||||
|
var ret = this._storage.get(element).delete(key);
|
||||||
|
if (!this._storage.get(element).size === 0) {
|
||||||
|
this._storage.delete(element);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @implements {module:select.SVGFactory}
|
* @implements {module:select.SVGFactory}
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ describe('Basic Module', function () {
|
|||||||
workarea.append(svgcanvas);
|
workarea.append(svgcanvas);
|
||||||
const toolsLeft = document.createElement('div');
|
const toolsLeft = document.createElement('div');
|
||||||
toolsLeft.id = 'tools_left';
|
toolsLeft.id = 'tools_left';
|
||||||
|
|
||||||
svgEditor.append(workarea, toolsLeft);
|
svgEditor.append(workarea, toolsLeft);
|
||||||
document.body.append(svgEditor);
|
document.body.append(svgEditor);
|
||||||
|
|
||||||
@@ -159,8 +158,6 @@ describe('Basic Module', function () {
|
|||||||
assert.strictEqual(attrVal, 'bar', true, 'Preserved namespaced attribute on import');
|
assert.strictEqual(attrVal, 'bar', true, 'Preserved namespaced attribute on import');
|
||||||
|
|
||||||
const output = svgCanvas.getSvgString();
|
const output = svgCanvas.getSvgString();
|
||||||
// } catch(e) {console.log(e)}
|
|
||||||
// console.log('output',output);
|
|
||||||
const hasXlink = output.includes('xmlns:xlink="http://www.w3.org/1999/xlink"');
|
const hasXlink = output.includes('xmlns:xlink="http://www.w3.org/1999/xlink"');
|
||||||
const hasSe = output.includes('xmlns:se=');
|
const hasSe = output.includes('xmlns:se=');
|
||||||
const hasFoo = output.includes('xmlns:foo=');
|
const hasFoo = output.includes('xmlns:foo=');
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<title>Minimal demo of SvgCanvas</title>
|
<title>Minimal demo of SvgCanvas</title>
|
||||||
<script src="../src/editor/jquery.min.js"></script>
|
<script src="../src/editor/jquery.min.js"></script>
|
||||||
<style> #svgroot { overflow: hidden; } </style>
|
<style> #svgroot { overflow: hidden; } </style>
|
||||||
<link rel="shortcut icon" type="image/x-icon" href="../src/editor/images/logo.png" />
|
<link rel="shortcut icon" type="image/x-icon" href="../src/editor/images/logo.svg" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
@@ -37,7 +37,7 @@ const config = {
|
|||||||
initStroke: { color: '000000', opacity: 1, width: 1 },
|
initStroke: { color: '000000', opacity: 1, width: 1 },
|
||||||
text: { stroke_width: 0, font_size: 24, font_family: 'serif' },
|
text: { stroke_width: 0, font_size: 24, font_family: 'serif' },
|
||||||
initOpacity: 1,
|
initOpacity: 1,
|
||||||
imgPath: 'editor/images/',
|
imgPath: '../src/editor/images/',
|
||||||
dimensions: [ width, height ],
|
dimensions: [ width, height ],
|
||||||
baseUnit: 'px'
|
baseUnit: 'px'
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,58 +3,7 @@
|
|||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
plugins: [ 'plugins/markdown' ],
|
plugins: [ 'plugins/markdown' ],
|
||||||
markdown: {
|
markdown: {},
|
||||||
// tags: ['examples']
|
|
||||||
/*
|
|
||||||
// "The highlighter function should escape the code block's contents and wrap them in <pre><code> tags"
|
|
||||||
highlight (code, language) {
|
|
||||||
function ret () {
|
|
||||||
// Default:
|
|
||||||
return '<pre><code>' + code + ' in this language: ' + language + '</code></pre>';
|
|
||||||
}
|
|
||||||
if (language !== 'js') { // E.g., we have one URL in some tutorial Markdown
|
|
||||||
// Seems to be only for full triple-backticked fences
|
|
||||||
// console.log('lll', code);
|
|
||||||
return ret();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Programmatic ESLint API: https://eslint.org/docs/developer-guide/nodejs-api
|
|
||||||
const {CLIEngine} = require('eslint');
|
|
||||||
const cli = new CLIEngine({
|
|
||||||
useEslintrc: true,
|
|
||||||
rules: {
|
|
||||||
'no-undef': 0, // Many variables in examples will be undefined
|
|
||||||
'padded-blocks': 0 // Can look nicer
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Undo escaping done by node_modules/jsdoc/lib/jsdoc/util/markdown.js
|
|
||||||
code = code
|
|
||||||
.replace(/\s+$/, '')
|
|
||||||
.replace(/'/g, "'")
|
|
||||||
.replace(/(https?):\\\/\\\//g, '$1://')
|
|
||||||
.replace(/\{@[^}\r\n]+\}/g, function (wholeMatch) {
|
|
||||||
return wholeMatch.replace(/"/g, '"');
|
|
||||||
});
|
|
||||||
|
|
||||||
// lint the supplied text and optionally set
|
|
||||||
// a filename that is displayed in the report
|
|
||||||
const report = cli.executeOnText(code + '\n');
|
|
||||||
if (!report.errorCount && !report.warningCount) {
|
|
||||||
return ret();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Although we don't get the file, at least we can report the source code
|
|
||||||
const {messages} = report.results[0];
|
|
||||||
messages.forEach(({message, line, column, severity, ruleId}) => {
|
|
||||||
console.log(`${ruleId}: ${message} (Severity: ${severity}; ${line}:${column})`);
|
|
||||||
});
|
|
||||||
console.log('\n' + code);
|
|
||||||
|
|
||||||
return ret();
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
},
|
|
||||||
recurseDepth: 10,
|
recurseDepth: 10,
|
||||||
source: {
|
source: {
|
||||||
exclude: [
|
exclude: [
|
||||||
|
|||||||
@@ -14,11 +14,6 @@
|
|||||||
# Default build command.
|
# Default build command.
|
||||||
command = "npm run build"
|
command = "npm run build"
|
||||||
|
|
||||||
# Production context: all deploys from the Production branch set in your site's
|
|
||||||
# deploy contexts will inherit these settings.
|
|
||||||
[context."v7-preview"]
|
|
||||||
publish = "/"
|
|
||||||
|
|
||||||
[context."release-v6.0.0"]
|
[context."release-v6.0.0"]
|
||||||
publish = "/"
|
publish = "/"
|
||||||
command = "echo 'branch release-v6.0.0 already built'"
|
command = "echo 'branch release-v6.0.0 already built'"
|
||||||
@@ -27,9 +22,6 @@
|
|||||||
publish = "/"
|
publish = "/"
|
||||||
command = "echo 'branch release-v5.1.0 already built'"
|
command = "echo 'branch release-v5.1.0 already built'"
|
||||||
|
|
||||||
[context.master]
|
|
||||||
publish = "/"
|
|
||||||
command = "echo 'already built'"
|
|
||||||
|
|
||||||
# Production context: all deploys from the Production branch set in your site's
|
# Production context: all deploys from the Production branch set in your site's
|
||||||
# deploy contexts will inherit these settings.
|
# deploy contexts will inherit these settings.
|
||||||
|
|||||||
2238
package-lock.json
generated
41
package.json
@@ -40,15 +40,8 @@
|
|||||||
"build-and-open-docs-no-start": "run-s build-docs open-docs-no-start",
|
"build-and-open-docs-no-start": "run-s build-docs open-docs-no-start",
|
||||||
"build-and-open-docs": "run-s build-docs open-docs",
|
"build-and-open-docs": "run-s build-docs open-docs",
|
||||||
"open-embedded-no-start": "open-cli http://localhost:8000/editor/embedapi.html",
|
"open-embedded-no-start": "open-cli http://localhost:8000/editor/embedapi.html",
|
||||||
"open-embedded": "run-p start-embedded open-embedded-no-start",
|
|
||||||
"open-all-ext-no-start": "open-cli http://localhost:8000/src/editor/svg-editor-es.html?extensions=ext-arrows.js,ext-closepath.js,ext-foreignobject.js,ext-helloworld.js,ext-mathjax.js,ext-php_savefile.js,ext-server_moinsave.js,ext-server_opensave.js,ext-webappfind.js,ext-xdomain-messaging.js",
|
"open-all-ext-no-start": "open-cli http://localhost:8000/src/editor/svg-editor-es.html?extensions=ext-arrows.js,ext-closepath.js,ext-foreignobject.js,ext-helloworld.js,ext-mathjax.js,ext-php_savefile.js,ext-server_moinsave.js,ext-server_opensave.js,ext-webappfind.js,ext-xdomain-messaging.js",
|
||||||
"open-all-ext": "run-p start open-all-ext-no-start",
|
|
||||||
"open-compiled-no-start": "open-cli http://localhost:8000/src/editor/svg-editor.html",
|
"open-compiled-no-start": "open-cli http://localhost:8000/src/editor/svg-editor.html",
|
||||||
"open-compiled": "run-p start open-compiled-no-start",
|
|
||||||
"open-no-start": "open-cli http://localhost:8000/src/editor/svg-editor-es.html",
|
|
||||||
"open": "run-p start open-no-start",
|
|
||||||
"open-cov-no-start": "open-cli http://localhost:8000/coverage/",
|
|
||||||
"open-cov": "run-p start open-cov-no-start",
|
|
||||||
"report": "run-s report-no-mochawesome mochawesome-cli",
|
"report": "run-s report-no-mochawesome mochawesome-cli",
|
||||||
"report-summary": "run-s report-text-summary mochawesome-cli-dot",
|
"report-summary": "run-s report-text-summary mochawesome-cli-dot",
|
||||||
"coverage-badge": "coveradge badges/coverage-badge",
|
"coverage-badge": "coveradge badges/coverage-badge",
|
||||||
@@ -113,7 +106,7 @@
|
|||||||
"@babel/polyfill": "7.12.1",
|
"@babel/polyfill": "7.12.1",
|
||||||
"@web/dev-server-rollup": "0.3.3",
|
"@web/dev-server-rollup": "0.3.3",
|
||||||
"canvg": "3.0.7",
|
"canvg": "3.0.7",
|
||||||
"core-js": "3.11.0",
|
"core-js": "3.12.1",
|
||||||
"deparam": "^1.0.5",
|
"deparam": "^1.0.5",
|
||||||
"elix": "^15.0.0",
|
"elix": "^15.0.0",
|
||||||
"i18next": "^20.2.2",
|
"i18next": "^20.2.2",
|
||||||
@@ -124,10 +117,10 @@
|
|||||||
"svg2pdf.js": "2.1.0"
|
"svg2pdf.js": "2.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "7.13.16",
|
"@babel/core": "7.14.2",
|
||||||
"@babel/preset-env": "7.13.15",
|
"@babel/preset-env": "7.14.2",
|
||||||
"@babel/register": "7.13.16",
|
"@babel/register": "7.13.16",
|
||||||
"@babel/runtime-corejs3": "7.13.17",
|
"@babel/runtime-corejs3": "7.14.0",
|
||||||
"@cypress/code-coverage": "3.9.5",
|
"@cypress/code-coverage": "3.9.5",
|
||||||
"@cypress/fiddle": "1.19.2",
|
"@cypress/fiddle": "1.19.2",
|
||||||
"@fintechstudios/eslint-plugin-chai-as-promised": "3.1.0",
|
"@fintechstudios/eslint-plugin-chai-as-promised": "3.1.0",
|
||||||
@@ -139,30 +132,30 @@
|
|||||||
"@rollup/plugin-node-resolve": "11.2.1",
|
"@rollup/plugin-node-resolve": "11.2.1",
|
||||||
"@rollup/plugin-replace": "2.4.2",
|
"@rollup/plugin-replace": "2.4.2",
|
||||||
"@rollup/plugin-url": "6.0.0",
|
"@rollup/plugin-url": "6.0.0",
|
||||||
"@web/dev-server": "^0.1.16",
|
"@web/dev-server": "^0.1.17",
|
||||||
"axe-core": "4.2.0",
|
"axe-core": "4.2.0",
|
||||||
"babel-plugin-transform-object-rest-spread": "7.0.0-beta.3",
|
"babel-plugin-transform-object-rest-spread": "7.0.0-beta.3",
|
||||||
"copyfiles": "2.4.1",
|
"copyfiles": "2.4.1",
|
||||||
"core-js-bundle": "3.11.0",
|
"core-js-bundle": "3.12.1",
|
||||||
"coveradge": "0.6.0",
|
"coveradge": "0.6.0",
|
||||||
"cp-cli": "2.0.0",
|
"cp-cli": "2.0.0",
|
||||||
"cross-var": "1.1.0",
|
"cross-var": "1.1.0",
|
||||||
"cypress": "7.2.0",
|
"cypress": "7.3.0",
|
||||||
"cypress-axe": "0.12.2",
|
"cypress-axe": "0.12.2",
|
||||||
"cypress-multi-reporters": "1.5.0",
|
"cypress-multi-reporters": "1.5.0",
|
||||||
"cypress-plugin-snapshots": "1.4.4",
|
"cypress-plugin-snapshots": "1.4.4",
|
||||||
"eslint": "^7.25.0",
|
"eslint": "^7.26.0",
|
||||||
"eslint-config-standard": "16.0.2",
|
"eslint-config-standard": "16.0.2",
|
||||||
"eslint-plugin-array-func": "3.1.7",
|
"eslint-plugin-array-func": "3.1.7",
|
||||||
"eslint-plugin-chai-expect": "2.2.0",
|
"eslint-plugin-chai-expect": "2.2.0",
|
||||||
"eslint-plugin-chai-expect-keywords": "2.1.0",
|
"eslint-plugin-chai-expect-keywords": "2.1.0",
|
||||||
"eslint-plugin-chai-friendly": "0.6.0",
|
"eslint-plugin-chai-friendly": "0.7.1",
|
||||||
"eslint-plugin-compat": "^3.9.0",
|
"eslint-plugin-compat": "^3.9.0",
|
||||||
"eslint-plugin-cypress": "2.11.2",
|
"eslint-plugin-cypress": "2.11.3",
|
||||||
"eslint-plugin-eslint-comments": "3.2.0",
|
"eslint-plugin-eslint-comments": "3.2.0",
|
||||||
"eslint-plugin-html": "^6.1.2",
|
"eslint-plugin-html": "^6.1.2",
|
||||||
"eslint-plugin-import": "^2.22.1",
|
"eslint-plugin-import": "2.23.0",
|
||||||
"eslint-plugin-jsdoc": "^32.3.3",
|
"eslint-plugin-jsdoc": "34.2.2",
|
||||||
"eslint-plugin-markdown": "^2.1.0",
|
"eslint-plugin-markdown": "^2.1.0",
|
||||||
"eslint-plugin-mocha": "8.1.0",
|
"eslint-plugin-mocha": "8.1.0",
|
||||||
"eslint-plugin-mocha-cleanup": "1.9.1",
|
"eslint-plugin-mocha-cleanup": "1.9.1",
|
||||||
@@ -172,11 +165,11 @@
|
|||||||
"eslint-plugin-promise": "^5.1.0",
|
"eslint-plugin-promise": "^5.1.0",
|
||||||
"eslint-plugin-sonarjs": "^0.7.0",
|
"eslint-plugin-sonarjs": "^0.7.0",
|
||||||
"eslint-plugin-standard": "4.1.0",
|
"eslint-plugin-standard": "4.1.0",
|
||||||
"eslint-plugin-unicorn": "31.0.0",
|
"eslint-plugin-unicorn": "32.0.1",
|
||||||
"imageoptim-cli": "3.0.2",
|
"imageoptim-cli": "3.0.2",
|
||||||
"jamilih": "0.54.0",
|
"jamilih": "0.54.0",
|
||||||
"jsdoc": "3.6.6",
|
"jsdoc": "3.6.6",
|
||||||
"mocha": "8.3.2",
|
"mocha": "8.4.0",
|
||||||
"mocha-badge-generator": "0.9.0",
|
"mocha-badge-generator": "0.9.0",
|
||||||
"mochawesome": "6.2.2",
|
"mochawesome": "6.2.2",
|
||||||
"mochawesome-merge": "4.2.0",
|
"mochawesome-merge": "4.2.0",
|
||||||
@@ -192,7 +185,7 @@
|
|||||||
"remark-lint-ordered-list-marker-value": "2.0.1",
|
"remark-lint-ordered-list-marker-value": "2.0.1",
|
||||||
"requirejs": "2.3.6",
|
"requirejs": "2.3.6",
|
||||||
"rimraf": "3.0.2",
|
"rimraf": "3.0.2",
|
||||||
"rollup": "2.45.2",
|
"rollup": "2.47.0",
|
||||||
"rollup-plugin-copy": "3.4.0",
|
"rollup-plugin-copy": "3.4.0",
|
||||||
"rollup-plugin-filesize": "9.1.1",
|
"rollup-plugin-filesize": "9.1.1",
|
||||||
"rollup-plugin-node-polyfills": "0.2.1",
|
"rollup-plugin-node-polyfills": "0.2.1",
|
||||||
@@ -200,8 +193,8 @@
|
|||||||
"rollup-plugin-re": "1.0.7",
|
"rollup-plugin-re": "1.0.7",
|
||||||
"rollup-plugin-terser": "7.0.2",
|
"rollup-plugin-terser": "7.0.2",
|
||||||
"stackblur-canvas": "2.5.0",
|
"stackblur-canvas": "2.5.0",
|
||||||
"start-server-and-test": "^1.12.1",
|
"start-server-and-test": "^1.12.2",
|
||||||
"systemjs": "6.8.3",
|
"systemjs": "6.9.0",
|
||||||
"typescript": "4.2.4",
|
"typescript": "4.2.4",
|
||||||
"underscore": "1.13.1"
|
"underscore": "1.13.1"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,8 @@ const getDirectories = (source) => {
|
|||||||
// capture the list of files to build for extensions and ext-locales
|
// capture the list of files to build for extensions and ext-locales
|
||||||
const extensionDirs = getDirectories('src/editor/extensions');
|
const extensionDirs = getDirectories('src/editor/extensions');
|
||||||
|
|
||||||
const dest = ['dist/editor', 'dist/editor/system'];
|
/** @todo should we support systemjs? */
|
||||||
|
const dest = [ 'dist/editor' ];
|
||||||
|
|
||||||
// remove existing distribution
|
// remove existing distribution
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
@@ -50,15 +51,16 @@ const config = [{
|
|||||||
sourcemap: true,
|
sourcemap: true,
|
||||||
file: 'dist/editor/xdomain-index.js',
|
file: 'dist/editor/xdomain-index.js',
|
||||||
intro: 'const XDOMAIN = true;'
|
intro: 'const XDOMAIN = true;'
|
||||||
},
|
}
|
||||||
|
/*
|
||||||
{
|
{
|
||||||
format: 'system',
|
format: 'system',
|
||||||
dir: 'dist/editor/system',
|
dir: 'dist/editor/system',
|
||||||
inlineDynamicImports: true
|
inlineDynamicImports: true
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
],
|
],
|
||||||
plugins: [
|
plugins: [
|
||||||
// progress(),
|
|
||||||
copy({
|
copy({
|
||||||
targets: [
|
targets: [
|
||||||
{
|
{
|
||||||
@@ -72,6 +74,7 @@ const config = [{
|
|||||||
transform: (contents) => contents.toString()
|
transform: (contents) => contents.toString()
|
||||||
.replace('<script type="module" src="index.js">', '<script type="module" src="xdomain-index.js">')
|
.replace('<script type="module" src="index.js">', '<script type="module" src="xdomain-index.js">')
|
||||||
},
|
},
|
||||||
|
/*
|
||||||
{
|
{
|
||||||
src: 'src/editor/index.html',
|
src: 'src/editor/index.html',
|
||||||
dest: ['dist/editor/system'],
|
dest: ['dist/editor/system'],
|
||||||
@@ -91,14 +94,13 @@ const config = [{
|
|||||||
src: ['node_modules/systemjs/dist/s.min.js', 'node_modules/systemjs/dist/s.min.js.map'],
|
src: ['node_modules/systemjs/dist/s.min.js', 'node_modules/systemjs/dist/s.min.js.map'],
|
||||||
dest: 'dist/editor/system'
|
dest: 'dist/editor/system'
|
||||||
},
|
},
|
||||||
|
*/
|
||||||
{ src: 'src/editor/images', dest },
|
{ src: 'src/editor/images', dest },
|
||||||
{ src: 'src/editor/extensions/ext-shapes/shapelib', dest: dest.map((d) => `${d}/extensions/ext-shapes`) },
|
{ src: 'src/editor/extensions/ext-shapes/shapelib', dest: dest.map((d) => `${d}/extensions/ext-shapes`) },
|
||||||
{src: 'src/editor/jgraduate', dest},
|
|
||||||
{src: 'src/editor/spinbtn', dest},
|
|
||||||
{ src: 'src/editor/embedapi.html', dest },
|
{ src: 'src/editor/embedapi.html', dest },
|
||||||
{ src: 'src/editor/embedapi.js', dest },
|
{ src: 'src/editor/embedapi.js', dest },
|
||||||
{ src: 'src/editor/browser-not-supported.html', dest },
|
{ src: 'src/editor/browser-not-supported.html', dest },
|
||||||
{src: 'src/editor/redirect-on-lacking-support.js', dest},
|
{ src: 'src/editor/browser-not-supported.js', dest },
|
||||||
{ src: 'src/editor/svgedit.css', dest }
|
{ src: 'src/editor/svgedit.css', dest }
|
||||||
]
|
]
|
||||||
}),
|
}),
|
||||||
@@ -127,15 +129,17 @@ extensionDirs.forEach((extensionDir) => {
|
|||||||
dir: `dist/editor/extensions/${extensionName}`,
|
dir: `dist/editor/extensions/${extensionName}`,
|
||||||
inlineDynamicImports: true,
|
inlineDynamicImports: true,
|
||||||
sourcemap: true
|
sourcemap: true
|
||||||
},
|
}
|
||||||
|
/*
|
||||||
|
,
|
||||||
{
|
{
|
||||||
format: 'system',
|
format: 'system',
|
||||||
dir: `dist/editor/system/extensions/${extensionName}`,
|
dir: `dist/editor/system/extensions/${extensionName}`,
|
||||||
inlineDynamicImports: true
|
inlineDynamicImports: true
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
],
|
],
|
||||||
plugins: [
|
plugins: [
|
||||||
// progress(),
|
|
||||||
url({
|
url({
|
||||||
include: [ '**/*.svg', '**/*.png', '**/*.jpg', '**/*.gif', '**/*.xml' ],
|
include: [ '**/*.svg', '**/*.png', '**/*.jpg', '**/*.gif', '**/*.xml' ],
|
||||||
limit: 0,
|
limit: 0,
|
||||||
|
|||||||
@@ -170,11 +170,11 @@ export default class ConfigObj {
|
|||||||
// 'ext-markers',
|
// 'ext-markers',
|
||||||
'ext-overview_window',
|
'ext-overview_window',
|
||||||
'ext-panning',
|
'ext-panning',
|
||||||
'ext-polygon',
|
|
||||||
'ext-shapes',
|
'ext-shapes',
|
||||||
'ext-star',
|
'ext-polystar',
|
||||||
'ext-storage',
|
'ext-storage',
|
||||||
'ext-opensave'
|
'ext-opensave',
|
||||||
|
// 'ext-helloworld',
|
||||||
];
|
];
|
||||||
this.curConfig = {
|
this.curConfig = {
|
||||||
// We do not put on defaultConfig to simplify object copying
|
// We do not put on defaultConfig to simplify object copying
|
||||||
|
|||||||
@@ -40,14 +40,6 @@ class Editor extends EditorStartup {
|
|||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
/**
|
/**
|
||||||
* @type {Float}
|
|
||||||
*/
|
|
||||||
this.tool_scale = 1;
|
|
||||||
/**
|
|
||||||
* @type {Integer}
|
|
||||||
*/
|
|
||||||
this.exportWindowCt = 0;
|
|
||||||
/**
|
|
||||||
* @type {boolean}
|
* @type {boolean}
|
||||||
*/
|
*/
|
||||||
this.langChanged = false;
|
this.langChanged = false;
|
||||||
@@ -60,7 +52,6 @@ class Editor extends EditorStartup {
|
|||||||
* @type {"ignore"|"waiting"|"closed"}
|
* @type {"ignore"|"waiting"|"closed"}
|
||||||
*/
|
*/
|
||||||
this.storagePromptState = 'ignore';
|
this.storagePromptState = 'ignore';
|
||||||
|
|
||||||
this.svgCanvas = null;
|
this.svgCanvas = null;
|
||||||
this.isReady = false;
|
this.isReady = false;
|
||||||
this.customExportImage = false;
|
this.customExportImage = false;
|
||||||
@@ -77,42 +68,41 @@ class Editor extends EditorStartup {
|
|||||||
// eslint-disable-next-line max-len
|
// eslint-disable-next-line max-len
|
||||||
this.goodLangs = [ 'ar', 'cs', 'de', 'en', 'es', 'fa', 'fr', 'fy', 'hi', 'it', 'ja', 'nl', 'pl', 'pt-BR', 'ro', 'ru', 'sk', 'sl', 'zh-CN', 'zh-TW' ];
|
this.goodLangs = [ 'ar', 'cs', 'de', 'en', 'es', 'fa', 'fr', 'fy', 'hi', 'it', 'ja', 'nl', 'pl', 'pt-BR', 'ro', 'ru', 'sk', 'sl', 'zh-CN', 'zh-TW' ];
|
||||||
const modKey = (isMac() ? 'meta+' : 'ctrl+');
|
const modKey = (isMac() ? 'meta+' : 'ctrl+');
|
||||||
const curObj = this;
|
this.shortcuts = [
|
||||||
this.toolButtons = [
|
|
||||||
// Shortcuts not associated with buttons
|
// Shortcuts not associated with buttons
|
||||||
{ key: 'ctrl+arrowleft', fn() { curObj.rotateSelected(0, 1); } },
|
{ key: 'ctrl+arrowleft', fn: () => { this.rotateSelected(0, 1); } },
|
||||||
{ key: 'ctrl+arrowright', fn() { curObj.rotateSelected(1, 1); } },
|
{ key: 'ctrl+arrowright', fn: () => { this.rotateSelected(1, 1); } },
|
||||||
{ key: 'ctrl+shift+arrowleft', fn() { curObj.rotateSelected(0, 5); } },
|
{ key: 'ctrl+shift+arrowleft', fn: () => { this.rotateSelected(0, 5); } },
|
||||||
{ key: 'ctrl+shift+arrowright', fn() { curObj.rotateSelected(1, 5); } },
|
{ key: 'ctrl+shift+arrowright', fn: () => { this.rotateSelected(1, 5); } },
|
||||||
{ key: 'shift+o', fn() { curObj.svgCanvas.cycleElement(0); } },
|
{ key: 'shift+o', fn: () => { this.svgCanvas.cycleElement(0); } },
|
||||||
{ key: 'shift+p', fn() { curObj.svgCanvas.cycleElement(1); } },
|
{ key: 'shift+p', fn: () => { this.svgCanvas.cycleElement(1); } },
|
||||||
{ key: 'tab', fn() { curObj.svgCanvas.cycleElement(0); } },
|
{ key: 'tab', fn: () => { this.svgCanvas.cycleElement(0); } },
|
||||||
{ key: 'shift+tab', fn() { curObj.svgCanvas.cycleElement(1); } },
|
{ key: 'shift+tab', fn: () => { this.svgCanvas.cycleElement(1); } },
|
||||||
{ key: [modKey + 'arrowup', true], fn() { curObj.zoomImage(2); } },
|
{ key: [ modKey + 'arrowup', true ], fn: () => { this.zoomImage(2); } },
|
||||||
{ key: [modKey + 'arrowdown', true], fn() { curObj.zoomImage(0.5); } },
|
{ key: [ modKey + 'arrowdown', true ], fn: () => { this.zoomImage(0.5); } },
|
||||||
{ key: [modKey + ']', true], fn() { curObj.moveUpDownSelected('Up'); } },
|
{ key: [ modKey + ']', true ], fn: () => { this.moveUpDownSelected('Up'); } },
|
||||||
{ key: [modKey + '[', true], fn() { curObj.moveUpDownSelected('Down'); } },
|
{ key: [ modKey + '[', true ], fn: () => { this.moveUpDownSelected('Down'); } },
|
||||||
{ key: ['arrowup', true], fn() { curObj.moveSelected(0, -1); } },
|
{ key: [ 'arrowup', true ], fn: () => { this.moveSelected(0, -1); } },
|
||||||
{ key: ['arrowdown', true], fn() { curObj.moveSelected(0, 1); } },
|
{ key: [ 'arrowdown', true ], fn: () => { this.moveSelected(0, 1); } },
|
||||||
{ key: ['arrowleft', true], fn() { curObj.moveSelected(-1, 0); } },
|
{ key: [ 'arrowleft', true ], fn: () => { this.moveSelected(-1, 0); } },
|
||||||
{ key: ['arrowright', true], fn() { curObj.moveSelected(1, 0); } },
|
{ key: [ 'arrowright', true ], fn: () => { this.moveSelected(1, 0); } },
|
||||||
{ key: 'shift+arrowup', fn() { curObj.moveSelected(0, -10); } },
|
{ key: 'shift+arrowup', fn: () => { this.moveSelected(0, -10); } },
|
||||||
{ key: 'shift+arrowdown', fn() { curObj.moveSelected(0, 10); } },
|
{ key: 'shift+arrowdown', fn: () => { this.moveSelected(0, 10); } },
|
||||||
{ key: 'shift+arrowleft', fn() { curObj.moveSelected(-10, 0); } },
|
{ key: 'shift+arrowleft', fn: () => { this.moveSelected(-10, 0); } },
|
||||||
{ key: 'shift+arrowright', fn() { curObj.moveSelected(10, 0); } },
|
{ key: 'shift+arrowright', fn: () => { this.moveSelected(10, 0); } },
|
||||||
{ key: ['alt+arrowup', true], fn() { curObj.svgCanvas.cloneSelectedElements(0, -1); } },
|
{ key: [ 'alt+arrowup', true ], fn: () => { this.svgCanvas.cloneSelectedElements(0, -1); } },
|
||||||
{ key: ['alt+arrowdown', true], fn() { curObj.svgCanvas.cloneSelectedElements(0, 1); } },
|
{ key: [ 'alt+arrowdown', true ], fn: () => { this.svgCanvas.cloneSelectedElements(0, 1); } },
|
||||||
{ key: ['alt+arrowleft', true], fn() { curObj.svgCanvas.cloneSelectedElements(-1, 0); } },
|
{ key: [ 'alt+arrowleft', true ], fn: () => { this.svgCanvas.cloneSelectedElements(-1, 0); } },
|
||||||
{ key: ['alt+arrowright', true], fn() { curObj.svgCanvas.cloneSelectedElements(1, 0); } },
|
{ key: [ 'alt+arrowright', true ], fn: () => { this.svgCanvas.cloneSelectedElements(1, 0); } },
|
||||||
{ key: ['alt+shift+arrowup', true], fn() { curObj.svgCanvas.cloneSelectedElements(0, -10); } },
|
{ key: [ 'alt+shift+arrowup', true ], fn: () => { this.svgCanvas.cloneSelectedElements(0, -10); } },
|
||||||
{ key: ['alt+shift+arrowdown', true], fn() { curObj.svgCanvas.cloneSelectedElements(0, 10); } },
|
{ key: [ 'alt+shift+arrowdown', true ], fn: () => { this.svgCanvas.cloneSelectedElements(0, 10); } },
|
||||||
{ key: ['alt+shift+arrowleft', true], fn() { curObj.svgCanvas.cloneSelectedElements(-10, 0); } },
|
{ key: [ 'alt+shift+arrowleft', true ], fn: () => { this.svgCanvas.cloneSelectedElements(-10, 0); } },
|
||||||
{ key: ['alt+shift+arrowright', true], fn() { curObj.svgCanvas.cloneSelectedElements(10, 0); } },
|
{ key: [ 'alt+shift+arrowright', true ], fn: () => { this.svgCanvas.cloneSelectedElements(10, 0); } },
|
||||||
{ key: 'a', fn() { curObj.svgCanvas.selectAllInCurrentLayer(); } },
|
{ key: 'a', fn: () => { this.svgCanvas.selectAllInCurrentLayer(); } },
|
||||||
{ key: modKey + 'a', fn() { curObj.svgCanvas.selectAllInCurrentLayer(); } },
|
{ key: modKey + 'a', fn: () => { this.svgCanvas.selectAllInCurrentLayer(); } },
|
||||||
{ key: modKey + 'x', fn() { curObj.cutSelected(); } },
|
{ key: modKey + 'x', fn: () => { this.cutSelected(); } },
|
||||||
{ key: modKey + 'c', fn() { curObj.copySelected(); } },
|
{ key: modKey + 'c', fn: () => { this.copySelected(); } },
|
||||||
{ key: modKey + 'v', fn() { curObj.pasteInCenter(); } }
|
{ key: modKey + 'v', fn: () => { this.pasteInCenter(); } }
|
||||||
];
|
];
|
||||||
this.leftPanel = new LeftPanel(this);
|
this.leftPanel = new LeftPanel(this);
|
||||||
this.bottomPanel = new BottomPanel(this);
|
this.bottomPanel = new BottomPanel(this);
|
||||||
@@ -228,18 +218,18 @@ class Editor extends EditorStartup {
|
|||||||
setAll() {
|
setAll() {
|
||||||
const keyHandler = {}; // will contain the action for each pressed key
|
const keyHandler = {}; // will contain the action for each pressed key
|
||||||
|
|
||||||
this.toolButtons.forEach((opts) => {
|
this.shortcuts.forEach((shortcut) => {
|
||||||
// Bind function to shortcut key
|
// Bind function to shortcut key
|
||||||
if (opts.key) {
|
if (shortcut.key) {
|
||||||
// Set shortcut based on options
|
// Set shortcut based on options
|
||||||
let keyval = opts.key;
|
let keyval = shortcut.key;
|
||||||
let pd = false;
|
let pd = false;
|
||||||
if (Array.isArray(opts.key)) {
|
if (Array.isArray(shortcut.key)) {
|
||||||
keyval = opts.key[0];
|
keyval = shortcut.key[0];
|
||||||
if (opts.key.length > 1) { pd = opts.key[1]; }
|
if (shortcut.key.length > 1) { pd = shortcut.key[1]; }
|
||||||
}
|
}
|
||||||
keyval = String(keyval);
|
keyval = String(keyval);
|
||||||
const { fn } = opts;
|
const { fn } = shortcut;
|
||||||
keyval.split('/').forEach((key) => { keyHandler[key] = { fn, pd }; });
|
keyval.split('/').forEach((key) => { keyHandler[key] = { fn, pd }; });
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -304,7 +294,7 @@ class Editor extends EditorStartup {
|
|||||||
'5/Shift+5': 'tools_ellipse'
|
'5/Shift+5': 'tools_ellipse'
|
||||||
};
|
};
|
||||||
Object.entries(keyAssocs).forEach(([ keyval, sel ]) => {
|
Object.entries(keyAssocs).forEach(([ keyval, sel ]) => {
|
||||||
const parentsElements = this.getParents($id(sel), $id('main_menu'))
|
const parentsElements = this.getParents($id(sel), $id('main_menu'));
|
||||||
const menu = (parentsElements.length);
|
const menu = (parentsElements.length);
|
||||||
|
|
||||||
$qa(sel).forEach((element) => {
|
$qa(sel).forEach((element) => {
|
||||||
@@ -318,7 +308,7 @@ class Editor extends EditorStartup {
|
|||||||
mod = modBits[0] + '+';
|
mod = modBits[0] + '+';
|
||||||
key = modBits[1];
|
key = modBits[1];
|
||||||
}
|
}
|
||||||
keyStr += (i ? '/' : '') + mod + (this.uiStrings['key_' + key] || key);
|
keyStr += (i ? '/' : '') + mod + (this.i18next.t('key_' + key) || key);
|
||||||
});
|
});
|
||||||
if (menu) {
|
if (menu) {
|
||||||
this.lastChild.textContent = t + ' [' + keyStr + ']';
|
this.lastChild.textContent = t + ' [' + keyStr + ']';
|
||||||
@@ -333,20 +323,11 @@ class Editor extends EditorStartup {
|
|||||||
* @returns {module:SVGthis.ToolButton}
|
* @returns {module:SVGthis.ToolButton}
|
||||||
*/
|
*/
|
||||||
getButtonData(sel) {
|
getButtonData(sel) {
|
||||||
return Object.values(this.toolButtons).find((btn) => {
|
return Object.values(this.shortcuts).find((btn) => {
|
||||||
return btn.sel === sel;
|
return btn.sel === sel;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Expose the `uiStrings`.
|
|
||||||
* @function module:SVGthis.canvas.getUIStrings
|
|
||||||
* @returns {module:SVGthis.uiStrings}
|
|
||||||
*/
|
|
||||||
getUIStrings() {
|
|
||||||
return this.uiStrings;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {boolean} editmode
|
* @param {boolean} editmode
|
||||||
* @param {module:svgcanvas.SvgCanvas#event:selected} elems
|
* @param {module:svgcanvas.SvgCanvas#event:selected} elems
|
||||||
@@ -359,9 +340,9 @@ class Editor extends EditorStartup {
|
|||||||
const elements = document.getElementsByClassName("tool_button_current");
|
const elements = document.getElementsByClassName("tool_button_current");
|
||||||
Array.from(elements).forEach(function (element) {
|
Array.from(elements).forEach(function (element) {
|
||||||
element.classList.add('tool_button_current');
|
element.classList.add('tool_button_current');
|
||||||
element.classList.remove('tool_button')
|
element.classList.remove('tool_button');
|
||||||
});
|
});
|
||||||
$id('tool_select').classList.add('tool_button_current')
|
$id('tool_select').classList.add('tool_button_current');
|
||||||
$id('tool_select').classList.remove('tool_button');
|
$id('tool_select').classList.remove('tool_button');
|
||||||
this.multiselected = false;
|
this.multiselected = false;
|
||||||
if (elems.length) {
|
if (elems.length) {
|
||||||
@@ -386,7 +367,7 @@ class Editor extends EditorStartup {
|
|||||||
this.exportWindow = window.open(blankPageObjectURL || '', exportWindowName); // A hack to get the window via JSON-able name without opening a new one
|
this.exportWindow = window.open(blankPageObjectURL || '', exportWindowName); // A hack to get the window via JSON-able name without opening a new one
|
||||||
|
|
||||||
if (!this.exportWindow || this.exportWindow.closed) {
|
if (!this.exportWindow || this.exportWindow.closed) {
|
||||||
seAlert(this.uiStrings.notification.popupWindowBlocked);
|
seAlert(this.i18next.t('notification.popupWindowBlocked'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -398,7 +379,7 @@ class Editor extends EditorStartup {
|
|||||||
// Check if there are issues
|
// Check if there are issues
|
||||||
if (issues.length) {
|
if (issues.length) {
|
||||||
const pre = '\n \u2022 ';
|
const pre = '\n \u2022 ';
|
||||||
note += ('\n\n' + this.uiStrings.notification.noteTheseIssues + pre + issues.join(pre));
|
note += ('\n\n' + this.i18next.t('notification..noteTheseIssues') + pre + issues.join(pre));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note that this will also prevent the notice even though new issues may appear later.
|
// Note that this will also prevent the notice even though new issues may appear later.
|
||||||
@@ -784,7 +765,7 @@ class Editor extends EditorStartup {
|
|||||||
const icon = (typeof iconId === 'string') ? img : iconId.cloneNode(true);
|
const icon = (typeof iconId === 'string') ? img : iconId.cloneNode(true);
|
||||||
if (!icon) {
|
if (!icon) {
|
||||||
// Todo: Investigate why this still occurs in some cases
|
// Todo: Investigate why this still occurs in some cases
|
||||||
console.log('NOTE: Icon image missing: ' + iconId);
|
console.warn('NOTE: Icon image missing: ' + iconId);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// empty()
|
// empty()
|
||||||
@@ -950,7 +931,7 @@ class Editor extends EditorStartup {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (!this.svgCanvas.setSvgString(e.detail.value)) {
|
if (!this.svgCanvas.setSvgString(e.detail.value)) {
|
||||||
const ok = await seConfirm(this.uiStrings.notification.QerrorsRevertToSource);
|
const ok = await seConfirm(this.i18next.t('notification.QerrorsRevertToSource'));
|
||||||
if (ok === false || ok === 'Cancel') {
|
if (ok === false || ok === 'Cancel') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -979,7 +960,7 @@ class Editor extends EditorStartup {
|
|||||||
if (editingsource) {
|
if (editingsource) {
|
||||||
const origSource = this.svgCanvas.getSvgString();
|
const origSource = this.svgCanvas.getSvgString();
|
||||||
if (origSource !== e.detail.value) {
|
if (origSource !== e.detail.value) {
|
||||||
const ok = seConfirm(this.uiStrings.notification.QignoreSourceChanges);
|
const ok = seConfirm(this.i18next.t('notification.QignoreSourceChanges'));
|
||||||
if (ok) {
|
if (ok) {
|
||||||
this.hideSourceEditor();
|
this.hideSourceEditor();
|
||||||
}
|
}
|
||||||
@@ -1009,7 +990,7 @@ class Editor extends EditorStartup {
|
|||||||
if (this.svgCanvas.undoMgr.getUndoStackSize() === 0) {
|
if (this.svgCanvas.undoMgr.getUndoStackSize() === 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return await seConfirm(this.uiStrings.notification.QwantToOpen);
|
return await seConfirm(this.i18next.t('notification.QwantToOpen'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1061,13 +1042,12 @@ class Editor extends EditorStartup {
|
|||||||
const $editDialog = document.getElementById('se-edit-prefs');
|
const $editDialog = document.getElementById('se-edit-prefs');
|
||||||
$editDialog.setAttribute('lang', lang);
|
$editDialog.setAttribute('lang', lang);
|
||||||
const oldLayerName = ($id('#layerlist')) ? $id('#layerlist').querySelector('tr.layersel td.layername').textContent : "";
|
const oldLayerName = ($id('#layerlist')) ? $id('#layerlist').querySelector('tr.layersel td.layername').textContent : "";
|
||||||
const renameLayer = (oldLayerName === this.uiStrings.common.layer + ' 1');
|
const renameLayer = (oldLayerName === this.i18next.t('notification.common.layer') + ' 1');
|
||||||
|
|
||||||
// this.svgCanvas.setUiStrings(allStrings);
|
|
||||||
this.setTitles();
|
this.setTitles();
|
||||||
|
|
||||||
if (renameLayer) {
|
if (renameLayer) {
|
||||||
this.svgCanvas.renameCurrentLayer(this.uiStrings.common.layer + ' 1');
|
this.svgCanvas.renameCurrentLayer(this.i18next.t('notification.common.layer') + ' 1');
|
||||||
this.layersPanel.populateLayers();
|
this.layersPanel.populateLayers();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1160,7 +1140,7 @@ class Editor extends EditorStartup {
|
|||||||
dataType: 'text',
|
dataType: 'text',
|
||||||
cache: Boolean(cache),
|
cache: Boolean(cache),
|
||||||
beforeSend() {
|
beforeSend() {
|
||||||
$.process_cancel(this.uiStrings.notification.loadingImage);
|
$.process_cancel(this.i18next.t('notification.loadingImage'));
|
||||||
},
|
},
|
||||||
success(str) {
|
success(str) {
|
||||||
this.loadSvgString(str, { noAlert });
|
this.loadSvgString(str, { noAlert });
|
||||||
@@ -1174,7 +1154,7 @@ class Editor extends EditorStartup {
|
|||||||
reject(new Error('URLLoadFail'));
|
reject(new Error('URLLoadFail'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
seAlert(this.uiStrings.notification.URLLoadFail + ': \n' + err);
|
seAlert(this.i18next.t('notification.URLLoadFail') + ': \n' + err);
|
||||||
resolve();
|
resolve();
|
||||||
},
|
},
|
||||||
complete() {
|
complete() {
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ class EditorStartup {
|
|||||||
constructor () {
|
constructor () {
|
||||||
this.extensionsAdded = false;
|
this.extensionsAdded = false;
|
||||||
this.messageQueue = [];
|
this.messageQueue = [];
|
||||||
this.$svgEditor = $id('svg_editor')
|
this.$svgEditor = $id('svg_editor');
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Auto-run after a Promise microtask.
|
* Auto-run after a Promise microtask.
|
||||||
@@ -61,6 +61,10 @@ class EditorStartup {
|
|||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
async init () {
|
async init () {
|
||||||
|
if ('localStorage' in window) { // && onWeb removed so Webkit works locally
|
||||||
|
this.storage = window.localStorage;
|
||||||
|
}
|
||||||
|
this.configObj.load();
|
||||||
const self = this;
|
const self = this;
|
||||||
const { i18next } = await putLocale(this.configObj.pref('lang'), this.goodLangs);
|
const { i18next } = await putLocale(this.configObj.pref('lang'), this.goodLangs);
|
||||||
this.i18next = i18next;
|
this.i18next = i18next;
|
||||||
@@ -97,12 +101,6 @@ class EditorStartup {
|
|||||||
console.error(err);
|
console.error(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('localStorage' in window) { // && onWeb removed so Webkit works locally
|
|
||||||
this.storage = window.localStorage;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.configObj.load();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @name module:SVGthis.canvas
|
* @name module:SVGthis.canvas
|
||||||
* @type {module:svgcanvas.SvgCanvas}
|
* @type {module:svgcanvas.SvgCanvas}
|
||||||
@@ -136,7 +134,7 @@ class EditorStartup {
|
|||||||
this.selectedElement = null;
|
this.selectedElement = null;
|
||||||
this.multiselected = false;
|
this.multiselected = false;
|
||||||
|
|
||||||
const aLinks = $id('cur_context_panel').querySelectorAll('a')
|
const aLinks = $id('cur_context_panel').querySelectorAll('a');
|
||||||
|
|
||||||
for (const aLink of aLinks) {
|
for (const aLink of aLinks) {
|
||||||
aLink.addEventListener('click', (evt) => {
|
aLink.addEventListener('click', (evt) => {
|
||||||
@@ -165,7 +163,7 @@ class EditorStartup {
|
|||||||
this.exportWindow = window.open('', this.exportWindowName); // A hack to get the window via JSON-able name without opening a new one
|
this.exportWindow = window.open('', this.exportWindowName); // A hack to get the window via JSON-able name without opening a new one
|
||||||
}
|
}
|
||||||
if (!this.exportWindow || this.exportWindow.closed) {
|
if (!this.exportWindow || this.exportWindow.closed) {
|
||||||
seAlert(this.uiStrings.notification.popupWindowBlocked);
|
seAlert(this.i18next.t('notification.popupWindowBlocked'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.exportWindow.location.href = data.output;
|
this.exportWindow.location.href = data.output;
|
||||||
@@ -216,7 +214,7 @@ class EditorStartup {
|
|||||||
let promptMoveLayerOnce = false;
|
let promptMoveLayerOnce = false;
|
||||||
$id('selLayerNames').addEventListener('change', function(evt) {
|
$id('selLayerNames').addEventListener('change', function(evt) {
|
||||||
const destLayer = evt.currentTarget.options[evt.currentTarget.selectedIndex].value;
|
const destLayer = evt.currentTarget.options[evt.currentTarget.selectedIndex].value;
|
||||||
const confirmStr = self.uiStrings.notification.QmoveElemsToLayer.replace('%s', destLayer);
|
const confirmStr = self.i18next.t('notification.QmoveElemsToLayer').replace('%s', destLayer);
|
||||||
/**
|
/**
|
||||||
* @param {boolean} ok
|
* @param {boolean} ok
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
@@ -426,16 +424,16 @@ class EditorStartup {
|
|||||||
Array.from(elements).forEach(function(element) {
|
Array.from(elements).forEach(function(element) {
|
||||||
element.addEventListener('mousedown', function(event) {
|
element.addEventListener('mousedown', function(event) {
|
||||||
if (!event.currentTarget.classList.contains('disabled')) {
|
if (!event.currentTarget.classList.contains('disabled')) {
|
||||||
event.currentTarget.classList.add('push_button_pressed')
|
event.currentTarget.classList.add('push_button_pressed');
|
||||||
event.currentTarget.classList.remove('push_button');
|
event.currentTarget.classList.remove('push_button');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
element.addEventListener('mouseout', function(event) {
|
element.addEventListener('mouseout', function(event) {
|
||||||
event.currentTarget.classList.add('push_button')
|
event.currentTarget.classList.add('push_button');
|
||||||
event.currentTarget.classList.remove('push_button_pressed');
|
event.currentTarget.classList.remove('push_button_pressed');
|
||||||
});
|
});
|
||||||
element.addEventListener('mouseup', function(event) {
|
element.addEventListener('mouseup', function(event) {
|
||||||
event.currentTarget.classList.add('push_button')
|
event.currentTarget.classList.add('push_button');
|
||||||
event.currentTarget.classList.remove('push_button_pressed');
|
event.currentTarget.classList.remove('push_button_pressed');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -577,8 +575,8 @@ class EditorStartup {
|
|||||||
// showSaveWarning is set to 'false' when the page is saved.
|
// showSaveWarning is set to 'false' when the page is saved.
|
||||||
if (!this.configObj.curConfig.no_save_warning && this.showSaveWarning) {
|
if (!this.configObj.curConfig.no_save_warning && this.showSaveWarning) {
|
||||||
// Browser already asks question about closing the page
|
// Browser already asks question about closing the page
|
||||||
e.returnValue = this.uiStrings.notification.unsavedChanges; // Firefox needs this when beforeunload set by addEventListener (even though message is not used)
|
e.returnValue = this.i18next.t('notification.unsavedChanges'); // Firefox needs this when beforeunload set by addEventListener (even though message is not used)
|
||||||
return this.uiStrings.notification.unsavedChanges;
|
return this.i18next.t('notification.unsavedChanges');
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
@@ -594,7 +592,7 @@ class EditorStartup {
|
|||||||
*/
|
*/
|
||||||
const editorObj = this;
|
const editorObj = this;
|
||||||
const importImage = function (e) {
|
const importImage = function (e) {
|
||||||
document.getElementById('se-prompt-dialog').title = editorObj.uiStrings.notification.loadingImage;
|
document.getElementById('se-prompt-dialog').title = editorObj.i18next.t('notification.loadingImage');
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const file = (e.type === 'drop') ? e.dataTransfer.files[0] : this.files[0];
|
const file = (e.type === 'drop') ? e.dataTransfer.files[0] : this.files[0];
|
||||||
@@ -791,7 +789,6 @@ class EditorStartup {
|
|||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
messageListener ({ data, origin }) {
|
messageListener ({ data, origin }) {
|
||||||
// console.log('data, origin, extensionsAdded', data, origin, extensionsAdded);
|
|
||||||
const messageObj = { data, origin };
|
const messageObj = { data, origin };
|
||||||
if (!this.extensionsAdded) {
|
if (!this.extensionsAdded) {
|
||||||
this.messageQueue.push(messageObj);
|
this.messageQueue.push(messageObj);
|
||||||
|
|||||||
@@ -15,6 +15,10 @@ class MainMenu {
|
|||||||
*/
|
*/
|
||||||
constructor(editor) {
|
constructor(editor) {
|
||||||
this.editor = editor;
|
this.editor = editor;
|
||||||
|
/**
|
||||||
|
* @type {Integer}
|
||||||
|
*/
|
||||||
|
this.exportWindowCt = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -23,7 +27,7 @@ class MainMenu {
|
|||||||
*/
|
*/
|
||||||
async clickClear() {
|
async clickClear() {
|
||||||
const [ x, y ] = this.editor.configObj.curConfig.dimensions;
|
const [ x, y ] = this.editor.configObj.curConfig.dimensions;
|
||||||
const ok = await seConfirm(this.editor.uiStrings.notification.QwantToClear);
|
const ok = await seConfirm(this.editor.i18next.t('notification.QwantToClear'));
|
||||||
if (ok === "Cancel") {
|
if (ok === "Cancel") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -68,15 +72,15 @@ class MainMenu {
|
|||||||
this.editor.svgCanvas.setDocumentTitle(title);
|
this.editor.svgCanvas.setDocumentTitle(title);
|
||||||
|
|
||||||
if (w !== "fit" && !isValidUnit("width", w)) {
|
if (w !== "fit" && !isValidUnit("width", w)) {
|
||||||
seAlert(this.editor.uiStrings.notification.invalidAttrValGiven);
|
seAlert(this.editor.i18next.t('notification.invalidAttrValGiven'));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (h !== "fit" && !isValidUnit("height", h)) {
|
if (h !== "fit" && !isValidUnit("height", h)) {
|
||||||
seAlert(this.editor.uiStrings.notification.invalidAttrValGiven);
|
seAlert(this.editor.i18next.t('notification.invalidAttrValGiven'));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!this.editor.svgCanvas.setResolution(w, h)) {
|
if (!this.editor.svgCanvas.setResolution(w, h)) {
|
||||||
seAlert(this.editor.uiStrings.notification.noContentToFitTo);
|
seAlert(this.editor.i18next.t('notification.noContentToFitTo'));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Set image save option
|
// Set image save option
|
||||||
@@ -107,11 +111,8 @@ class MainMenu {
|
|||||||
|
|
||||||
// set language
|
// set language
|
||||||
if (lang && lang !== this.editor.configObj.pref("lang")) {
|
if (lang && lang !== this.editor.configObj.pref("lang")) {
|
||||||
const { langParam, langData } = await this.editor.putLocale(
|
this.editor.configObj.pref("lang", lang);
|
||||||
lang,
|
seAlert('Changing the language needs reload');
|
||||||
this.editor.goodLangs
|
|
||||||
);
|
|
||||||
await this.editor.svgCanvassetLang(langParam, langData);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// set grid setting
|
// set grid setting
|
||||||
@@ -126,7 +127,7 @@ class MainMenu {
|
|||||||
this.editor.configObj.curConfig.baseUnit = baseunit;
|
this.editor.configObj.curConfig.baseUnit = baseunit;
|
||||||
this.editor.svgCanvas.setConfig(this.editor.configObj.curConfig);
|
this.editor.svgCanvas.setConfig(this.editor.configObj.curConfig);
|
||||||
this.editor.updateCanvas();
|
this.editor.updateCanvas();
|
||||||
this.editor.hidePreferences();
|
this.hidePreferences();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -161,7 +162,7 @@ class MainMenu {
|
|||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
const openExportWindow = () => {
|
const openExportWindow = () => {
|
||||||
const { loadingImage } = this.editor.uiStrings.notification;
|
const loadingImage = this.editor.i18next.t('notification.loadingImage');
|
||||||
if (this.editor.configObj.curConfig.exportWindowType === "new") {
|
if (this.editor.configObj.curConfig.exportWindowType === "new") {
|
||||||
this.editor.exportWindowCt++;
|
this.editor.exportWindowCt++;
|
||||||
}
|
}
|
||||||
@@ -301,7 +302,7 @@ class MainMenu {
|
|||||||
init() {
|
init() {
|
||||||
// add Top panel
|
// add Top panel
|
||||||
const template = document.createElement("template");
|
const template = document.createElement("template");
|
||||||
const {i18next} = this.editor
|
const { i18next } = this.editor;
|
||||||
// eslint-disable-next-line no-unsanitized/property
|
// eslint-disable-next-line no-unsanitized/property
|
||||||
template.innerHTML = `
|
template.innerHTML = `
|
||||||
<se-menu id="main_button" label="SVG-Edit" src="./images/logo.svg" alt="logo">
|
<se-menu id="main_button" label="SVG-Edit" src="./images/logo.svg" alt="logo">
|
||||||
@@ -330,7 +331,7 @@ class MainMenu {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
$id("tool_clear").addEventListener("click", this.clickClear.bind(this));
|
$id("tool_clear").addEventListener("click", this.clickClear.bind(this));
|
||||||
$id("tool_open").addEventListener("click", e => {
|
$id("tool_open").addEventListener("click", (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this.clickOpen();
|
this.clickOpen();
|
||||||
window.dispatchEvent(new CustomEvent("openImage"));
|
window.dispatchEvent(new CustomEvent("openImage"));
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ export function isObject(item) {
|
|||||||
export function mergeDeep(target, source) {
|
export function mergeDeep(target, source) {
|
||||||
let output = Object.assign({}, target);
|
let output = Object.assign({}, target);
|
||||||
if (isObject(target) && isObject(source)) {
|
if (isObject(target) && isObject(source)) {
|
||||||
Object.keys(source).forEach(key => {
|
Object.keys(source).forEach((key) => {
|
||||||
if (isObject(source[key])) {
|
if (isObject(source[key])) {
|
||||||
if (!(key in target))
|
if (!(key in target))
|
||||||
Object.assign(output, { [key]: source[key] });
|
Object.assign(output, { [key]: source[key] });
|
||||||
|
|||||||
@@ -1368,7 +1368,7 @@ export function jPickerMethod (elem, options, commitCallback, liveCallback, canc
|
|||||||
if (!that.querySelectorAll('div.jPicker.Container').length) {
|
if (!that.querySelectorAll('div.jPicker.Container').length) {
|
||||||
document.body.insertBefore(container, document.body.firstChild);
|
document.body.insertBefore(container, document.body.firstChild);
|
||||||
} else {
|
} else {
|
||||||
that.querySelector('div.jPicker.Container:last').insertAdjacentElement('afterend', container)
|
that.querySelector('div.jPicker.Container:last').insertAdjacentElement('afterend', container);
|
||||||
}
|
}
|
||||||
container.addEventListener('mousedown', function () {
|
container.addEventListener('mousedown', function () {
|
||||||
container.style.zIndex = 20;
|
container.style.zIndex = 20;
|
||||||
@@ -1520,7 +1520,7 @@ export function jPickerMethod (elem, options, commitCallback, liveCallback, canc
|
|||||||
iconAlpha = that.icon.querySelector('.Alpha');
|
iconAlpha = that.icon.querySelector('.Alpha');
|
||||||
setImg.call(that, iconAlpha, images.clientPath + 'bar-opacity.png');
|
setImg.call(that, iconAlpha, images.clientPath + 'bar-opacity.png');
|
||||||
setAlpha.call(that, iconAlpha, toFixedNumeric(((255 - (!isNullish(all) ? all.a : 0)) * 100) / 255, 4));
|
setAlpha.call(that, iconAlpha, toFixedNumeric(((255 - (!isNullish(all) ? all.a : 0)) * 100) / 255, 4));
|
||||||
iconImage = that.icon.querySelector('.Image')
|
iconImage = that.icon.querySelector('.Image');
|
||||||
iconImage.style.backgroundImage = 'url(\'' + images.clientPath + images.picker.file + '\')';
|
iconImage.style.backgroundImage = 'url(\'' + images.clientPath + images.picker.file + '\')';
|
||||||
iconImage.addEventListener('click', iconImageClicked);
|
iconImage.addEventListener('click', iconImageClicked);
|
||||||
if (win.bindToInput && win.updateInputColor) {
|
if (win.bindToInput && win.updateInputColor) {
|
||||||
|
|||||||
@@ -344,7 +344,7 @@ div.jGraduate_Swatch {
|
|||||||
}
|
}
|
||||||
div.jGraduate_GradContainer {
|
div.jGraduate_GradContainer {
|
||||||
border: 2px inset #EEE;
|
border: 2px inset #EEE;
|
||||||
background-image: url(../images/map-opacity.png);
|
background-image: url(./components/jgraduate/images/map-opacity.png);
|
||||||
background-position: 0px 0px;
|
background-position: 0px 0px;
|
||||||
height: 256px;
|
height: 256px;
|
||||||
width: 256px;
|
width: 256px;
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ class Dropdown extends ListComboBox {
|
|||||||
::slotted(*) {
|
::slotted(*) {
|
||||||
padding: 4px;
|
padding: 4px;
|
||||||
background: #E8E8E8;
|
background: #E8E8E8;
|
||||||
border: 1px solid #B0B0B0;
|
border: 1px solid #5a6162;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
[part~="popup"] {
|
[part~="popup"] {
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ template.innerHTML = `
|
|||||||
.menu-item {
|
.menu-item {
|
||||||
line-height: 1em;
|
line-height: 1em;
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
border: 1px solid #B0B0B0;
|
border: 1px solid #5a6162;
|
||||||
background: #E8E8E8;
|
background: #E8E8E8;
|
||||||
margin-bottom: -1px;
|
margin-bottom: -1px;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ template.innerHTML = `
|
|||||||
elix-number-spin-box {
|
elix-number-spin-box {
|
||||||
background-color: var(--input-color);
|
background-color: var(--input-color);
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
height: 20px !important;
|
height: 20px;
|
||||||
margin-top: 1px;
|
margin-top: 1px;
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,6 @@ export const add = function (menuItem) {
|
|||||||
throw new Error('Cannot add extension "' + menuItem.id + '", an extension by that name already exists"');
|
throw new Error('Cannot add extension "' + menuItem.id + '", an extension by that name already exists"');
|
||||||
}
|
}
|
||||||
// Register menuItem action, see below for deferred menu dom injection
|
// Register menuItem action, see below for deferred menu dom injection
|
||||||
console.log('Registered contextmenu item: {id:' + menuItem.id + ', label:' + menuItem.label + '}');
|
|
||||||
contextMenuExtensions[menuItem.id] = menuItem;
|
contextMenuExtensions[menuItem.id] = menuItem;
|
||||||
// TODO: Need to consider how to handle custom enable/disable behavior
|
// TODO: Need to consider how to handle custom enable/disable behavior
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ export default class SePlainAlertDialog extends PlainAlertDialog {
|
|||||||
background: #DDD;
|
background: #DDD;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
border: 1px solid #B0B0B0;
|
border: 1px solid #5a6162;
|
||||||
padding: 1em;
|
padding: 1em;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
-moz-border-radius: 5px;
|
-moz-border-radius: 5px;
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import 'elix/define/Dialog.js';
|
|
||||||
|
|
||||||
const template = document.createElement('template');
|
const template = document.createElement('template');
|
||||||
template.innerHTML = `
|
template.innerHTML = `
|
||||||
@@ -71,7 +70,8 @@ template.innerHTML = `
|
|||||||
}
|
}
|
||||||
#svg_prefs #svg_prefs_container {
|
#svg_prefs #svg_prefs_container {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
background-color: #B0B0B0;
|
background-color: #5a6162;
|
||||||
|
color: #c5c5c5;
|
||||||
border: 1px outset #777;
|
border: 1px outset #777;
|
||||||
opacity: 1.0;
|
opacity: 1.0;
|
||||||
font-family: Verdana, Helvetica, sans-serif;
|
font-family: Verdana, Helvetica, sans-serif;
|
||||||
@@ -84,6 +84,17 @@ template.innerHTML = `
|
|||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#tool_prefs_save {
|
||||||
|
width: 30%;
|
||||||
|
background-color: #c79605;
|
||||||
|
margin-left: 20%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#tool_prefs_cancel {
|
||||||
|
width: 30%;
|
||||||
|
background-color: #c8c8c8;
|
||||||
|
}
|
||||||
|
|
||||||
#svg_prefs #svg_docprops_prefs {
|
#svg_prefs #svg_docprops_prefs {
|
||||||
float: left;
|
float: left;
|
||||||
width: 221px;
|
width: 221px;
|
||||||
@@ -138,11 +149,9 @@ template.innerHTML = `
|
|||||||
<div id="svg_prefs_container">
|
<div id="svg_prefs_container">
|
||||||
<div id="tool_prefs_back" class="toolbar_button">
|
<div id="tool_prefs_back" class="toolbar_button">
|
||||||
<button id="tool_prefs_save">
|
<button id="tool_prefs_save">
|
||||||
<img class="svg_icon" src="./images/ok.svg" alt="icon" width="16" height="16" />
|
|
||||||
OK
|
OK
|
||||||
</button>
|
</button>
|
||||||
<button id="tool_prefs_cancel">
|
<button id="tool_prefs_cancel">
|
||||||
<img class="svg_icon" src="./images/cancel.svg" alt="icon" width="16" height="16" />
|
|
||||||
Cancel
|
Cancel
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import 'elix/define/Dialog.js';
|
|
||||||
import './se-elix/define/NumberSpinBox.js';
|
import './se-elix/define/NumberSpinBox.js';
|
||||||
|
|
||||||
const template = document.createElement('template');
|
const template = document.createElement('template');
|
||||||
@@ -7,10 +6,10 @@ template.innerHTML = `
|
|||||||
|
|
||||||
#dialog_content {
|
#dialog_content {
|
||||||
margin: 10px 10px 5px 10px;
|
margin: 10px 10px 5px 10px;
|
||||||
background: #DDD;
|
background: #5a6162;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
border: 1px solid #B0B0B0;
|
border: 1px solid #c8c8c8;
|
||||||
}
|
}
|
||||||
|
|
||||||
#dialog_content p, #dialog_content select, #dialog_content label {
|
#dialog_content p, #dialog_content select, #dialog_content label {
|
||||||
@@ -25,7 +24,7 @@ template.innerHTML = `
|
|||||||
top: 50%;
|
top: 50%;
|
||||||
max-width: 400px;
|
max-width: 400px;
|
||||||
z-index: 50001;
|
z-index: 50001;
|
||||||
background: #CCC;
|
background: #5a6162;
|
||||||
border: 1px outset #777;
|
border: 1px outset #777;
|
||||||
font-family:Verdana,Helvetica,sans-serif;
|
font-family:Verdana,Helvetica,sans-serif;
|
||||||
font-size:0.8em;
|
font-size:0.8em;
|
||||||
@@ -73,11 +72,9 @@ template.innerHTML = `
|
|||||||
</div>
|
</div>
|
||||||
<div id="dialog_buttons">
|
<div id="dialog_buttons">
|
||||||
<button id="export_ok">
|
<button id="export_ok">
|
||||||
<img class="svg_icon" src="./images/ok.svg" alt="icon" width="16" height="16" />
|
|
||||||
Ok
|
Ok
|
||||||
</button>
|
</button>
|
||||||
<button id="export_cancel">
|
<button id="export_cancel">
|
||||||
<img class="svg_icon" src="./images/cancel.svg" alt="icon" width="16" height="16" />
|
|
||||||
Cancel
|
Cancel
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import 'elix/define/Dialog.js';
|
|
||||||
import { isValidUnit } from '../../common/units.js';
|
import { isValidUnit } from '../../common/units.js';
|
||||||
|
|
||||||
const template = document.createElement('template');
|
const template = document.createElement('template');
|
||||||
@@ -17,7 +16,8 @@ template.innerHTML = `
|
|||||||
}
|
}
|
||||||
#svg_docprops #svg_docprops_container {
|
#svg_docprops #svg_docprops_container {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
background-color: #B0B0B0;
|
background-color: #5a6162;
|
||||||
|
color: #c5c5c5;
|
||||||
border: 1px outset #777;
|
border: 1px outset #777;
|
||||||
opacity: 1.0;
|
opacity: 1.0;
|
||||||
font-family: Verdana, Helvetica, sans-serif;
|
font-family: Verdana, Helvetica, sans-serif;
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import 'elix/define/Dialog.js';
|
||||||
import './imagePropertiesDialog.js';
|
import './imagePropertiesDialog.js';
|
||||||
import './editorPreferencesDialog.js';
|
import './editorPreferencesDialog.js';
|
||||||
import './svgSourceDialog.js';
|
import './svgSourceDialog.js';
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
import 'elix/define/Dialog.js';
|
|
||||||
|
|
||||||
const template = document.createElement('template');
|
const template = document.createElement('template');
|
||||||
template.innerHTML = `
|
template.innerHTML = `
|
||||||
<style>
|
<style>
|
||||||
@@ -16,7 +14,8 @@ template.innerHTML = `
|
|||||||
}
|
}
|
||||||
|
|
||||||
#svg_source_editor #svg_source_container {
|
#svg_source_editor #svg_source_container {
|
||||||
background-color: #B0B0B0;
|
background-color: #5a6162;
|
||||||
|
color: #c5c5c5;
|
||||||
opacity: 1.0;
|
opacity: 1.0;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
border: 1px outset #777;
|
border: 1px outset #777;
|
||||||
@@ -44,18 +43,27 @@ template.innerHTML = `
|
|||||||
|
|
||||||
#svg_source_editor #tool_source_back {
|
#svg_source_editor #tool_source_back {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
margin: 5px 10px;
|
height: 30px;
|
||||||
|
}
|
||||||
|
#tool_source_save {
|
||||||
|
width: 20%;
|
||||||
|
background-color: #c79605;
|
||||||
|
margin-left: 30%;
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#tool_source_cancel {
|
||||||
|
width: 20%;
|
||||||
|
background-color: #c8c8c8;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<elix-dialog id="svg_source_editor" aria-label="SVG Source Editor" closed>
|
<elix-dialog id="svg_source_editor" aria-label="SVG Source Editor" closed>
|
||||||
<div id="svg_source_container">
|
<div id="svg_source_container">
|
||||||
<div id="tool_source_back" class="toolbar_button">
|
<div id="tool_source_back" class="toolbar_button">
|
||||||
<button id="tool_source_save">
|
<button id="tool_source_save">
|
||||||
<img class="svg_icon" src="./images/ok.svg" alt="icon" width="16" height="16" />
|
|
||||||
Apply Changes
|
Apply Changes
|
||||||
</button>
|
</button>
|
||||||
<button id="tool_source_cancel">
|
<button id="tool_source_cancel">
|
||||||
<img class="svg_icon" src="./images/cancel.svg" alt="icon" width="16" height="16" />
|
|
||||||
Cancel
|
Cancel
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
const loadExtensionTranslation = async function (svgEditor) {
|
const loadExtensionTranslation = async function (svgEditor) {
|
||||||
let translationModule;
|
let translationModule;
|
||||||
const lang = svgEditor.configObj.pref('lang')
|
const lang = svgEditor.configObj.pref('lang');
|
||||||
try {
|
try {
|
||||||
// eslint-disable-next-line no-unsanitized/method
|
// eslint-disable-next-line no-unsanitized/method
|
||||||
translationModule = await import(`./locale/${encodeURIComponent(lang)}.js`);
|
translationModule = await import(`./locale/${encodeURIComponent(lang)}.js`);
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ export default {
|
|||||||
x: midX + lenX * ratio,
|
x: midX + lenX * ratio,
|
||||||
y: midY + lenY * ratio
|
y: midY + lenY * ratio
|
||||||
};
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {"start"|"end"} side
|
* @param {"start"|"end"} side
|
||||||
@@ -92,7 +92,7 @@ export default {
|
|||||||
// TODO: Make this number (5) be based on marker width/height
|
// TODO: Make this number (5) be based on marker width/height
|
||||||
const size = line.getAttribute('stroke-width') * 5;
|
const size = line.getAttribute('stroke-width') * 5;
|
||||||
return giveOffset ? size : 0;
|
return giveOffset ? size : 0;
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {boolean} on
|
* @param {boolean} on
|
||||||
@@ -108,7 +108,7 @@ export default {
|
|||||||
connRules.textContent = (!on ? '' : '#tool_clone, #tool_topath, #tool_angle, #xy_panel { display: none !important; }');
|
connRules.textContent = (!on ? '' : '#tool_clone, #tool_topath, #tool_angle, #xy_panel { display: none !important; }');
|
||||||
if ($id('connector_panel'))
|
if ($id('connector_panel'))
|
||||||
$id('connector_panel').style.display = (on) ? 'block' : 'none';
|
$id('connector_panel').style.display = (on) ? 'block' : 'none';
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Element} elem
|
* @param {Element} elem
|
||||||
@@ -144,7 +144,7 @@ export default {
|
|||||||
const ptEnd = pts.getItem(pts.numberOfItems - 1);
|
const ptEnd = pts.getItem(pts.numberOfItems - 1);
|
||||||
setPoint(elem, 1, (ptEnd.x + ptStart.x) / 2, (ptEnd.y + ptStart.y) / 2);
|
setPoint(elem, 1, (ptEnd.x + ptStart.x) / 2, (ptEnd.y + ptStart.y) / 2);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Float} diffX
|
* @param {Float} diffX
|
||||||
@@ -184,7 +184,7 @@ export default {
|
|||||||
const pt2 = getBBintersect(pt.x, pt.y, dataStorage.get(line, altPre + '_bb'), getOffset(altPre, line));
|
const pt2 = getBBintersect(pt.x, pt.y, dataStorage.get(line, altPre + '_bb'), getOffset(altPre, line));
|
||||||
setPoint(line, conn.is_start ? 'end' : 0, pt2.x, pt2.y, true);
|
setPoint(line, conn.is_start ? 'end' : 0, pt2.x, pt2.y, true);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -244,7 +244,7 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Element[]} [elems=selElems]
|
* @param {Element[]} [elems=selElems]
|
||||||
@@ -302,7 +302,7 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
// Do once
|
// Do once
|
||||||
(function () {
|
(function () {
|
||||||
@@ -347,7 +347,7 @@ export default {
|
|||||||
svgCanvas.getEditorNS(true);
|
svgCanvas.getEditorNS(true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
const strings = await loadExtensionTranslation(svgEditor.configObj.pref('lang'));
|
const strings = await loadExtensionTranslation(svgEditor.configObj.pref('lang'));
|
||||||
return {
|
return {
|
||||||
@@ -359,7 +359,7 @@ export default {
|
|||||||
const buttonTemplate = document.createElement("template");
|
const buttonTemplate = document.createElement("template");
|
||||||
buttonTemplate.innerHTML = `
|
buttonTemplate.innerHTML = `
|
||||||
<se-button id="mode_connect" title="Connect two objects" src="./images/conn.svg"></se-button>
|
<se-button id="mode_connect" title="Connect two objects" src="./images/conn.svg"></se-button>
|
||||||
`
|
`;
|
||||||
$id('tools_left').append(buttonTemplate.content.cloneNode(true));
|
$id('tools_left').append(buttonTemplate.content.cloneNode(true));
|
||||||
$id('mode_connect').addEventListener("click", () => {
|
$id('mode_connect').addEventListener("click", () => {
|
||||||
svgCanvas.setMode('connector');
|
svgCanvas.setMode('connector');
|
||||||
|
|||||||
@@ -4,27 +4,32 @@
|
|||||||
* @license MIT
|
* @license MIT
|
||||||
*
|
*
|
||||||
* @copyright 2010 Jeff Schiller
|
* @copyright 2010 Jeff Schiller
|
||||||
|
* @copyright 2021 OptimistikSAS
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const loadExtensionTranslation = async function (lang) {
|
const name = "eyedropper";
|
||||||
|
|
||||||
|
const loadExtensionTranslation = async function (svgEditor) {
|
||||||
let translationModule;
|
let translationModule;
|
||||||
|
const lang = svgEditor.configObj.pref('lang');
|
||||||
try {
|
try {
|
||||||
// eslint-disable-next-line no-unsanitized/method
|
// eslint-disable-next-line no-unsanitized/method
|
||||||
translationModule = await import(`./locale/${encodeURIComponent(lang)}.js`);
|
translationModule = await import(`./locale/${lang}.js`);
|
||||||
} catch (_error) {
|
} catch (_error) {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.error(`Missing translation (${lang}) - using 'en'`);
|
console.warn(`Missing translation (${lang}) for ${name} - using 'en'`);
|
||||||
|
// eslint-disable-next-line no-unsanitized/method
|
||||||
translationModule = await import(`./locale/en.js`);
|
translationModule = await import(`./locale/en.js`);
|
||||||
}
|
}
|
||||||
return translationModule.default;
|
svgEditor.i18next.addResourceBundle(lang, name, translationModule.default);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'eyedropper',
|
name,
|
||||||
async init(S) {
|
async init(S) {
|
||||||
const svgEditor = this;
|
const svgEditor = this;
|
||||||
const strings = await loadExtensionTranslation(svgEditor.configObj.pref('lang'));
|
await loadExtensionTranslation(svgEditor);
|
||||||
const { ChangeElementCommand } = S, // , svgcontent,
|
const { ChangeElementCommand } = S, // , svgcontent,
|
||||||
// svgdoc = S.svgroot.parentNode.ownerDocument,
|
// svgdoc = S.svgroot.parentNode.ownerDocument,
|
||||||
{ svgCanvas } = svgEditor,
|
{ svgCanvas } = svgEditor,
|
||||||
@@ -71,16 +76,19 @@ export default {
|
|||||||
} else {
|
} else {
|
||||||
tool.classList.add('disabled');
|
tool.classList.add('disabled');
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
name: strings.name,
|
name: svgEditor.i18next.t(`${name}:name`),
|
||||||
callback() {
|
callback() {
|
||||||
// Add the button and its handler(s)
|
// Add the button and its handler(s)
|
||||||
const buttonTemplate = document.createElement("template");
|
const buttonTemplate = document.createElement("template");
|
||||||
|
const title = svgEditor.i18next.t(`${name}:buttons.0.title`);
|
||||||
|
const key = svgEditor.i18next.t(`${name}:buttons.0.key`);
|
||||||
|
// eslint-disable-next-line no-unsanitized/property
|
||||||
buttonTemplate.innerHTML = `
|
buttonTemplate.innerHTML = `
|
||||||
<se-button id="tool_eyedropper" title="Eye Dropper Tool" src="./images/eye_dropper.svg" shortcut="I"></se-button>
|
<se-button id="tool_eyedropper" title="${title}" src="./images/eye_dropper.svg" shortcut=${key}></se-button>
|
||||||
`
|
`;
|
||||||
$id('tools_left').append(buttonTemplate.content.cloneNode(true));
|
$id('tools_left').append(buttonTemplate.content.cloneNode(true));
|
||||||
$id('tool_eyedropper').addEventListener("click", () => {
|
$id('tool_eyedropper').addEventListener("click", () => {
|
||||||
svgCanvas.setMode('eyedropper');
|
svgCanvas.setMode('eyedropper');
|
||||||
|
|||||||
9
src/editor/extensions/ext-eyedropper/locale/fr.js
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
export default {
|
||||||
|
name: 'pipette',
|
||||||
|
buttons: [
|
||||||
|
{
|
||||||
|
title: 'Outil pipette',
|
||||||
|
key: 'I'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
@@ -277,7 +277,7 @@ export default {
|
|||||||
const attrs = {
|
const attrs = {
|
||||||
width: newFO.getAttribute('width'),
|
width: newFO.getAttribute('width'),
|
||||||
height: newFO.getAttribute('height'),
|
height: newFO.getAttribute('height'),
|
||||||
}
|
};
|
||||||
const keep = (attrs.width !== '0' || attrs.height !== '0');
|
const keep = (attrs.width !== '0' || attrs.height !== '0');
|
||||||
svgCanvas.addToSelection([ newFO ], true);
|
svgCanvas.addToSelection([ newFO ], true);
|
||||||
|
|
||||||
|
|||||||
@@ -7,24 +7,28 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const loadExtensionTranslation = async function (lang) {
|
const name = "grid";
|
||||||
|
|
||||||
|
const loadExtensionTranslation = async function (svgEditor) {
|
||||||
let translationModule;
|
let translationModule;
|
||||||
|
const lang = svgEditor.configObj.pref('lang');
|
||||||
try {
|
try {
|
||||||
// eslint-disable-next-line no-unsanitized/method
|
// eslint-disable-next-line no-unsanitized/method
|
||||||
translationModule = await import(`./locale/${encodeURIComponent(lang)}.js`);
|
translationModule = await import(`./locale/${lang}.js`);
|
||||||
} catch (_error) {
|
} catch (_error) {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.error(`Missing translation (${lang}) - using 'en'`);
|
console.warn(`Missing translation (${lang}) for ${name} - using 'en'`);
|
||||||
|
// eslint-disable-next-line no-unsanitized/method
|
||||||
translationModule = await import(`./locale/en.js`);
|
translationModule = await import(`./locale/en.js`);
|
||||||
}
|
}
|
||||||
return translationModule.default;
|
svgEditor.i18next.addResourceBundle(lang, name, translationModule.default);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'grid',
|
name,
|
||||||
async init ({ NS, getTypeMap }) {
|
async init ({ NS, getTypeMap }) {
|
||||||
const svgEditor = this;
|
const svgEditor = this;
|
||||||
const strings = await loadExtensionTranslation(svgEditor.configObj.pref('lang'));
|
await loadExtensionTranslation(svgEditor);
|
||||||
const { svgCanvas } = svgEditor;
|
const { svgCanvas } = svgEditor;
|
||||||
const { $id } = svgCanvas;
|
const { $id } = svgCanvas;
|
||||||
const svgdoc = document.getElementById('svgcanvas').ownerDocument;
|
const svgdoc = document.getElementById('svgcanvas').ownerDocument;
|
||||||
@@ -138,7 +142,7 @@ export default {
|
|||||||
gridimg.parentNode.setAttribute('width', bigInt);
|
gridimg.parentNode.setAttribute('width', bigInt);
|
||||||
gridimg.parentNode.setAttribute('height', bigInt);
|
gridimg.parentNode.setAttribute('height', bigInt);
|
||||||
svgCanvas.setHref(gridimg, datauri);
|
svgCanvas.setHref(gridimg, datauri);
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -150,18 +154,21 @@ export default {
|
|||||||
}
|
}
|
||||||
$id('canvasGrid').style.display = (showGrid) ? 'block' : 'none';
|
$id('canvasGrid').style.display = (showGrid) ? 'block' : 'none';
|
||||||
document.getElementById('view_grid').pressed = showGrid;
|
document.getElementById('view_grid').pressed = showGrid;
|
||||||
}
|
};
|
||||||
return {
|
return {
|
||||||
name: strings.name,
|
name: svgEditor.i18next.t(`${name}:name`),
|
||||||
zoomChanged (zoom) {
|
zoomChanged (zoom) {
|
||||||
if (showGrid) { updateGrid(zoom); }
|
if (showGrid) { updateGrid(zoom); }
|
||||||
},
|
},
|
||||||
callback () {
|
callback () {
|
||||||
// Add the button and its handler(s)
|
// Add the button and its handler(s)
|
||||||
const buttonTemplate = document.createElement("template");
|
const buttonTemplate = document.createElement("template");
|
||||||
|
const title = svgEditor.i18next.t(`${name}:buttons.0.title`);
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-unsanitized/property
|
||||||
buttonTemplate.innerHTML = `
|
buttonTemplate.innerHTML = `
|
||||||
<se-button id="view_grid" title="Show grid" src="./images/grid.svg"></se-button>
|
<se-button id="view_grid" title="${title}" src="./images/grid.svg"></se-button>
|
||||||
`
|
`;
|
||||||
$id('editor_panel').append(buttonTemplate.content.cloneNode(true));
|
$id('editor_panel').append(buttonTemplate.content.cloneNode(true));
|
||||||
$id('view_grid').addEventListener("click", () => {
|
$id('view_grid').addEventListener("click", () => {
|
||||||
svgEditor.configObj.curConfig.showGrid = showGrid = !showGrid;
|
svgEditor.configObj.curConfig.showGrid = showGrid = !showGrid;
|
||||||
|
|||||||
8
src/editor/extensions/ext-grid/locale/fr.js
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
export default {
|
||||||
|
name: 'Grille',
|
||||||
|
buttons: [
|
||||||
|
{
|
||||||
|
title: 'Afficher/Cacher Grille'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
@@ -13,39 +13,45 @@
|
|||||||
* will show the user the point on the canvas that was clicked on.
|
* will show the user the point on the canvas that was clicked on.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const loadExtensionTranslation = async function (lang) {
|
const name = "helloworld";
|
||||||
|
|
||||||
|
const loadExtensionTranslation = async function (svgEditor) {
|
||||||
let translationModule;
|
let translationModule;
|
||||||
|
const lang = svgEditor.configObj.pref('lang');
|
||||||
try {
|
try {
|
||||||
// eslint-disable-next-line no-unsanitized/method
|
// eslint-disable-next-line no-unsanitized/method
|
||||||
translationModule = await import(`./locale/${encodeURIComponent(lang)}.js`);
|
translationModule = await import(`./locale/${lang}.js`);
|
||||||
} catch (_error) {
|
} catch (_error) {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.error(`Missing translation (${lang}) - using 'en'`);
|
console.warn(`Missing translation (${lang}) for ${name} - using 'en'`);
|
||||||
|
// eslint-disable-next-line no-unsanitized/method
|
||||||
translationModule = await import(`./locale/en.js`);
|
translationModule = await import(`./locale/en.js`);
|
||||||
}
|
}
|
||||||
return translationModule.default;
|
svgEditor.i18next.addResourceBundle(lang, name, translationModule.default);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'helloworld',
|
name,
|
||||||
async init ({ _importLocale }) {
|
async init ({ _importLocale }) {
|
||||||
const svgEditor = this;
|
const svgEditor = this;
|
||||||
const strings = await loadExtensionTranslation(svgEditor.configObj.pref('lang'));
|
await loadExtensionTranslation(svgEditor);
|
||||||
const { svgCanvas } = svgEditor;
|
const { svgCanvas } = svgEditor;
|
||||||
|
const { $id } = svgCanvas;
|
||||||
return {
|
return {
|
||||||
name: strings.name,
|
name: svgEditor.i18next.t(`${name}:name`),
|
||||||
events: [{
|
callback() {
|
||||||
// Must match the icon ID in helloworld-icon.xml
|
// Add the button and its handler(s)
|
||||||
id: 'hello_world',
|
const buttonTemplate = document.createElement("template");
|
||||||
// Tooltip text
|
const title = svgEditor.i18next.t(`${name}:buttons.0.title`);
|
||||||
title: strings.buttons[0].title,
|
// eslint-disable-next-line no-unsanitized/property
|
||||||
click () {
|
buttonTemplate.innerHTML = `
|
||||||
// The action taken when the button is clicked on.
|
<se-button id="hello_world" title="${title}" src="./images/hello_world.svg"></se-button>
|
||||||
// For "mode" buttons, any other button will
|
`;
|
||||||
// automatically be de-pressed.
|
$id('tools_left').append(buttonTemplate.content.cloneNode(true));
|
||||||
|
$id('hello_world').addEventListener("click", () => {
|
||||||
svgCanvas.setMode('hello_world');
|
svgCanvas.setMode('hello_world');
|
||||||
}
|
});
|
||||||
}],
|
},
|
||||||
// This is triggered when the main mouse button is pressed down
|
// This is triggered when the main mouse button is pressed down
|
||||||
// on the editor canvas (not the tool panels)
|
// on the editor canvas (not the tool panels)
|
||||||
mouseDown () {
|
mouseDown () {
|
||||||
@@ -70,14 +76,7 @@ export default {
|
|||||||
const y = opts.mouse_y / zoom;
|
const y = opts.mouse_y / zoom;
|
||||||
|
|
||||||
// We do our own formatting
|
// We do our own formatting
|
||||||
let {text} = strings;
|
let text = svgEditor.i18next.t(`${name}:text`, { x, y });
|
||||||
[
|
|
||||||
['x', x],
|
|
||||||
['y', y]
|
|
||||||
].forEach(([prop, val]) => {
|
|
||||||
text = text.replace('{' + prop + '}', val);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Show the text using the custom alert function
|
// Show the text using the custom alert function
|
||||||
alert(text);
|
alert(text);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
export default {
|
export default {
|
||||||
name: 'Hello World',
|
name: 'Hello World',
|
||||||
text: 'Hello World!\n\nYou clicked here: {x}, {y}',
|
text: 'Hello World!\n\nYou clicked here: {{x}}, {{y}}',
|
||||||
buttons: [
|
buttons: [
|
||||||
{
|
{
|
||||||
title: "Say 'Hello World'"
|
title: "Say 'Hello World'"
|
||||||
|
|||||||
9
src/editor/extensions/ext-helloworld/locale/fr.js
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
export default {
|
||||||
|
name: 'Bonjour le Monde',
|
||||||
|
text: 'Bonjour le Monde!\n\nVous avez cliqué ici: {{x}}, {{y}}',
|
||||||
|
buttons: [
|
||||||
|
{
|
||||||
|
title: "Dire 'Bonjour le Monde'"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
export default {
|
export default {
|
||||||
name: 'Hello World',
|
name: 'Hello World',
|
||||||
text: 'Hello World!\n\n 请点击: {x}, {y}',
|
text: 'Hello World!\n\n 请点击: {{x}}, {{y}}',
|
||||||
buttons: [
|
buttons: [
|
||||||
{
|
{
|
||||||
title: "输出 'Hello World'"
|
title: "输出 'Hello World'"
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ export default {
|
|||||||
const { $id } = svgEditor.svgCanvas;
|
const { $id } = svgEditor.svgCanvas;
|
||||||
const imagelibStrings = await loadExtensionTranslation(svgEditor.configObj.pref('lang'));
|
const imagelibStrings = await loadExtensionTranslation(svgEditor.configObj.pref('lang'));
|
||||||
|
|
||||||
const { uiStrings, svgCanvas } = svgEditor;
|
const { svgCanvas } = svgEditor;
|
||||||
|
|
||||||
const allowedImageLibOrigins = imagelibStrings.imgLibs.map(({ url }) => {
|
const allowedImageLibOrigins = imagelibStrings.imgLibs.map(({ url }) => {
|
||||||
try {
|
try {
|
||||||
@@ -46,7 +46,7 @@ export default {
|
|||||||
const closeBrowser = () => {
|
const closeBrowser = () => {
|
||||||
$id("imgbrowse_holder").style.display = 'none';
|
$id("imgbrowse_holder").style.display = 'none';
|
||||||
document.activeElement.blur(); // make sure focus is the body to correct issue #417
|
document.activeElement.blur(); // make sure focus is the body to correct issue #417
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} url
|
* @param {string} url
|
||||||
@@ -67,7 +67,7 @@ export default {
|
|||||||
svgCanvas.clearSelection();
|
svgCanvas.clearSelection();
|
||||||
svgCanvas.addToSelection([ newImage ]);
|
svgCanvas.addToSelection([ newImage ]);
|
||||||
svgCanvas.setImageURL(url);
|
svgCanvas.setImageURL(url);
|
||||||
}
|
};
|
||||||
|
|
||||||
const pending = {};
|
const pending = {};
|
||||||
|
|
||||||
@@ -112,7 +112,8 @@ export default {
|
|||||||
* @param {ImageLibMetaMessage|ImageLibMessage|string} cfg.data String is deprecated when parsed to JSON `ImageLibMessage`
|
* @param {ImageLibMetaMessage|ImageLibMessage|string} cfg.data String is deprecated when parsed to JSON `ImageLibMessage`
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
async function onMessage({ origin, data: response }) {
|
async function onMessage({ origin, data }) {
|
||||||
|
let response = data;
|
||||||
if (!response || ![ 'string', 'object' ].includes(typeof response)) {
|
if (!response || ![ 'string', 'object' ].includes(typeof response)) {
|
||||||
// Do nothing
|
// Do nothing
|
||||||
return;
|
return;
|
||||||
@@ -129,7 +130,7 @@ export default {
|
|||||||
}
|
}
|
||||||
if (!allowedImageLibOrigins.includes('*') && !allowedImageLibOrigins.includes(origin)) {
|
if (!allowedImageLibOrigins.includes('*') && !allowedImageLibOrigins.includes(origin)) {
|
||||||
// Todo: Surface this error to user?
|
// Todo: Surface this error to user?
|
||||||
console.log(`Origin ${origin} not whitelisted for posting to ${window.origin}`);
|
console.error(`Origin ${origin} not whitelisted for posting to ${window.origin}`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const hasName = 'name' in response;
|
const hasName = 'name' in response;
|
||||||
@@ -184,7 +185,7 @@ export default {
|
|||||||
|
|
||||||
const name = (curMeta.name || 'file');
|
const name = (curMeta.name || 'file');
|
||||||
|
|
||||||
const message = uiStrings.notification.retrieving.replace('%s', name);
|
const message = svgEditor.i18next.t('notification.retrieving').replace('%s', name);
|
||||||
|
|
||||||
if (mode !== 'm') {
|
if (mode !== 'm') {
|
||||||
await seConfirm(message);
|
await seConfirm(message);
|
||||||
@@ -290,7 +291,7 @@ export default {
|
|||||||
const img = document.createElement("img");
|
const img = document.createElement("img");
|
||||||
img.src = curMeta.preview_url;
|
img.src = curMeta.preview_url;
|
||||||
entry.appendChild(img);
|
entry.appendChild(img);
|
||||||
entry.appendChild(document.createTextNode(title))
|
entry.appendChild(document.createTextNode(title));
|
||||||
} else {
|
} else {
|
||||||
entry = document.createElement("img");
|
entry = document.createElement("img");
|
||||||
entry.src = response;
|
entry.src = response;
|
||||||
@@ -330,7 +331,7 @@ export default {
|
|||||||
|
|
||||||
const insertAfter = (referenceNode, newNode) => {
|
const insertAfter = (referenceNode, newNode) => {
|
||||||
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
|
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
|
||||||
}
|
};
|
||||||
|
|
||||||
const toggleMultiLoop = () => {
|
const toggleMultiLoop = () => {
|
||||||
multiArr.forEach(function(item, i){
|
multiArr.forEach(function(item, i){
|
||||||
@@ -347,7 +348,7 @@ export default {
|
|||||||
preview.removeChild(preview.firstChild);
|
preview.removeChild(preview.firstChild);
|
||||||
multiArr = [];
|
multiArr = [];
|
||||||
$id("imgbrowse_holder").style.display = 'none';
|
$id("imgbrowse_holder").style.display = 'none';
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {boolean} show
|
* @param {boolean} show
|
||||||
@@ -375,7 +376,7 @@ export default {
|
|||||||
submit.style.display = (show) ? 'block' : 'none';
|
submit.style.display = (show) ? 'block' : 'none';
|
||||||
preview.style.display = (show) ? 'block' : 'none';
|
preview.style.display = (show) ? 'block' : 'none';
|
||||||
|
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -411,7 +412,7 @@ export default {
|
|||||||
|
|
||||||
const button = document.createElement('button');
|
const button = document.createElement('button');
|
||||||
// eslint-disable-next-line max-len
|
// eslint-disable-next-line max-len
|
||||||
button.innerHTML = '<img class="svg_icon" src="./images/cancel.svg" alt="icon" width="16" height="16" />' + uiStrings.common.cancel;
|
button.innerHTML = '<img class="svg_icon" src="./images/cancel.svg" alt="icon" width="16" height="16" />' + svgEditor.i18next.t('common.cancel');
|
||||||
browser.appendChild(button);
|
browser.appendChild(button);
|
||||||
button.addEventListener('click', function () {
|
button.addEventListener('click', function () {
|
||||||
$id("imgbrowse_holder").style.display = 'none';
|
$id("imgbrowse_holder").style.display = 'none';
|
||||||
@@ -496,7 +497,7 @@ export default {
|
|||||||
} else {
|
} else {
|
||||||
$id("imgbrowse_holder").style.display = 'block';
|
$id("imgbrowse_holder").style.display = 'block';
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
svgicons: 'ext-imagelib.xml',
|
svgicons: 'ext-imagelib.xml',
|
||||||
@@ -529,7 +530,7 @@ export default {
|
|||||||
'bottom: 25px;' +
|
'bottom: 25px;' +
|
||||||
'min-width: 300px;' +
|
'min-width: 300px;' +
|
||||||
'min-height: 200px;' +
|
'min-height: 200px;' +
|
||||||
'background: #B0B0B0;' +
|
'background: #5a6162;' +
|
||||||
'border: 1px outset #777;' +
|
'border: 1px outset #777;' +
|
||||||
'}' +
|
'}' +
|
||||||
'#imgbrowse h1 {' +
|
'#imgbrowse h1 {' +
|
||||||
@@ -567,7 +568,7 @@ export default {
|
|||||||
'list-style: none;' +
|
'list-style: none;' +
|
||||||
'padding: .5em;' +
|
'padding: .5em;' +
|
||||||
'background: #E8E8E8;' +
|
'background: #E8E8E8;' +
|
||||||
'border-bottom: 1px solid #B0B0B0;' +
|
'border-bottom: 1px solid #5a6162;' +
|
||||||
'line-height: 1.2em;' +
|
'line-height: 1.2em;' +
|
||||||
'font-style: sans-serif;' +
|
'font-style: sans-serif;' +
|
||||||
'}' +
|
'}' +
|
||||||
|
|||||||
@@ -48,5 +48,5 @@ Array.prototype.forEach.call(atags, function (aEle) {
|
|||||||
}, 'html'); // 'html' is necessary to keep returned data as a string
|
}, 'html'); // 'html' is necessary to keep returned data as a string
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
})
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ async function processResults (url) {
|
|||||||
|
|
||||||
const r = await fetch(url);
|
const r = await fetch(url);
|
||||||
const json = await r.json();
|
const json = await r.json();
|
||||||
// console.log('json', json);
|
|
||||||
|
|
||||||
if (!json || json.msg !== 'success') {
|
if (!json || json.msg !== 'success') {
|
||||||
// Todo: This could use a generic alert library instead
|
// Todo: This could use a generic alert library instead
|
||||||
@@ -87,7 +86,6 @@ async function processResults (url) {
|
|||||||
async click (e) {
|
async click (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const { value: svgurl } = this.dataset;
|
const { value: svgurl } = this.dataset;
|
||||||
// console.log('this', id, svgurl);
|
|
||||||
const post = (message) => {
|
const post = (message) => {
|
||||||
// Todo: Make origin customizable as set by opening window
|
// Todo: Make origin customizable as set by opening window
|
||||||
// Todo: If dropping IE9, avoid stringifying
|
// Todo: If dropping IE9, avoid stringifying
|
||||||
@@ -103,7 +101,6 @@ async function processResults (url) {
|
|||||||
});
|
});
|
||||||
const result = await fetch(svgurl);
|
const result = await fetch(svgurl);
|
||||||
const svg = await result.text();
|
const svg = await result.text();
|
||||||
// console.log('url and svg', svgurl, svg);
|
|
||||||
post({
|
post({
|
||||||
href: svgurl,
|
href: svgurl,
|
||||||
data: svg
|
data: svg
|
||||||
|
|||||||
@@ -123,8 +123,6 @@ export default {
|
|||||||
function setIcon (pos, id) {
|
function setIcon (pos, id) {
|
||||||
if (id.substr(0, 1) !== '\\') { id = '\\textmarker'; }
|
if (id.substr(0, 1) !== '\\') { id = '\\textmarker'; }
|
||||||
const ci = idPrefix + pos + '_' + id.substr(1);
|
const ci = idPrefix + pos + '_' + id.substr(1);
|
||||||
console.log(ci)
|
|
||||||
console.log('cur_' + pos + '_marker_list')
|
|
||||||
svgEditor.setIcon('cur_' + pos + '_marker_list', $id(ci).children);
|
svgEditor.setIcon('cur_' + pos + '_marker_list', $id(ci).children);
|
||||||
$id(ci).classList.add('current');
|
$id(ci).classList.add('current');
|
||||||
const siblings = Array.prototype.filter.call($id(ci).parentNode.children, function(child){
|
const siblings = Array.prototype.filter.call($id(ci).parentNode.children, function(child){
|
||||||
@@ -585,7 +583,6 @@ export default {
|
|||||||
},
|
},
|
||||||
selectedChanged (opts) {
|
selectedChanged (opts) {
|
||||||
// Use this to update the current selected elements
|
// Use this to update the current selected elements
|
||||||
// console.log('selectChanged',opts);
|
|
||||||
selElems = opts.elems;
|
selElems = opts.elems;
|
||||||
|
|
||||||
const markerElems = [ 'line', 'path', 'polyline', 'polygon' ];
|
const markerElems = [ 'line', 'path', 'polyline', 'polygon' ];
|
||||||
|
|||||||
@@ -191,12 +191,11 @@ export default {
|
|||||||
// When MathJax is loaded get the div where the math will be rendered.
|
// When MathJax is loaded get the div where the math will be rendered.
|
||||||
MathJax.Hub.queue.Push(function () {
|
MathJax.Hub.queue.Push(function () {
|
||||||
math = MathJax.Hub.getAllJax('#mathjax_creator')[0];
|
math = MathJax.Hub.getAllJax('#mathjax_creator')[0];
|
||||||
console.log(math);
|
|
||||||
mathjaxLoaded = true;
|
mathjaxLoaded = true;
|
||||||
console.log('MathJax Loaded');
|
console.info('MathJax Loaded');
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log('Failed loading MathJax.');
|
console.warn('Failed loading MathJax.');
|
||||||
// eslint-disable-next-line no-alert
|
// eslint-disable-next-line no-alert
|
||||||
alert('Failed loading MathJax. You will not be able to change the mathematics.');
|
alert('Failed loading MathJax. You will not be able to change the mathematics.');
|
||||||
}
|
}
|
||||||
@@ -260,7 +259,7 @@ export default {
|
|||||||
'position: absolute;' +
|
'position: absolute;' +
|
||||||
'top: 50px;' +
|
'top: 50px;' +
|
||||||
'padding: 10px;' +
|
'padding: 10px;' +
|
||||||
'background-color: #B0B0B0;' +
|
'background-color: #5a6162;' +
|
||||||
'border: 1px outset #777;' +
|
'border: 1px outset #777;' +
|
||||||
'opacity: 1.0;' +
|
'opacity: 1.0;' +
|
||||||
'font-family: Verdana, Helvetica, sans-serif;' +
|
'font-family: Verdana, Helvetica, sans-serif;' +
|
||||||
|
|||||||
@@ -0,0 +1,97 @@
|
|||||||
|
// https://github.com/knadh/dragmove.js
|
||||||
|
// Kailash Nadh (c) 2020.
|
||||||
|
// MIT License.
|
||||||
|
// can't use npm version as the dragmove is different.
|
||||||
|
|
||||||
|
let _loaded = false;
|
||||||
|
let _callbacks = [];
|
||||||
|
const _isTouch = window.ontouchstart !== undefined;
|
||||||
|
|
||||||
|
export const dragmove = function(target, handler, parent, onStart, onEnd, onDrag) {
|
||||||
|
// Register a global event to capture mouse moves (once).
|
||||||
|
if (!_loaded) {
|
||||||
|
document.addEventListener(_isTouch ? "touchmove" : "mousemove", function(e) {
|
||||||
|
let c = e;
|
||||||
|
if (e.touches) {
|
||||||
|
c = e.touches[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// On mouse move, dispatch the coords to all registered callbacks.
|
||||||
|
for (let i = 0; i < _callbacks.length; i++) {
|
||||||
|
_callbacks[i](c.clientX, c.clientY);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_loaded = true;
|
||||||
|
let isMoving = false, hasStarted = false;
|
||||||
|
let startX = 0, startY = 0, lastX = 0, lastY = 0;
|
||||||
|
|
||||||
|
// On the first click and hold, record the offset of the pointer in relation
|
||||||
|
// to the point of click inside the element.
|
||||||
|
handler.addEventListener(_isTouch ? "touchstart" : "mousedown", function(e) {
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
if (target.dataset.dragEnabled === "false") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let c = e;
|
||||||
|
if (e.touches) {
|
||||||
|
c = e.touches[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
isMoving = true;
|
||||||
|
startX = target.offsetLeft - c.clientX;
|
||||||
|
startY = target.offsetTop - c.clientY;
|
||||||
|
});
|
||||||
|
|
||||||
|
// On leaving click, stop moving.
|
||||||
|
document.addEventListener(_isTouch ? "touchend" : "mouseup", function() {
|
||||||
|
if (onEnd && hasStarted) {
|
||||||
|
onEnd(target, parent, parseInt(target.style.left), parseInt(target.style.top));
|
||||||
|
}
|
||||||
|
|
||||||
|
isMoving = false;
|
||||||
|
hasStarted = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
// On leaving click, stop moving.
|
||||||
|
document.addEventListener(_isTouch ? "touchmove" : "mousemove", function() {
|
||||||
|
if (onDrag && hasStarted) {
|
||||||
|
onDrag(target, parseInt(target.style.left), parseInt(target.style.top));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Register mouse-move callback to move the element.
|
||||||
|
_callbacks.push(function move(x, y) {
|
||||||
|
if (!isMoving) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasStarted) {
|
||||||
|
hasStarted = true;
|
||||||
|
if (onStart) {
|
||||||
|
onStart(target, lastX, lastY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lastX = x + startX;
|
||||||
|
lastY = y + startY;
|
||||||
|
|
||||||
|
// If boundary checking is on, don't let the element cross the viewport.
|
||||||
|
if (target.dataset.dragBoundary === "true") {
|
||||||
|
if (lastX < 1 || lastX >= window.innerWidth - target.offsetWidth) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (lastY < 1 || lastY >= window.innerHeight - target.offsetHeight) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
target.style.left = lastX + "px";
|
||||||
|
target.style.top = lastY + "px";
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export { dragmove as default };
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
* @copyright 2013 James Sacksteder
|
* @copyright 2013 James Sacksteder
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
import { dragmove } from '../../../editor/dragmove/dragmove.js';
|
import { dragmove } from './dragmove/dragmove.js';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'overview_window',
|
name: 'overview_window',
|
||||||
@@ -119,12 +119,12 @@ export default {
|
|||||||
if((el.offsetLeft + el.offsetWidth) > parseFloat(getComputedStyle(parent, null).width.replace("px", ""))){
|
if((el.offsetLeft + el.offsetWidth) > parseFloat(getComputedStyle(parent, null).width.replace("px", ""))){
|
||||||
el.style.left = (parseFloat(getComputedStyle(parent, null).width.replace("px", "")) - el.offsetWidth) + 'px';
|
el.style.left = (parseFloat(getComputedStyle(parent, null).width.replace("px", "")) - el.offsetWidth) + 'px';
|
||||||
} else if(el.offsetLeft < 0){
|
} else if(el.offsetLeft < 0){
|
||||||
el.style.left = "0px"
|
el.style.left = "0px";
|
||||||
}
|
}
|
||||||
if((el.offsetTop + el.offsetHeight) > parseFloat(getComputedStyle(parent, null).height.replace("px", ""))){
|
if((el.offsetTop + el.offsetHeight) > parseFloat(getComputedStyle(parent, null).height.replace("px", ""))){
|
||||||
el.style.top = (parseFloat(getComputedStyle(parent, null).height.replace("px", "")) - el.offsetHeight) + 'px';
|
el.style.top = (parseFloat(getComputedStyle(parent, null).height.replace("px", "")) - el.offsetHeight) + 'px';
|
||||||
} else if(el.offsetTop < 0){
|
} else if(el.offsetTop < 0){
|
||||||
el.style.top = "0px"
|
el.style.top = "0px";
|
||||||
}
|
}
|
||||||
overviewWindowGlobals.viewBoxDragging = false;
|
overviewWindowGlobals.viewBoxDragging = false;
|
||||||
updateViewPortFromViewBox();
|
updateViewPortFromViewBox();
|
||||||
@@ -136,7 +136,7 @@ export default {
|
|||||||
const parentElem = document.querySelector("#overviewMiniView");
|
const parentElem = document.querySelector("#overviewMiniView");
|
||||||
dragmove(dragElem, dragElem, parentElem, onStart, onEnd, onDrag);
|
dragmove(dragElem, dragElem, parentElem, onStart, onEnd, onDrag);
|
||||||
|
|
||||||
$id("overviewMiniView").addEventListener("click", evt => {
|
$id("overviewMiniView").addEventListener("click", (evt) => {
|
||||||
// Firefox doesn't support evt.offsetX and evt.offsetY.
|
// Firefox doesn't support evt.offsetX and evt.offsetY.
|
||||||
const mouseX = (evt.offsetX || evt.originalEvent.layerX);
|
const mouseX = (evt.offsetX || evt.originalEvent.layerX);
|
||||||
const mouseY = (evt.offsetY || evt.originalEvent.layerY);
|
const mouseY = (evt.offsetY || evt.originalEvent.layerY);
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ export default {
|
|||||||
} = svgCanvas;
|
} = svgCanvas;
|
||||||
const insertAfter = (referenceNode, newNode) => {
|
const insertAfter = (referenceNode, newNode) => {
|
||||||
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
|
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
|
||||||
}
|
};
|
||||||
return {
|
return {
|
||||||
newUI: true,
|
newUI: true,
|
||||||
name: strings.name,
|
name: strings.name,
|
||||||
|
|||||||
@@ -223,7 +223,6 @@ export default {
|
|||||||
function colorChanged (el) {
|
function colorChanged (el) {
|
||||||
const color = el.getAttribute('stroke');
|
const color = el.getAttribute('stroke');
|
||||||
const marker = getLinked(el, 'marker-start');
|
const marker = getLinked(el, 'marker-start');
|
||||||
// console.log(marker);
|
|
||||||
if (!marker) { return; }
|
if (!marker) { return; }
|
||||||
if (!marker.attributes.class) { return; } // not created by this extension
|
if (!marker.attributes.class) { return; } // not created by this extension
|
||||||
const ch = marker.lastElementChild;
|
const ch = marker.lastElementChild;
|
||||||
|
|||||||
@@ -1,209 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file ext-polygon.js
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @copyright 2010 CloudCanvas, Inc. All rights reserved
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
const loadExtensionTranslation = async function (lang) {
|
|
||||||
let translationModule;
|
|
||||||
try {
|
|
||||||
// eslint-disable-next-line no-unsanitized/method
|
|
||||||
translationModule = await import(`./locale/${encodeURIComponent(lang)}.js`);
|
|
||||||
} catch (_error) {
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.error(`Missing translation (${lang}) - using 'en'`);
|
|
||||||
translationModule = await import(`./locale/en.js`);
|
|
||||||
}
|
|
||||||
return translationModule.default;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'polygon',
|
|
||||||
async init (_S) {
|
|
||||||
const svgEditor = this;
|
|
||||||
const {svgCanvas} = svgEditor;
|
|
||||||
const {$id} = svgCanvas;
|
|
||||||
// const editingitex = false;
|
|
||||||
const strings = await loadExtensionTranslation(svgEditor.configObj.pref('lang'));
|
|
||||||
let selElems;
|
|
||||||
let started;
|
|
||||||
let newFO;
|
|
||||||
/**
|
|
||||||
* @param {boolean} on
|
|
||||||
* @returns {void}
|
|
||||||
*/
|
|
||||||
const showPanel = (on) => {
|
|
||||||
$id('polygon_panel').style.display = (on) ? 'block' : 'none';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} attr
|
|
||||||
* @param {string|Float} val
|
|
||||||
* @returns {void}
|
|
||||||
*/
|
|
||||||
const setAttr = (attr, val) => {
|
|
||||||
svgCanvas.changeSelectedAttribute(attr, val);
|
|
||||||
svgCanvas.call('changed', selElems);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Float} n
|
|
||||||
* @returns {Float}
|
|
||||||
*/
|
|
||||||
const cot = (n) => (1 / Math.tan(n));
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Float} n
|
|
||||||
* @returns {Float}
|
|
||||||
*/
|
|
||||||
const sec = (n) => (1 / Math.cos(n));
|
|
||||||
|
|
||||||
return {
|
|
||||||
name: strings.name,
|
|
||||||
// The callback should be used to load the DOM with the appropriate UI items
|
|
||||||
callback () {
|
|
||||||
// Add the button and its handler(s)
|
|
||||||
// Note: the star extension may also add the same flying button so we check first
|
|
||||||
if ($id('tools_polygon') === null) {
|
|
||||||
const buttonTemplate = document.createElement("template");
|
|
||||||
buttonTemplate.innerHTML = `
|
|
||||||
<se-flyingbutton id="tools_polygon" title="Polygone/Star Tool">
|
|
||||||
<se-button id="tool_polygon" title="Polygon Tool" src="./images/polygon.svg"></se-button>
|
|
||||||
<se-button id="tool_star" title="Star Tool" src="./images/star.svg"></se-button>
|
|
||||||
</se-flyingbutton>
|
|
||||||
`
|
|
||||||
$id('tools_left').append(buttonTemplate.content.cloneNode(true));
|
|
||||||
}
|
|
||||||
$id('tool_polygon').addEventListener("click", () => {
|
|
||||||
if (this.leftPanel.updateLeftPanel('tool_polygon')) {
|
|
||||||
svgCanvas.setMode('polygon');
|
|
||||||
showPanel(true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Add the context panel and its handler(s)
|
|
||||||
const panelTemplate = document.createElement("template");
|
|
||||||
panelTemplate.innerHTML = `
|
|
||||||
<div id="polygon_panel">
|
|
||||||
<se-spin-input size="3" id="polySides" min=1 step=1 value=5 label="sides">
|
|
||||||
</se-spin-input>
|
|
||||||
</div>
|
|
||||||
`
|
|
||||||
$id('tools_top').appendChild(panelTemplate.content.cloneNode(true));
|
|
||||||
$id("polygon_panel").style.display = 'none';
|
|
||||||
$id("polySides").addEventListener("change", (event) => {
|
|
||||||
setAttr('sides', event.target.value);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
mouseDown (opts) {
|
|
||||||
if (svgCanvas.getMode() !== 'polygon') {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
// const e = opts.event;
|
|
||||||
const rgb = svgCanvas.getColor('fill');
|
|
||||||
// const ccRgbEl = rgb.substring(1, rgb.length);
|
|
||||||
const sRgb = svgCanvas.getColor('stroke');
|
|
||||||
// ccSRgbEl = sRgb.substring(1, rgb.length);
|
|
||||||
const sWidth = svgCanvas.getStrokeWidth();
|
|
||||||
|
|
||||||
started = true;
|
|
||||||
|
|
||||||
newFO = svgCanvas.addSVGElementFromJson({
|
|
||||||
element: 'polygon',
|
|
||||||
attr: {
|
|
||||||
cx: opts.start_x,
|
|
||||||
cy: opts.start_y,
|
|
||||||
id: svgCanvas.getNextId(),
|
|
||||||
shape: 'regularPoly',
|
|
||||||
sides: document.getElementById('polySides').value,
|
|
||||||
orient: 'x',
|
|
||||||
edge: 0,
|
|
||||||
fill: rgb,
|
|
||||||
strokecolor: sRgb,
|
|
||||||
strokeWidth: sWidth
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
started: true
|
|
||||||
};
|
|
||||||
},
|
|
||||||
mouseMove (opts) {
|
|
||||||
if (!started || svgCanvas.getMode() !== 'polygon') {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
const cx = Number(newFO.getAttribute('cx'));
|
|
||||||
const cy = Number(newFO.getAttribute('cy'));
|
|
||||||
const sides = Number(newFO.getAttribute('sides'));
|
|
||||||
// const orient = newFO.getAttribute('orient');
|
|
||||||
const fill = newFO.getAttribute('fill');
|
|
||||||
const strokecolor = newFO.getAttribute('strokecolor');
|
|
||||||
const strokeWidth = Number(newFO.getAttribute('strokeWidth'));
|
|
||||||
|
|
||||||
let x = opts.mouse_x;
|
|
||||||
let y = opts.mouse_y;
|
|
||||||
|
|
||||||
const edg = (Math.sqrt((x - cx) * (x - cx) + (y - cy) * (y - cy))) / 1.5;
|
|
||||||
newFO.setAttribute('edge', edg);
|
|
||||||
|
|
||||||
const inradius = (edg / 2) * cot(Math.PI / sides);
|
|
||||||
const circumradius = inradius * sec(Math.PI / sides);
|
|
||||||
let points = '';
|
|
||||||
for (let s = 0; sides >= s; s++) {
|
|
||||||
const angle = 2.0 * Math.PI * s / sides;
|
|
||||||
x = (circumradius * Math.cos(angle)) + cx;
|
|
||||||
y = (circumradius * Math.sin(angle)) + cy;
|
|
||||||
|
|
||||||
points += x + ',' + y + ' ';
|
|
||||||
}
|
|
||||||
|
|
||||||
// const poly = newFO.createElementNS(NS.SVG, 'polygon');
|
|
||||||
newFO.setAttribute('points', points);
|
|
||||||
newFO.setAttribute('fill', fill);
|
|
||||||
newFO.setAttribute('stroke', strokecolor);
|
|
||||||
newFO.setAttribute('stroke-width', strokeWidth);
|
|
||||||
return {
|
|
||||||
started: true
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
mouseUp () {
|
|
||||||
if (svgCanvas.getMode() !== 'polygon') {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
const edge = newFO.getAttribute('edge');
|
|
||||||
const keep = (edge !== '0');
|
|
||||||
// svgCanvas.addToSelection([newFO], true);
|
|
||||||
return {
|
|
||||||
keep,
|
|
||||||
element: newFO
|
|
||||||
};
|
|
||||||
},
|
|
||||||
selectedChanged (opts) {
|
|
||||||
// Use this to update the current selected elements
|
|
||||||
selElems = opts.elems;
|
|
||||||
|
|
||||||
let i = selElems.length;
|
|
||||||
while (i--) {
|
|
||||||
const elem = selElems[i];
|
|
||||||
if (elem && elem.getAttribute('shape') === 'regularPoly') {
|
|
||||||
if (opts.selectedElement && !opts.multiselected) {
|
|
||||||
$id('polySides').value = elem.getAttribute('sides');
|
|
||||||
|
|
||||||
showPanel(true);
|
|
||||||
} else {
|
|
||||||
showPanel(false);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
showPanel(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
elementChanged () {
|
|
||||||
// const elem = opts.elems[0];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
export default {
|
|
||||||
name: 'polygon',
|
|
||||||
buttons: [
|
|
||||||
{
|
|
||||||
title: 'Polygon Tool'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
contextTools: [
|
|
||||||
{
|
|
||||||
title: 'Number of Sides',
|
|
||||||
label: 'sides'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
export default {
|
|
||||||
name: '多边形',
|
|
||||||
buttons: [
|
|
||||||
{
|
|
||||||
title: '多边形工具'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
contextTools: [
|
|
||||||
{
|
|
||||||
title: '边数',
|
|
||||||
label: '边数'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
360
src/editor/extensions/ext-polystar/ext-polystar.js
Normal file
@@ -0,0 +1,360 @@
|
|||||||
|
/**
|
||||||
|
* @file ext-polystar.js
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @copyright 2010 CloudCanvas, Inc. All rights reserved
|
||||||
|
* @copyright 2021 Optimistik SAS, Inc. All rights reserved
|
||||||
|
* @license MIT
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
const name = "polystar";
|
||||||
|
|
||||||
|
const loadExtensionTranslation = async function (svgEditor) {
|
||||||
|
let translationModule;
|
||||||
|
const lang = svgEditor.configObj.pref('lang');
|
||||||
|
try {
|
||||||
|
// eslint-disable-next-line no-unsanitized/method
|
||||||
|
translationModule = await import(`./locale/${lang}.js`);
|
||||||
|
} catch (_error) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.warn(`Missing translation (${lang}) for ${name} - using 'en'`);
|
||||||
|
// eslint-disable-next-line no-unsanitized/method
|
||||||
|
translationModule = await import(`./locale/en.js`);
|
||||||
|
}
|
||||||
|
svgEditor.i18next.addResourceBundle(lang, name, translationModule.default);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name,
|
||||||
|
async init(_S) {
|
||||||
|
const svgEditor = this;
|
||||||
|
const { svgCanvas } = svgEditor;
|
||||||
|
const { $id } = svgCanvas;
|
||||||
|
let selElems;
|
||||||
|
let started;
|
||||||
|
let newFO;
|
||||||
|
await loadExtensionTranslation(svgEditor);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {boolean} on true=display
|
||||||
|
* @param {string} tool "star" or "polygone"
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
const showPanel = (on, tool) => {
|
||||||
|
$id(`${tool}_panel`).style.display = on ? "block" : "none";
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {string} attr attribute to change
|
||||||
|
* @param {string|Float} val new value
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
const setAttr = (attr, val) => {
|
||||||
|
svgCanvas.changeSelectedAttribute(attr, val);
|
||||||
|
svgCanvas.call("changed", selElems);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Float} n angle
|
||||||
|
* @return {Float} cotangeante
|
||||||
|
*/
|
||||||
|
const cot = (n) => 1 / Math.tan(n);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Float} n angle
|
||||||
|
* @returns {Float} sec
|
||||||
|
*/
|
||||||
|
const sec = (n) => 1 / Math.cos(n);
|
||||||
|
|
||||||
|
return {
|
||||||
|
name: svgEditor.i18next.t(`${name}:name`),
|
||||||
|
// The callback should be used to load the DOM with the appropriate UI items
|
||||||
|
callback() {
|
||||||
|
// Add the button and its handler(s)
|
||||||
|
// Note: the star extension needs to be loaded before the polygon extension
|
||||||
|
const fbtitle = svgEditor.i18next.t(`${name}:title`);
|
||||||
|
const title_star = svgEditor.i18next.t(`${name}:buttons.0.title`);
|
||||||
|
const title_polygon = svgEditor.i18next.t(`${name}:buttons.1.title`);
|
||||||
|
const buttonTemplate = document.createElement("template");
|
||||||
|
// eslint-disable-next-line no-unsanitized/property
|
||||||
|
buttonTemplate.innerHTML = `
|
||||||
|
<se-flyingbutton id="tools_polygon" title="${fbtitle}">
|
||||||
|
<se-button id="tool_star" title="${title_star}" src="./images/star.svg">
|
||||||
|
</se-button>
|
||||||
|
<se-button id="tool_polygon" title="${title_polygon}" src="./images/polygon.svg">
|
||||||
|
</se-button>
|
||||||
|
</se-flyingbutton>
|
||||||
|
`;
|
||||||
|
$id("tools_left").append(buttonTemplate.content.cloneNode(true));
|
||||||
|
// handler
|
||||||
|
$id("tool_star").addEventListener("click", () => {
|
||||||
|
if (this.leftPanel.updateLeftPanel("tool_star")) {
|
||||||
|
svgCanvas.setMode("star");
|
||||||
|
showPanel(true, "star");
|
||||||
|
showPanel(false, "polygon");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$id("tool_polygon").addEventListener("click", () => {
|
||||||
|
if (this.leftPanel.updateLeftPanel("tool_polygon")) {
|
||||||
|
svgCanvas.setMode("polygon");
|
||||||
|
showPanel(true, "polygon");
|
||||||
|
showPanel(false, "star");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const label0 = svgEditor.i18next.t(`${name}:contextTools.0.label`);
|
||||||
|
const title0 = svgEditor.i18next.t(`${name}:contextTools.0.title`);
|
||||||
|
const label1 = svgEditor.i18next.t(`${name}:contextTools.1.label`);
|
||||||
|
const title1 = svgEditor.i18next.t(`${name}:contextTools.1.title`);
|
||||||
|
const label2 = svgEditor.i18next.t(`${name}:contextTools.2.label`);
|
||||||
|
const title2 = svgEditor.i18next.t(`${name}:contextTools.2.title`);
|
||||||
|
const label3 = svgEditor.i18next.t(`${name}:contextTools.3.label`);
|
||||||
|
const title3 = svgEditor.i18next.t(`${name}:contextTools.3.title`);
|
||||||
|
// Add the context panel and its handler(s)
|
||||||
|
const panelTemplate = document.createElement("template");
|
||||||
|
// eslint-disable-next-line no-unsanitized/property
|
||||||
|
panelTemplate.innerHTML = `
|
||||||
|
<div id="star_panel">
|
||||||
|
<se-spin-input id="starNumPoints" label="${label0}" min=1 step=1 value=5 title="${title0}">
|
||||||
|
</se-spin-input>
|
||||||
|
<se-spin-input id="RadiusMultiplier" label="${label1}" min=1 step=2.5 value=3 title="${title1}">
|
||||||
|
</se-spin-input>
|
||||||
|
<se-spin-input id="radialShift" min=0 step=1 value=0 label="${label2}" title="${title2}">
|
||||||
|
</se-spin-input>
|
||||||
|
</div>
|
||||||
|
<div id="polygon_panel">
|
||||||
|
<se-spin-input size="3" id="polySides" min=1 step=1 value=5 label="${label3}" title="${title3}">
|
||||||
|
</se-spin-input>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
//add handlers for the panel
|
||||||
|
$id("tools_top").appendChild(panelTemplate.content.cloneNode(true));
|
||||||
|
// don't display the panels on start
|
||||||
|
showPanel(false, "star");
|
||||||
|
showPanel(false, "polygon");
|
||||||
|
$id("starNumPoints").addEventListener("change", (event) => {
|
||||||
|
setAttr("point", event.target.value);
|
||||||
|
});
|
||||||
|
$id("RadiusMultiplier").addEventListener("change", (event) => {
|
||||||
|
setAttr("starRadiusMultiplier", event.target.value);
|
||||||
|
});
|
||||||
|
$id("radialShift").addEventListener("change", (event) => {
|
||||||
|
setAttr("radialshift", event.target.value);
|
||||||
|
});
|
||||||
|
$id("polySides").addEventListener("change", (event) => {
|
||||||
|
setAttr("sides", event.target.value);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
mouseDown(opts) {
|
||||||
|
if (svgCanvas.getMode() === "star") {
|
||||||
|
const rgb = svgCanvas.getColor("fill");
|
||||||
|
const sRgb = svgCanvas.getColor("stroke");
|
||||||
|
const sWidth = svgCanvas.getStrokeWidth();
|
||||||
|
started = true;
|
||||||
|
newFO = svgCanvas.addSVGElementFromJson({
|
||||||
|
element: "polygon",
|
||||||
|
attr: {
|
||||||
|
cx: opts.start_x,
|
||||||
|
cy: opts.start_y,
|
||||||
|
id: svgCanvas.getNextId(),
|
||||||
|
shape: "star",
|
||||||
|
point: document.getElementById("starNumPoints").value,
|
||||||
|
r: 0,
|
||||||
|
radialshift: document.getElementById("radialShift").value,
|
||||||
|
r2: 0,
|
||||||
|
orient: "point",
|
||||||
|
fill: rgb,
|
||||||
|
strokecolor: sRgb,
|
||||||
|
strokeWidth: sWidth
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
started: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (svgCanvas.getMode() === "polygon") {
|
||||||
|
// const e = opts.event;
|
||||||
|
const rgb = svgCanvas.getColor("fill");
|
||||||
|
// const ccRgbEl = rgb.substring(1, rgb.length);
|
||||||
|
const sRgb = svgCanvas.getColor("stroke");
|
||||||
|
// ccSRgbEl = sRgb.substring(1, rgb.length);
|
||||||
|
const sWidth = svgCanvas.getStrokeWidth();
|
||||||
|
started = true;
|
||||||
|
newFO = svgCanvas.addSVGElementFromJson({
|
||||||
|
element: "polygon",
|
||||||
|
attr: {
|
||||||
|
cx: opts.start_x,
|
||||||
|
cy: opts.start_y,
|
||||||
|
id: svgCanvas.getNextId(),
|
||||||
|
shape: "regularPoly",
|
||||||
|
sides: document.getElementById("polySides").value,
|
||||||
|
orient: "x",
|
||||||
|
edge: 0,
|
||||||
|
fill: rgb,
|
||||||
|
strokecolor: sRgb,
|
||||||
|
strokeWidth: sWidth
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
started: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
},
|
||||||
|
mouseMove(opts) {
|
||||||
|
if (!started) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
if (svgCanvas.getMode() === "star") {
|
||||||
|
const cx = Number(newFO.getAttribute("cx"));
|
||||||
|
const cy = Number(newFO.getAttribute("cy"));
|
||||||
|
const point = Number(newFO.getAttribute("point"));
|
||||||
|
const orient = newFO.getAttribute("orient");
|
||||||
|
const fill = newFO.getAttribute("fill");
|
||||||
|
const strokecolor = newFO.getAttribute("strokecolor");
|
||||||
|
const strokeWidth = Number(newFO.getAttribute("strokeWidth"));
|
||||||
|
const radialshift = Number(newFO.getAttribute("radialshift"));
|
||||||
|
|
||||||
|
let x = opts.mouse_x;
|
||||||
|
let y = opts.mouse_y;
|
||||||
|
|
||||||
|
const circumradius =
|
||||||
|
Math.sqrt((x - cx) * (x - cx) + (y - cy) * (y - cy)) / 1.5;
|
||||||
|
const inradius =
|
||||||
|
circumradius / document.getElementById("RadiusMultiplier").value;
|
||||||
|
newFO.setAttribute("r", circumradius);
|
||||||
|
newFO.setAttribute("r2", inradius);
|
||||||
|
|
||||||
|
let polyPoints = "";
|
||||||
|
for (let s = 0; point >= s; s++) {
|
||||||
|
let angle = 2.0 * Math.PI * (s / point);
|
||||||
|
if (orient === "point") {
|
||||||
|
angle -= Math.PI / 2;
|
||||||
|
} else if (orient === "edge") {
|
||||||
|
angle = angle + Math.PI / point - Math.PI / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
x = circumradius * Math.cos(angle) + cx;
|
||||||
|
y = circumradius * Math.sin(angle) + cy;
|
||||||
|
|
||||||
|
polyPoints += x + "," + y + " ";
|
||||||
|
|
||||||
|
if (!isNaN(inradius)) {
|
||||||
|
angle = 2.0 * Math.PI * (s / point) + Math.PI / point;
|
||||||
|
if (orient === "point") {
|
||||||
|
angle -= Math.PI / 2;
|
||||||
|
} else if (orient === "edge") {
|
||||||
|
angle = angle + Math.PI / point - Math.PI / 2;
|
||||||
|
}
|
||||||
|
angle += radialshift;
|
||||||
|
|
||||||
|
x = inradius * Math.cos(angle) + cx;
|
||||||
|
y = inradius * Math.sin(angle) + cy;
|
||||||
|
|
||||||
|
polyPoints += x + "," + y + " ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
newFO.setAttribute("points", polyPoints);
|
||||||
|
newFO.setAttribute("fill", fill);
|
||||||
|
newFO.setAttribute("stroke", strokecolor);
|
||||||
|
newFO.setAttribute("stroke-width", strokeWidth);
|
||||||
|
/* const shape = */ newFO.getAttribute("shape");
|
||||||
|
|
||||||
|
return {
|
||||||
|
started: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (svgCanvas.getMode() === "polygon") {
|
||||||
|
const cx = Number(newFO.getAttribute("cx"));
|
||||||
|
const cy = Number(newFO.getAttribute("cy"));
|
||||||
|
const sides = Number(newFO.getAttribute("sides"));
|
||||||
|
// const orient = newFO.getAttribute('orient');
|
||||||
|
const fill = newFO.getAttribute("fill");
|
||||||
|
const strokecolor = newFO.getAttribute("strokecolor");
|
||||||
|
const strokeWidth = Number(newFO.getAttribute("strokeWidth"));
|
||||||
|
|
||||||
|
let x = opts.mouse_x;
|
||||||
|
let y = opts.mouse_y;
|
||||||
|
|
||||||
|
const edg =
|
||||||
|
Math.sqrt((x - cx) * (x - cx) + (y - cy) * (y - cy)) / 1.5;
|
||||||
|
newFO.setAttribute("edge", edg);
|
||||||
|
|
||||||
|
const inradius = (edg / 2) * cot(Math.PI / sides);
|
||||||
|
const circumradius = inradius * sec(Math.PI / sides);
|
||||||
|
let points = "";
|
||||||
|
for (let s = 0; sides >= s; s++) {
|
||||||
|
const angle = (2.0 * Math.PI * s) / sides;
|
||||||
|
x = circumradius * Math.cos(angle) + cx;
|
||||||
|
y = circumradius * Math.sin(angle) + cy;
|
||||||
|
|
||||||
|
points += x + "," + y + " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
// const poly = newFO.createElementNS(NS.SVG, 'polygon');
|
||||||
|
newFO.setAttribute("points", points);
|
||||||
|
newFO.setAttribute("fill", fill);
|
||||||
|
newFO.setAttribute("stroke", strokecolor);
|
||||||
|
newFO.setAttribute("stroke-width", strokeWidth);
|
||||||
|
return {
|
||||||
|
started: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
},
|
||||||
|
mouseUp() {
|
||||||
|
if (svgCanvas.getMode() === "star") {
|
||||||
|
const r = newFO.getAttribute("r");
|
||||||
|
return {
|
||||||
|
keep: r !== "0",
|
||||||
|
element: newFO
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (svgCanvas.getMode() === "polygon") {
|
||||||
|
const edge = newFO.getAttribute("edge");
|
||||||
|
const keep = edge !== "0";
|
||||||
|
// svgCanvas.addToSelection([newFO], true);
|
||||||
|
return {
|
||||||
|
keep,
|
||||||
|
element: newFO
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
},
|
||||||
|
selectedChanged(opts) {
|
||||||
|
// Use this to update the current selected elements
|
||||||
|
selElems = opts.elems;
|
||||||
|
|
||||||
|
let i = selElems.length;
|
||||||
|
while (i--) {
|
||||||
|
const elem = selElems[i];
|
||||||
|
if (elem && elem.getAttribute("shape") === "star") {
|
||||||
|
if (opts.selectedElement && !opts.multiselected) {
|
||||||
|
$id("starNumPoints").value = elem.getAttribute("point");
|
||||||
|
$id("radialShift").value = elem.getAttribute("radialshift");
|
||||||
|
showPanel(true, "star");
|
||||||
|
} else {
|
||||||
|
showPanel(false, "star");
|
||||||
|
}
|
||||||
|
} else if (elem && elem.getAttribute("shape") === "regularPoly") {
|
||||||
|
if (opts.selectedElement && !opts.multiselected) {
|
||||||
|
$id("polySides").value = elem.getAttribute("sides");
|
||||||
|
showPanel(true, "polygon");
|
||||||
|
} else {
|
||||||
|
showPanel(false, "polygon");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
showPanel(false, "star");
|
||||||
|
showPanel(false, "polygon");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
elementChanged(_opts) {
|
||||||
|
// const elem = opts.elems[0];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -1,8 +1,12 @@
|
|||||||
export default {
|
export default {
|
||||||
name: 'star',
|
name: 'star',
|
||||||
|
title: 'Polygone/Star Tool',
|
||||||
buttons: [
|
buttons: [
|
||||||
{
|
{
|
||||||
title: 'Star Tool'
|
title: 'Star Tool'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Polygon Tool'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
contextTools: [
|
contextTools: [
|
||||||
@@ -17,6 +21,10 @@ export default {
|
|||||||
{
|
{
|
||||||
title: 'Twists the star',
|
title: 'Twists the star',
|
||||||
label: 'Radial Shift'
|
label: 'Radial Shift'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Number of Sides',
|
||||||
|
label: 'sides'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
30
src/editor/extensions/ext-polystar/locale/fr.js
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
export default {
|
||||||
|
name: 'etoile',
|
||||||
|
title: 'Outil Polygone/Etoile',
|
||||||
|
buttons: [
|
||||||
|
{
|
||||||
|
title: 'Outil Etoile'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Outil Polygone'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
contextTools: [
|
||||||
|
{
|
||||||
|
title: 'Nombre de côtés',
|
||||||
|
label: 'points'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Précision',
|
||||||
|
label: 'Précision'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Torsion Etoile',
|
||||||
|
label: 'Décalage Radial'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Nombre de côtés',
|
||||||
|
label: 'côtés'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
@@ -1,8 +1,12 @@
|
|||||||
export default {
|
export default {
|
||||||
name: '星形',
|
name: '星形',
|
||||||
|
title: 'Polygone/Star Tool',
|
||||||
buttons: [
|
buttons: [
|
||||||
{
|
{
|
||||||
title: '星形工具'
|
title: '星形工具'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '多边形工具'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
contextTools: [
|
contextTools: [
|
||||||
@@ -17,6 +21,10 @@ export default {
|
|||||||
{
|
{
|
||||||
title: '径向',
|
title: '径向',
|
||||||
label: '径向'
|
label: '径向'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '边数',
|
||||||
|
label: '边数'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
@@ -96,7 +96,8 @@ export default {
|
|||||||
|
|
||||||
svgEditor.setCustomHandlers({
|
svgEditor.setCustomHandlers({
|
||||||
save (win, data) {
|
save (win, data) {
|
||||||
const svg = '<?xml version="1.0" encoding="UTF-8"?>\n' + data, // Firefox doesn't seem to know it is UTF-8 (no matter whether we use or skip the clientDownload code) despite the Content-Disposition header containing UTF-8, but adding the encoding works
|
// Firefox doesn't seem to know it is UTF-8 (no matter whether we use or skip the clientDownload code) despite the Content-Disposition header containing UTF-8, but adding the encoding works
|
||||||
|
const svg = '<?xml version="1.0" encoding="UTF-8"?>\n' + data,
|
||||||
filename = getFileNameFromTitle();
|
filename = getFileNameFromTitle();
|
||||||
|
|
||||||
if (clientDownloadSupport(filename, '.svg', 'data:image/svg+xml;charset=UTF-8;base64,' + encode64(svg))) {
|
if (clientDownloadSupport(filename, '.svg', 'data:image/svg+xml;charset=UTF-8;base64,' + encode64(svg))) {
|
||||||
@@ -148,7 +149,6 @@ export default {
|
|||||||
c.style.height = svgCanvas.contentH;
|
c.style.height = svgCanvas.contentH;
|
||||||
await canvg(c, data.svg);
|
await canvg(c, data.svg);
|
||||||
const datauri = quality ? c.toDataURL(mimeType, quality) : c.toDataURL(mimeType);
|
const datauri = quality ? c.toDataURL(mimeType, quality) : c.toDataURL(mimeType);
|
||||||
// {uiStrings} = svgEditor;
|
|
||||||
|
|
||||||
// Check if there are issues
|
// Check if there are issues
|
||||||
let pre, note = '';
|
let pre, note = '';
|
||||||
@@ -228,7 +228,6 @@ export default {
|
|||||||
openSvgForm.method = 'post';
|
openSvgForm.method = 'post';
|
||||||
openSvgForm.target = 'output_frame';
|
openSvgForm.target = 'output_frame';
|
||||||
|
|
||||||
|
|
||||||
// Create import form
|
// Create import form
|
||||||
const importSvgForm = openSvgForm.cloneNode(true);
|
const importSvgForm = openSvgForm.cloneNode(true);
|
||||||
importSvgForm.action = importSvgAction;
|
importSvgForm.action = importSvgAction;
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ export default {
|
|||||||
buttonTemplate.innerHTML = `
|
buttonTemplate.innerHTML = `
|
||||||
<se-explorerbutton id="tool_shapelib" title="Shape library" lib="./extensions/ext-shapes/shapelib/"
|
<se-explorerbutton id="tool_shapelib" title="Shape library" lib="./extensions/ext-shapes/shapelib/"
|
||||||
src="./images/shapelib.svg"></se-explorerbutton>
|
src="./images/shapelib.svg"></se-explorerbutton>
|
||||||
`
|
`;
|
||||||
$id('tools_left').append(buttonTemplate.content.cloneNode(true));
|
$id('tools_left').append(buttonTemplate.content.cloneNode(true));
|
||||||
$id('tool_shapelib').addEventListener("click", () => {
|
$id('tool_shapelib').addEventListener("click", () => {
|
||||||
canv.setMode(modeId);
|
canv.setMode(modeId);
|
||||||
|
|||||||
@@ -1,231 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file ext-star.js
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @copyright 2010 CloudCanvas, Inc. All rights reserved
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
const loadExtensionTranslation = async function (lang) {
|
|
||||||
let translationModule;
|
|
||||||
try {
|
|
||||||
// eslint-disable-next-line no-unsanitized/method
|
|
||||||
translationModule = await import(`./locale/${encodeURIComponent(lang)}.js`);
|
|
||||||
} catch (_error) {
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.error(`Missing translation (${lang}) - using 'en'`);
|
|
||||||
translationModule = await import(`./locale/en.js`);
|
|
||||||
}
|
|
||||||
return translationModule.default;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'star',
|
|
||||||
async init (_S) {
|
|
||||||
const svgEditor = this;
|
|
||||||
const {svgCanvas} = svgEditor;
|
|
||||||
const {$id} = svgCanvas;
|
|
||||||
let selElems;
|
|
||||||
let started;
|
|
||||||
let newFO;
|
|
||||||
const strings = await loadExtensionTranslation(svgEditor.configObj.pref('lang'));
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param {boolean} on
|
|
||||||
* @returns {void}
|
|
||||||
*/
|
|
||||||
const showPanel = (on) => {
|
|
||||||
$id('star_panel').style.display = (on) ? 'block' : 'none';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param {string} attr
|
|
||||||
* @param {string|Float} val
|
|
||||||
* @returns {void}
|
|
||||||
*/
|
|
||||||
const setAttr = (attr, val) => {
|
|
||||||
svgCanvas.changeSelectedAttribute(attr, val);
|
|
||||||
svgCanvas.call('changed', selElems);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
name: strings.name,
|
|
||||||
// The callback should be used to load the DOM with the appropriate UI items
|
|
||||||
callback () {
|
|
||||||
// Add the button and its handler(s)
|
|
||||||
// Note: the star extension may also add the same flying button so we check first
|
|
||||||
if ($id('tools_polygon') === null) {
|
|
||||||
const buttonTemplate = document.createElement("template");
|
|
||||||
buttonTemplate.innerHTML = `
|
|
||||||
<se-flyingbutton id="tools_polygon" title="Polygone/Star Tool">
|
|
||||||
<se-button id="tool_polygon" title="Polygon Tool" src="./images/polygon.svg"></se-button>
|
|
||||||
<se-button id="tool_star" title="Star Tool" src="./images/star.svg"></se-button>
|
|
||||||
</se-flyingbutton>
|
|
||||||
`
|
|
||||||
$id('tools_left').append(buttonTemplate.content.cloneNode(true));
|
|
||||||
}
|
|
||||||
$id('tool_star').addEventListener("click", () => { showPanel(true);
|
|
||||||
if (this.leftPanel.updateLeftPanel('tool_polygon')) {
|
|
||||||
svgCanvas.setMode('star');
|
|
||||||
showPanel(true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Add the context panel and its handler(s)
|
|
||||||
const panelTemplate = document.createElement("template");
|
|
||||||
panelTemplate.innerHTML = `
|
|
||||||
<div id="star_panel">
|
|
||||||
<se-spin-input id="starNumPoints" label="points" min=1 step=1 value=5 title="Change rotation angle">
|
|
||||||
</se-spin-input>
|
|
||||||
<se-spin-input id="RadiusMultiplier" label="Radis multiplier" min=1 step=2.5 value=5 title="Change rotation angle">
|
|
||||||
</se-spin-input>
|
|
||||||
<se-spin-input id="radialShift" min=0 step=1 value=0 label="radial shift" title="Change rotation angle">
|
|
||||||
</se-spin-input>
|
|
||||||
</div>
|
|
||||||
`
|
|
||||||
//add handlers for the panel
|
|
||||||
$id('tools_top').appendChild(panelTemplate.content.cloneNode(true));
|
|
||||||
$id("starNumPoints").addEventListener("change", (event) => {
|
|
||||||
setAttr('point', event.target.value);
|
|
||||||
});
|
|
||||||
$id("RadiusMultiplier").addEventListener("change", (event) => {
|
|
||||||
setAttr('starRadiusMultiplier', event.target.value);
|
|
||||||
});
|
|
||||||
$id("radialShift").addEventListener("change", (event) => {
|
|
||||||
setAttr('radialshift', event.target.value);
|
|
||||||
});
|
|
||||||
// don't display the star panel on start
|
|
||||||
$id("star_panel").style.display = 'none';
|
|
||||||
},
|
|
||||||
mouseDown (opts) {
|
|
||||||
const rgb = svgCanvas.getColor('fill');
|
|
||||||
const sRgb = svgCanvas.getColor('stroke');
|
|
||||||
const sWidth = svgCanvas.getStrokeWidth();
|
|
||||||
|
|
||||||
if (svgCanvas.getMode() === 'star') {
|
|
||||||
started = true;
|
|
||||||
|
|
||||||
newFO = svgCanvas.addSVGElementFromJson({
|
|
||||||
element: 'polygon',
|
|
||||||
attr: {
|
|
||||||
cx: opts.start_x,
|
|
||||||
cy: opts.start_y,
|
|
||||||
id: svgCanvas.getNextId(),
|
|
||||||
shape: 'star',
|
|
||||||
point: document.getElementById('starNumPoints').value,
|
|
||||||
r: 0,
|
|
||||||
radialshift: document.getElementById('radialShift').value,
|
|
||||||
r2: 0,
|
|
||||||
orient: 'point',
|
|
||||||
fill: rgb,
|
|
||||||
strokecolor: sRgb,
|
|
||||||
strokeWidth: sWidth
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return {
|
|
||||||
started: true
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
},
|
|
||||||
mouseMove (opts) {
|
|
||||||
if (!started) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
if (svgCanvas.getMode() === 'star') {
|
|
||||||
const cx = Number(newFO.getAttribute('cx'));
|
|
||||||
const cy = Number(newFO.getAttribute('cy'));
|
|
||||||
const point = Number(newFO.getAttribute('point'));
|
|
||||||
const orient = newFO.getAttribute('orient');
|
|
||||||
const fill = newFO.getAttribute('fill');
|
|
||||||
const strokecolor = newFO.getAttribute('strokecolor');
|
|
||||||
const strokeWidth = Number(newFO.getAttribute('strokeWidth'));
|
|
||||||
const radialshift = Number(newFO.getAttribute('radialshift'));
|
|
||||||
|
|
||||||
let x = opts.mouse_x;
|
|
||||||
let y = opts.mouse_y;
|
|
||||||
|
|
||||||
const circumradius = (Math.sqrt((x - cx) * (x - cx) + (y - cy) * (y - cy))) / 1.5;
|
|
||||||
const inradius = circumradius / document.getElementById('RadiusMultiplier').value;
|
|
||||||
newFO.setAttribute('r', circumradius);
|
|
||||||
newFO.setAttribute('r2', inradius);
|
|
||||||
|
|
||||||
let polyPoints = '';
|
|
||||||
for (let s = 0; point >= s; s++) {
|
|
||||||
let angle = 2.0 * Math.PI * (s / point);
|
|
||||||
if (orient === 'point') {
|
|
||||||
angle -= (Math.PI / 2);
|
|
||||||
} else if (orient === 'edge') {
|
|
||||||
angle = (angle + (Math.PI / point)) - (Math.PI / 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
x = (circumradius * Math.cos(angle)) + cx;
|
|
||||||
y = (circumradius * Math.sin(angle)) + cy;
|
|
||||||
|
|
||||||
polyPoints += x + ',' + y + ' ';
|
|
||||||
|
|
||||||
if (!isNaN(inradius)) {
|
|
||||||
angle = (2.0 * Math.PI * (s / point)) + (Math.PI / point);
|
|
||||||
if (orient === 'point') {
|
|
||||||
angle -= (Math.PI / 2);
|
|
||||||
} else if (orient === 'edge') {
|
|
||||||
angle = (angle + (Math.PI / point)) - (Math.PI / 2);
|
|
||||||
}
|
|
||||||
angle += radialshift;
|
|
||||||
|
|
||||||
x = (inradius * Math.cos(angle)) + cx;
|
|
||||||
y = (inradius * Math.sin(angle)) + cy;
|
|
||||||
|
|
||||||
polyPoints += x + ',' + y + ' ';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
newFO.setAttribute('points', polyPoints);
|
|
||||||
newFO.setAttribute('fill', fill);
|
|
||||||
newFO.setAttribute('stroke', strokecolor);
|
|
||||||
newFO.setAttribute('stroke-width', strokeWidth);
|
|
||||||
/* const shape = */ newFO.getAttribute('shape');
|
|
||||||
|
|
||||||
return {
|
|
||||||
started: true
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
},
|
|
||||||
mouseUp () {
|
|
||||||
if (svgCanvas.getMode() === 'star') {
|
|
||||||
const r = newFO.getAttribute('r');
|
|
||||||
return {
|
|
||||||
keep: (r !== '0'),
|
|
||||||
element: newFO
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
},
|
|
||||||
selectedChanged (opts) {
|
|
||||||
// Use this to update the current selected elements
|
|
||||||
selElems = opts.elems;
|
|
||||||
|
|
||||||
let i = selElems.length;
|
|
||||||
while (i--) {
|
|
||||||
const elem = selElems[i];
|
|
||||||
if (elem && elem.getAttribute('shape') === 'star') {
|
|
||||||
if (opts.selectedElement && !opts.multiselected) {
|
|
||||||
$id('starNumPoints').value = elem.getAttribute('point');
|
|
||||||
$id('radialShift').value = elem.getAttribute('radialshift');
|
|
||||||
showPanel(true);
|
|
||||||
} else {
|
|
||||||
showPanel(false);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
showPanel(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
elementChanged (_opts) {
|
|
||||||
// const elem = opts.elems[0];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
/* eslint-disable max-len */
|
/* eslint-disable max-len */
|
||||||
import 'elix/define/Dialog.js';
|
|
||||||
|
|
||||||
const template = document.createElement('template');
|
const template = document.createElement('template');
|
||||||
template.innerHTML = `
|
template.innerHTML = `
|
||||||
@@ -10,7 +9,7 @@ template.innerHTML = `
|
|||||||
background: #DDD;
|
background: #DDD;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
border: 1px solid #B0B0B0;
|
border: 1px solid #5a6162;
|
||||||
}
|
}
|
||||||
|
|
||||||
#dialog_content p, #dialog_content select, #dialog_content label {
|
#dialog_content p, #dialog_content select, #dialog_content label {
|
||||||
@@ -25,7 +24,7 @@ template.innerHTML = `
|
|||||||
top: 50%;
|
top: 50%;
|
||||||
max-width: 400px;
|
max-width: 400px;
|
||||||
z-index: 50001;
|
z-index: 50001;
|
||||||
background: #CCC;
|
background: #5a6162;
|
||||||
border: 1px outset #777;
|
border: 1px outset #777;
|
||||||
font-family:Verdana,Helvetica,sans-serif;
|
font-family:Verdana,Helvetica,sans-serif;
|
||||||
font-size:0.8em;
|
font-size:0.8em;
|
||||||
|
|||||||
@@ -32,21 +32,18 @@ export default {
|
|||||||
this.canvas.bind(
|
this.canvas.bind(
|
||||||
'message',
|
'message',
|
||||||
/**
|
/**
|
||||||
* @param {external:Window} win
|
*
|
||||||
* @param {PlainObject} info
|
* @param {external:Window} win external Window handler
|
||||||
* @param {module:svgcanvas.SvgCanvas#event:message} info.data
|
* @param {*} param1 info
|
||||||
* @param {string} info.origin
|
|
||||||
* @listens module:svgcanvas.SvgCanvas#event:message
|
|
||||||
* @throws {Error} Unexpected event type
|
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
(win, { data, origin }) => {
|
(win, { data, origin }) => {
|
||||||
// console.log('data, origin', data, origin);
|
|
||||||
let type, content;
|
let type, content;
|
||||||
try {
|
try {
|
||||||
({ type, pathID, content } = data.webappfind); // May throw if data is not an object
|
({ type, pathID, content } = data.webappfind); // May throw if data is not an object
|
||||||
if (origin !== location.origin || // We are only interested in a message sent as though within this URL by our browser add-on
|
if (origin !== location.origin || // We are only interested in a message sent as though within this URL by our browser add-on
|
||||||
excludedMessages.includes(type) // Avoid our post below (other messages might be possible in the future which may also need to be excluded if your subsequent code makes assumptions on the type of message this is)
|
// Avoid our post below (other msgs might be possible which may need to be excluded if code makes assumptions on the type of message)
|
||||||
|
excludedMessages.includes(type)
|
||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 637 B |
|
Before Width: | Height: | Size: 474 B |
11
src/editor/images/hello_world.svg
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
|
||||||
|
<svg width="102" height="102" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<!-- Created with SVG-edit - https://github.com/SVG-Edit/svgedit -->
|
||||||
|
<g>
|
||||||
|
<title>Layer 1</title>
|
||||||
|
<rect ry="30" rx="30" x="2.5" y="2.5" width="97" height="97" id="svg_3" fill="#008000" stroke="#000000" stroke-width="5"/>
|
||||||
|
<text x="52.668" y="42.5" id="svg_1" fill="#ffffff" stroke="#000000" stroke-width="0" font-size="24" font-family="Monospace" text-anchor="middle" xml:space="preserve">Hello</text>
|
||||||
|
<text x="52.668" y="71.5" fill="#ffffff" stroke="#000000" stroke-width="0" font-size="24" font-family="Monospace" text-anchor="middle" xml:space="preserve" id="svg_2">World!</text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
After Width: | Height: | Size: 725 B |
@@ -1,21 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<!--
|
|
||||||
Sample icons file. This file looks like an SVG file with groups as its
|
|
||||||
children. Each group element has an ID that must match the ID of the button given
|
|
||||||
in the extension. The SVG inside the group makes up the actual icon, and
|
|
||||||
needs use a viewBox instead of width/height for it to scale properly.
|
|
||||||
|
|
||||||
Multiple icons can be included, each within their own group.
|
|
||||||
-->
|
|
||||||
<g id="hello_world">
|
|
||||||
<svg width="102" height="102" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
||||||
<!-- Created with SVG-edit - https://github.com/SVG-Edit/svgedit -->
|
|
||||||
<g>
|
|
||||||
<title>Layer 1</title>
|
|
||||||
<rect ry="30" rx="30" x="2.5" y="2.5" width="97" height="97" id="svg_3" fill="#008000" stroke="#000000" stroke-width="5"/>
|
|
||||||
<text x="52.668" y="42.5" id="svg_1" fill="#ffffff" stroke="#000000" stroke-width="0" font-size="24" font-family="Monospace" text-anchor="middle" xml:space="preserve">Hello</text>
|
|
||||||
<text x="52.668" y="71.5" fill="#ffffff" stroke="#000000" stroke-width="0" font-size="24" font-family="Monospace" text-anchor="middle" xml:space="preserve" id="svg_2">World!</text>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.2 KiB |
@@ -1,110 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<!-- Created with SVG-edit - https://github.com/SVG-Edit/svgedit -->
|
|
||||||
<g id="nomarker">
|
|
||||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path stroke-width="10" stroke="#f9bc01" fill="#f9bc01" d="m-50,0l100,0"/>
|
|
||||||
</svg>
|
|
||||||
</g>
|
|
||||||
<g id="leftarrow">
|
|
||||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path stroke-width="10" stroke="#f9bc01" fill="#f9bc01" d="m-50,0l100,40l-30,-40l30,-40z"/>
|
|
||||||
</svg>
|
|
||||||
</g>
|
|
||||||
<g id="rightarrow">
|
|
||||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path stroke-width="10" stroke="#f9bc01" fill="#f9bc01" d="m50,0l-100,40l30,-40l-30,-40z"/>
|
|
||||||
</svg>
|
|
||||||
</g>
|
|
||||||
<g id="leftarrow_o">
|
|
||||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path stroke-width="10" stroke="#f9bc01" fill="none" d="m-50,0l100,40l-30,-40l30,-40z"/>
|
|
||||||
</svg>
|
|
||||||
</g>
|
|
||||||
<g id="rightarrow_o">
|
|
||||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path stroke-width="10" stroke="#f9bc01" fill="none" d="m50,0l-100,40l30,-40l-30,-40z"/>
|
|
||||||
</svg>
|
|
||||||
</g>
|
|
||||||
<g id="forwardslash">
|
|
||||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path stroke-width="10" stroke="#f9bc01" fill="none" d="m-20,50l40,-100"/>
|
|
||||||
</svg>
|
|
||||||
</g>
|
|
||||||
<g id="reverseslash">
|
|
||||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path stroke-width="10" stroke="#f9bc01" fill="none" d="m-20,-50l40,100"/>
|
|
||||||
</svg>
|
|
||||||
</g>
|
|
||||||
<g id="verticalslash">
|
|
||||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path stroke-width="10" stroke="#f9bc01" fill="none" d="m0,-50l0,100"/>
|
|
||||||
</svg>
|
|
||||||
</g>
|
|
||||||
<g id="mcircle">
|
|
||||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<circle stroke-width="10" stroke="#f9bc01" fill="#f9bc01" cy="0" cx="0" r="30"/>
|
|
||||||
</svg>
|
|
||||||
</g>
|
|
||||||
<g id="mcircle_o">
|
|
||||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<circle stroke-width="10" stroke="#f9bc01" fill="none" cy="0" cx="0" r="30"/>
|
|
||||||
</svg>
|
|
||||||
</g>
|
|
||||||
<g id="xmark">
|
|
||||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path stroke-width="10" stroke="#f9bc01" fill="#f9bc01" d="m-30,30l60,-60m0,60l-60,-60"/>
|
|
||||||
</svg>
|
|
||||||
</g>
|
|
||||||
<g id="box">
|
|
||||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path stroke-width="10" stroke="#f9bc01" fill="#f9bc01" d="m-30,-30l0,60l60,0l0,-60z"/>
|
|
||||||
</svg>
|
|
||||||
</g>
|
|
||||||
<g id="box_o">
|
|
||||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path stroke-width="10" stroke="#f9bc01" fill="none" d="m-30,-30l0,60l60,0l0,-60z"/>
|
|
||||||
</svg>
|
|
||||||
</g>
|
|
||||||
<g id="star_o">
|
|
||||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path stroke-width="10" stroke="#f9bc01" fill="none" d="m-40,-20l80,0l-70,60l30,-80l30,80z"/>
|
|
||||||
</svg>
|
|
||||||
</g>
|
|
||||||
<g id="triangle_o">
|
|
||||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path stroke-width="10" stroke="#f9bc01" fill="none" d="M-30,30 L0,-30 L30,30 Z"/>
|
|
||||||
</svg>
|
|
||||||
</g>
|
|
||||||
<g id="triangle">
|
|
||||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path stroke-width="10" stroke="#f9bc01" fill="#f9bc01" d="M-30,30 L0,-30 L30,30 Z"/>
|
|
||||||
</svg>
|
|
||||||
</g>
|
|
||||||
<g id="textmarker">
|
|
||||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<text xml:space="preserve" text-anchor="middle" font-family="serif" font-size="120" y="40" x="0" stroke-width="0" stroke="#f9bc01" fill="#f9bc01">T</text>
|
|
||||||
</svg>
|
|
||||||
</g>
|
|
||||||
<g id="mkr_markers_off">
|
|
||||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<line y2="0" x2="50" y1="0" x1="-50" stroke-width="5" stroke="#f9bc01" fill="none"/>
|
|
||||||
</svg>
|
|
||||||
</g>
|
|
||||||
<g id="mkr_markers_dimension">
|
|
||||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<line y2="0" x2="40" y1="0" x1="20" stroke-width="5" stroke="#f9bc01" fill="none"/>
|
|
||||||
<line y2="0" x2="-40" y1="0" x1="-20" stroke-width="5" stroke="#f9bc01" fill="none"/>
|
|
||||||
<text text-anchor="middle" font-family="serif" font-size="80" y="20" x="0" stroke-width="0" stroke="#f9bc01" fill="#f9bc01">T</text>
|
|
||||||
<path stroke-width="5" stroke="#f9bc01" fill="#f9bc01" d="M-50,0 L-30,-15 L-30,15 Z"/>
|
|
||||||
<path stroke-width="5" stroke="#f9bc01" fill="#f9bc01" d="M50,0 L30,-15 L30,15 Z"/>
|
|
||||||
</svg>
|
|
||||||
</g>
|
|
||||||
<g id="mkr_markers_label">
|
|
||||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<line y2="0" x2="40" y1="0" x1="-20" stroke-width="5" stroke="#f9bc01" fill="none"/>
|
|
||||||
<text text-anchor="middle" font-family="serif" font-size="80" y="20" x="-40" stroke-width="0" stroke="#f9bc01" fill="#f9bc01">T</text>
|
|
||||||
<path stroke-width="5" stroke="#f9bc01" fill="#f9bc01" d="M50,0 L30,-15 L30,15 Z"/>
|
|
||||||
</svg>
|
|
||||||
</g>
|
|
||||||
<g id="svg_eof"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 5.1 KiB |
7
src/editor/images/mkr_markers_dimension.svg
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<line y2="0" x2="40" y1="0" x1="20" stroke-width="5" stroke="#f9bc01" fill="none"/>
|
||||||
|
<line y2="0" x2="-40" y1="0" x1="-20" stroke-width="5" stroke="#f9bc01" fill="none"/>
|
||||||
|
<text text-anchor="middle" font-family="serif" font-size="80" y="20" x="0" stroke-width="0" stroke="#f9bc01" fill="#f9bc01">T</text>
|
||||||
|
<path stroke-width="5" stroke="#f9bc01" fill="#f9bc01" d="M-50,0 L-30,-15 L-30,15 Z"/>
|
||||||
|
<path stroke-width="5" stroke="#f9bc01" fill="#f9bc01" d="M50,0 L30,-15 L30,15 Z"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 598 B |
5
src/editor/images/mkr_markers_label.svg
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<line y2="0" x2="40" y1="0" x1="-20" stroke-width="5" stroke="#f9bc01" fill="none"/>
|
||||||
|
<text text-anchor="middle" font-family="serif" font-size="80" y="20" x="-40" stroke-width="0" stroke="#f9bc01" fill="#f9bc01">T</text>
|
||||||
|
<path stroke-width="5" stroke="#f9bc01" fill="#f9bc01" d="M50,0 L30,-15 L30,15 Z"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 390 B |
3
src/editor/images/mkr_markers_off.svg
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<line y2="0" x2="50" y1="0" x1="-50" stroke-width="5" stroke="#f9bc01" fill="none"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 162 B |
@@ -1,138 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<!-- Created with SVG-edit - https://github.com/SVG-Edit/svgedit -->
|
|
||||||
<g id="nomarker">
|
|
||||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path stroke-width="10" stroke="#f9bc01" fill="#f9bc01" d="m-50,0l100,0"/>
|
|
||||||
</svg>
|
|
||||||
</g>
|
|
||||||
<g id="leftarrow">
|
|
||||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path stroke-width="10" stroke="#f9bc01" fill="#f9bc01" d="m-50,0l100,40l-30,-40l30,-40z"/>
|
|
||||||
</svg>
|
|
||||||
</g>
|
|
||||||
<g id="rightarrow">
|
|
||||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path stroke-width="10" stroke="#f9bc01" fill="#f9bc01" d="m50,0l-100,40l30,-40l-30,-40z"/>
|
|
||||||
</svg>
|
|
||||||
</g>
|
|
||||||
<g id="leftarrow_o">
|
|
||||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path stroke-width="10" stroke="#f9bc01" fill="none" d="m-50,0l100,40l-30,-40l30,-40z"/>
|
|
||||||
</svg>
|
|
||||||
</g>
|
|
||||||
<g id="rightarrow_o">
|
|
||||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path stroke-width="10" stroke="#f9bc01" fill="none" d="m50,0l-100,40l30,-40l-30,-40z"/>
|
|
||||||
</svg>
|
|
||||||
</g>
|
|
||||||
<g id="forwardslash">
|
|
||||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path stroke-width="10" stroke="#f9bc01" fill="none" d="m-20,50l40,-100"/>
|
|
||||||
</svg>
|
|
||||||
</g>
|
|
||||||
<g id="reverseslash">
|
|
||||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path stroke-width="10" stroke="#f9bc01" fill="none" d="m-20,-50l40,100"/>
|
|
||||||
</svg>
|
|
||||||
</g>
|
|
||||||
<g id="verticalslash">
|
|
||||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path stroke-width="10" stroke="#f9bc01" fill="none" d="m0,-50l0,100"/>
|
|
||||||
</svg>
|
|
||||||
</g>
|
|
||||||
<g id="mcircle">
|
|
||||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<circle stroke-width="10" stroke="#f9bc01" fill="#f9bc01" cy="0" cx="0" r="30"/>
|
|
||||||
</svg>
|
|
||||||
</g>
|
|
||||||
<g id="mcircle_o">
|
|
||||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<circle stroke-width="10" stroke="#f9bc01" fill="none" cy="0" cx="0" r="30"/>
|
|
||||||
</svg>
|
|
||||||
</g>
|
|
||||||
<g id="xmark">
|
|
||||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path stroke-width="10" stroke="#f9bc01" fill="#f9bc01" d="m-30,30l60,-60m0,60l-60,-60"/>
|
|
||||||
</svg>
|
|
||||||
</g>
|
|
||||||
<g id="box">
|
|
||||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path stroke-width="10" stroke="#f9bc01" fill="#f9bc01" d="m-30,-30l0,60l60,0l0,-60z"/>
|
|
||||||
</svg>
|
|
||||||
</g>
|
|
||||||
<g id="star">
|
|
||||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path stroke-width="10" stroke="#f9bc01" fill="#f9bc01" d="m-40,-20l80,0l-70,60l30,-80l30,80z"/>
|
|
||||||
</svg>
|
|
||||||
</g>
|
|
||||||
<g id="box_o">
|
|
||||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path stroke-width="10" stroke="#f9bc01" fill="none" d="m-30,-30l0,60l60,0l0,-60z"/>
|
|
||||||
</svg>
|
|
||||||
</g>
|
|
||||||
<g id="star_o">
|
|
||||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path stroke-width="10" stroke="#f9bc01" fill="none" d="m-40,-20l80,0l-70,60l30,-80l30,80z"/>
|
|
||||||
</svg>
|
|
||||||
</g>
|
|
||||||
<g id="triangle_o">
|
|
||||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path stroke-width="10" stroke="#f9bc01" fill="none" d="M-30,30 L0,-30 L30,30 Z"/>
|
|
||||||
</svg>
|
|
||||||
</g>
|
|
||||||
<g id="triangle">
|
|
||||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path stroke-width="10" stroke="#f9bc01" fill="#f9bc01" d="M-30,30 L0,-30 L30,30 Z"/>
|
|
||||||
</svg>
|
|
||||||
</g>
|
|
||||||
<g id="textmarker">
|
|
||||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<text xml:space="preserve" text-anchor="middle" font-family="serif" font-size="120" y="40" x="0" stroke-width="0" stroke="#f9bc01" fill="#f9bc01">T</text>
|
|
||||||
</svg>
|
|
||||||
</g>
|
|
||||||
<g id="textmarker_top">
|
|
||||||
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path stroke-width="4" stroke="#f9bc01" fill="none" d="M 0 60 h 100 z M 30 30 h 40 v 20 h -40 z"/>
|
|
||||||
</svg>
|
|
||||||
</g>
|
|
||||||
<g id="textmarker_bottom">
|
|
||||||
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path stroke-width="4" stroke="#f9bc01" fill="none" d="M 0 30 h 100 z M 30 40 h 40 v 20 h -40 z"/>
|
|
||||||
</svg>
|
|
||||||
</g>
|
|
||||||
<g id="tool_placemark">
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="-1 -1 110 110">
|
|
||||||
<line fill="none" id="svg_4" marker-start="url(#se_marker_start_svg_4)" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" stroke-width="5" x1="0" x2="42.58373" y1="0" y2="56.42415"/>
|
|
||||||
<line fill="none" id="svg_5" stroke="#000000" stroke-linecap="round" stroke-width="5" x1="99.99999" x2="42.58373" y1="56.42415" y2="56.42415"/>
|
|
||||||
<rect fill="none" height="26.47059" id="svg_2" stroke="#000000" stroke-dasharray="10,10" stroke-linecap="round" stroke-linejoin="round" stroke-width="5" width="55.02392" x="44.01914" y="16.71827"/>
|
|
||||||
<rect fill="none" height="32.73994" id="svg_3" stroke="#000000" stroke-dasharray="10,10" stroke-linecap="round" stroke-linejoin="null" stroke-width="5" width="55.98086" x="44.01914" y="67.56966"/>
|
|
||||||
<defs>
|
|
||||||
<marker class="leftarrow" id="se_marker_start_svg_4" markerHeight="5" markerUnits="strokeWidth" markerWidth="5" orient="auto" refX="0" refY="50" viewBox="0 0 100 100">
|
|
||||||
<path d="m0,50l100,40l-30,-40l30,-40l-100,40z" fill="#000000" id="svg_1" stroke="#000000" stroke-width="10"/>
|
|
||||||
</marker>
|
|
||||||
</defs>
|
|
||||||
</svg>
|
|
||||||
</g>
|
|
||||||
<g id="mkr_markers_off">
|
|
||||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<line y2="0" x2="50" y1="0" x1="-50" stroke-width="5" stroke="#f9bc01" fill="none"/>
|
|
||||||
</svg>
|
|
||||||
</g>
|
|
||||||
<g id="mkr_markers_dimension">
|
|
||||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<line y2="0" x2="40" y1="0" x1="20" stroke-width="5" stroke="#f9bc01" fill="none"/>
|
|
||||||
<line y2="0" x2="-40" y1="0" x1="-20" stroke-width="5" stroke="#f9bc01" fill="none"/>
|
|
||||||
<text text-anchor="middle" font-family="serif" font-size="80" y="20" x="0" stroke-width="0" stroke="#f9bc01" fill="#f9bc01">T</text>
|
|
||||||
<path stroke-width="5" stroke="#f9bc01" fill="#f9bc01" d="M-50,0 L-30,-15 L-30,15 Z"/>
|
|
||||||
<path stroke-width="5" stroke="#f9bc01" fill="#f9bc01" d="M50,0 L30,-15 L30,15 Z"/>
|
|
||||||
</svg>
|
|
||||||
</g>
|
|
||||||
<g id="mkr_markers_label">
|
|
||||||
<svg viewBox="-60 -60 120 120" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<line y2="0" x2="40" y1="0" x1="-20" stroke-width="5" stroke="#f9bc01" fill="none"/>
|
|
||||||
<text text-anchor="middle" font-family="serif" font-size="80" y="20" x="-40" stroke-width="0" stroke="#f9bc01" fill="#f9bc01">T</text>
|
|
||||||
<path stroke-width="5" stroke="#f9bc01" fill="#f9bc01" d="M50,0 L30,-15 L30,15 Z"/>
|
|
||||||
</svg>
|
|
||||||
</g>
|
|
||||||
<g id="svg_eof"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 7.0 KiB |
3
src/editor/images/textmarker_bottom.svg
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path stroke-width="4" stroke="#f9bc01" fill="none" d="M 0 30 h 100 z M 30 40 h 40 v 20 h -40 z"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 172 B |
3
src/editor/images/textmarker_top.svg
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path stroke-width="4" stroke="#f9bc01" fill="none" d="M 0 60 h 100 z M 30 30 h 40 v 20 h -40 z"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 172 B |
11
src/editor/images/tool_placemark.svg
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="-1 -1 110 110">
|
||||||
|
<line fill="none" id="svg_4" marker-start="url(#se_marker_start_svg_4)" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" stroke-width="5" x1="0" x2="42.58373" y1="0" y2="56.42415"/>
|
||||||
|
<line fill="none" id="svg_5" stroke="#000000" stroke-linecap="round" stroke-width="5" x1="99.99999" x2="42.58373" y1="56.42415" y2="56.42415"/>
|
||||||
|
<rect fill="none" height="26.47059" id="svg_2" stroke="#000000" stroke-dasharray="10,10" stroke-linecap="round" stroke-linejoin="round" stroke-width="5" width="55.02392" x="44.01914" y="16.71827"/>
|
||||||
|
<rect fill="none" height="32.73994" id="svg_3" stroke="#000000" stroke-dasharray="10,10" stroke-linecap="round" stroke-linejoin="null" stroke-width="5" width="55.98086" x="44.01914" y="67.56966"/>
|
||||||
|
<defs>
|
||||||
|
<marker class="leftarrow" id="se_marker_start_svg_4" markerHeight="5" markerUnits="strokeWidth" markerWidth="5" orient="auto" refX="0" refY="50" viewBox="0 0 100 100">
|
||||||
|
<path d="m0,50l100,40l-30,-40l30,-40l-100,40z" fill="#000000" id="svg_1" stroke="#000000" stroke-width="10"/>
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.2 KiB |
@@ -18,7 +18,7 @@
|
|||||||
<!-- SCRIPTS -->
|
<!-- SCRIPTS -->
|
||||||
|
|
||||||
<!-- Lacking browser support -->
|
<!-- Lacking browser support -->
|
||||||
<script type="module" src="./redirect-on-lacking-support.js"></script>
|
<script type="module" src="./browser-not-supported.js"></script>
|
||||||
|
|
||||||
<!-- If you do not wish to add extensions by URL, you can add calls
|
<!-- If you do not wish to add extensions by URL, you can add calls
|
||||||
within the following file to svgEditor.setConfig -->
|
within the following file to svgEditor.setConfig -->
|
||||||
|
|||||||
@@ -83,6 +83,6 @@ export const putLocale = async function (givenParam, goodLangs) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
console.log(`Lang: ${i18next.t('lang')}`);
|
console.info(`Lang: ${i18next.t('lang')}`);
|
||||||
return { langParam, i18next };
|
return { langParam, i18next };
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ class BottomPanel {
|
|||||||
get multiselected () {
|
get multiselected () {
|
||||||
return this.editor.multiselected;
|
return this.editor.multiselected;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {module}
|
* @type {module}
|
||||||
*/
|
*/
|
||||||
@@ -39,7 +38,6 @@ class BottomPanel {
|
|||||||
}
|
}
|
||||||
this.editor.svgCanvas.setStrokeWidth(val);
|
this.editor.svgCanvas.setStrokeWidth(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {module}
|
* @type {module}
|
||||||
*/
|
*/
|
||||||
@@ -60,7 +58,6 @@ class BottomPanel {
|
|||||||
}
|
}
|
||||||
const zoom = this.editor.svgCanvas.getZoom();
|
const zoom = this.editor.svgCanvas.getZoom();
|
||||||
const wArea = this.editor.workarea;
|
const wArea = this.editor.workarea;
|
||||||
|
|
||||||
this.editor.zoomChanged(window, {
|
this.editor.zoomChanged(window, {
|
||||||
width: 0,
|
width: 0,
|
||||||
height: 0,
|
height: 0,
|
||||||
@@ -98,7 +95,6 @@ class BottomPanel {
|
|||||||
$id(btn).disabled = false;
|
$id(btn).disabled = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bNoStroke && bNoFill) {
|
if (bNoStroke && bNoFill) {
|
||||||
// eslint-disable-next-line sonarjs/no-identical-functions
|
// eslint-disable-next-line sonarjs/no-identical-functions
|
||||||
buttonsNeedingFillAndStroke.forEach((btn) => {
|
buttonsNeedingFillAndStroke.forEach((btn) => {
|
||||||
@@ -113,7 +109,6 @@ class BottomPanel {
|
|||||||
$id(btn).disabled = false;
|
$id(btn).disabled = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
this.editor.svgCanvas.runExtensions(
|
this.editor.svgCanvas.runExtensions(
|
||||||
'toolButtonStateUpdate',
|
'toolButtonStateUpdate',
|
||||||
/** @type {module:svgcanvas.SvgCanvas#event:ext_toolButtonStateUpdate} */ {
|
/** @type {module:svgcanvas.SvgCanvas#event:ext_toolButtonStateUpdate} */ {
|
||||||
@@ -122,7 +117,6 @@ class BottomPanel {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {module}
|
* @type {module}
|
||||||
*/
|
*/
|
||||||
@@ -164,7 +158,6 @@ class BottomPanel {
|
|||||||
}
|
}
|
||||||
this.updateToolButtonState();
|
this.updateToolButtonState();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {module}
|
* @type {module}
|
||||||
*/
|
*/
|
||||||
@@ -217,7 +210,7 @@ class BottomPanel {
|
|||||||
src="./images/opacity.svg"></se-spin-input>
|
src="./images/opacity.svg"></se-spin-input>
|
||||||
<se-palette id="palette"></se-palette>
|
<se-palette id="palette"></se-palette>
|
||||||
</div> <!-- tools_bottom -->
|
</div> <!-- tools_bottom -->
|
||||||
`
|
`;
|
||||||
this.editor.$svgEditor.append(template.content.cloneNode(true));
|
this.editor.$svgEditor.append(template.content.cloneNode(true));
|
||||||
$id('palette').addEventListener('change', this.handlePalette.bind(this));
|
$id('palette').addEventListener('change', this.handlePalette.bind(this));
|
||||||
const { curConfig } = this.editor.configObj;
|
const { curConfig } = this.editor.configObj;
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ class LayersPanel {
|
|||||||
* @param {PlainObject} editor
|
* @param {PlainObject} editor
|
||||||
*/
|
*/
|
||||||
constructor(editor) {
|
constructor(editor) {
|
||||||
this.uiStrings = editor.uiStrings;
|
|
||||||
this.updateContextPanel = editor.topPanel.updateContextPanel;
|
this.updateContextPanel = editor.topPanel.updateContextPanel;
|
||||||
this.sidedrag = -1;
|
this.sidedrag = -1;
|
||||||
this.sidedragging = false;
|
this.sidedragging = false;
|
||||||
@@ -79,7 +78,7 @@ class LayersPanel {
|
|||||||
*/
|
*/
|
||||||
toggleSidePanel(close) {
|
toggleSidePanel(close) {
|
||||||
const dpr = window.devicePixelRatio || 1;
|
const dpr = window.devicePixelRatio || 1;
|
||||||
const w = parseFloat(getComputedStyle($id("sidepanels"), null).width.replace("px", ""))
|
const w = parseFloat(getComputedStyle($id("sidepanels"), null).width.replace("px", ""));
|
||||||
const isOpened = (dpr < 1 ? w : w / dpr) > 2;
|
const isOpened = (dpr < 1 ? w : w / dpr) > 2;
|
||||||
const zoomAdjustedSidepanelWidth =
|
const zoomAdjustedSidepanelWidth =
|
||||||
(dpr < 1 ? 1 : dpr) * SIDEPANEL_OPENWIDTH;
|
(dpr < 1 ? 1 : dpr) * SIDEPANEL_OPENWIDTH;
|
||||||
@@ -173,7 +172,7 @@ class LayersPanel {
|
|||||||
"change",
|
"change",
|
||||||
this.lmenuFunc.bind(this)
|
this.lmenuFunc.bind(this)
|
||||||
);
|
);
|
||||||
$id("se-cmenu-layers-list").addEventListener("change", e => {
|
$id("se-cmenu-layers-list").addEventListener("change", (e) => {
|
||||||
this.lmenuFunc(e);
|
this.lmenuFunc(e);
|
||||||
});
|
});
|
||||||
$id("sidepanel_handle").addEventListener(
|
$id("sidepanel_handle").addEventListener(
|
||||||
@@ -183,7 +182,7 @@ class LayersPanel {
|
|||||||
if (this.editor.configObj.curConfig.showlayers) {
|
if (this.editor.configObj.curConfig.showlayers) {
|
||||||
this.toggleSidePanel();
|
this.toggleSidePanel();
|
||||||
}
|
}
|
||||||
$id("sidepanel_handle").addEventListener("mousedown", evt => {
|
$id("sidepanel_handle").addEventListener("mousedown", (evt) => {
|
||||||
this.sidedrag = evt.pageX;
|
this.sidedrag = evt.pageX;
|
||||||
window.addEventListener("mousemove", this.resizeSidePanel.bind(this));
|
window.addEventListener("mousemove", this.resizeSidePanel.bind(this));
|
||||||
this.allowmove = false;
|
this.allowmove = false;
|
||||||
@@ -192,14 +191,14 @@ class LayersPanel {
|
|||||||
this.allowmove = true;
|
this.allowmove = true;
|
||||||
}, 20);
|
}, 20);
|
||||||
});
|
});
|
||||||
$id("sidepanel_handle").addEventListener("mouseup", _evt => {
|
$id("sidepanel_handle").addEventListener("mouseup", (_evt) => {
|
||||||
if (!this.sidedragging) {
|
if (!this.sidedragging) {
|
||||||
this.toggleSidePanel();
|
this.toggleSidePanel();
|
||||||
}
|
}
|
||||||
this.sidedrag = -1;
|
this.sidedrag = -1;
|
||||||
this.sidedragging = false;
|
this.sidedragging = false;
|
||||||
});
|
});
|
||||||
window.addEventListener("mouseup", _evt => {
|
window.addEventListener("mouseup", (_evt) => {
|
||||||
this.sidedrag = -1;
|
this.sidedrag = -1;
|
||||||
this.sidedragging = false;
|
this.sidedragging = false;
|
||||||
$id("svg_editor").removeEventListener(
|
$id("svg_editor").removeEventListener(
|
||||||
@@ -215,18 +214,18 @@ class LayersPanel {
|
|||||||
let uniqName;
|
let uniqName;
|
||||||
let i = this.editor.svgCanvas.getCurrentDrawing().getNumLayers();
|
let i = this.editor.svgCanvas.getCurrentDrawing().getNumLayers();
|
||||||
do {
|
do {
|
||||||
uniqName = this.uiStrings.layers.layer + " " + ++i;
|
uniqName = this.editor.i18next.t("layers.layer") + " " + ++i;
|
||||||
} while (this.editor.svgCanvas.getCurrentDrawing().hasLayer(uniqName));
|
} while (this.editor.svgCanvas.getCurrentDrawing().hasLayer(uniqName));
|
||||||
|
|
||||||
const newName = prompt(
|
const newName = prompt(
|
||||||
this.uiStrings.notification.enterUniqueLayerName,
|
this.editor.i18next.t('notification.enterUniqueLayerName'),
|
||||||
uniqName
|
uniqName
|
||||||
);
|
);
|
||||||
if (!newName) {
|
if (!newName) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (this.editor.svgCanvas.getCurrentDrawing().hasLayer(newName)) {
|
if (this.editor.svgCanvas.getCurrentDrawing().hasLayer(newName)) {
|
||||||
alert(this.uiStrings.notification.dupeLayerName);
|
alert(this.editor.i18next.t('notification.dupeLayerName'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.editor.svgCanvas.createLayer(newName);
|
this.editor.svgCanvas.createLayer(newName);
|
||||||
@@ -263,14 +262,14 @@ class LayersPanel {
|
|||||||
this.editor.svgCanvas.getCurrentDrawing().getCurrentLayerName() + " copy";
|
this.editor.svgCanvas.getCurrentDrawing().getCurrentLayerName() + " copy";
|
||||||
|
|
||||||
const newName = prompt(
|
const newName = prompt(
|
||||||
this.uiStrings.notification.enterUniqueLayerName,
|
this.editor.i18next.t('notification.enterUniqueLayerName'),
|
||||||
name
|
name
|
||||||
);
|
);
|
||||||
if (!newName) {
|
if (!newName) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (this.editor.svgCanvas.getCurrentDrawing().hasLayer(newName)) {
|
if (this.editor.svgCanvas.getCurrentDrawing().hasLayer(newName)) {
|
||||||
alert(this.uiStrings.notification.dupeLayerName);
|
alert(this.editor.i18next.t('notification.dupeLayerName'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.editor.svgCanvas.cloneLayer(newName);
|
this.editor.svgCanvas.cloneLayer(newName);
|
||||||
@@ -323,7 +322,7 @@ class LayersPanel {
|
|||||||
*/
|
*/
|
||||||
layerRename() {
|
layerRename() {
|
||||||
const oldName = document.querySelector("#layerlist tr.layersel td.layername").textContent;
|
const oldName = document.querySelector("#layerlist tr.layersel td.layername").textContent;
|
||||||
const newName = prompt(this.uiStrings.notification.enterNewLayerName, "");
|
const newName = prompt(this.editor.i18next.t('notification.enterNewLayerName'), "");
|
||||||
if (!newName) {
|
if (!newName) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -331,7 +330,7 @@ class LayersPanel {
|
|||||||
oldName === newName ||
|
oldName === newName ||
|
||||||
this.editor.svgCanvas.getCurrentDrawing().hasLayer(newName)
|
this.editor.svgCanvas.getCurrentDrawing().hasLayer(newName)
|
||||||
) {
|
) {
|
||||||
alert(this.uiStrings.notification.layerHasThatName);
|
alert(this.editor.i18next.t('notification.layerHasThatName'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.editor.svgCanvas.renameCurrentLayer(newName);
|
this.editor.svgCanvas.renameCurrentLayer(newName);
|
||||||
@@ -353,7 +352,7 @@ class LayersPanel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (layerNameToHighlight) {
|
if (layerNameToHighlight) {
|
||||||
curNames.forEach(curName => {
|
curNames.forEach((curName) => {
|
||||||
if (curName !== layerNameToHighlight) {
|
if (curName !== layerNameToHighlight) {
|
||||||
this.editor.svgCanvas
|
this.editor.svgCanvas
|
||||||
.getCurrentDrawing()
|
.getCurrentDrawing()
|
||||||
@@ -361,7 +360,7 @@ class LayersPanel {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
curNames.forEach(curName => {
|
curNames.forEach((curName) => {
|
||||||
this.editor.svgCanvas.getCurrentDrawing().setLayerOpacity(curName, 1.0);
|
this.editor.svgCanvas.getCurrentDrawing().setLayerOpacity(curName, 1.0);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -412,14 +411,11 @@ class LayersPanel {
|
|||||||
self.editor.svgCanvas.setCurrentLayer(evt.currentTarget.textContent);
|
self.editor.svgCanvas.setCurrentLayer(evt.currentTarget.textContent);
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
});
|
});
|
||||||
element.addEventListener('mouseup', function(evt) {
|
element.addEventListener('mouseup', (evt) => {
|
||||||
self.toggleHighlightLayer(
|
self.toggleHighlightLayer(evt.currentTarget.textContent);
|
||||||
self.editor.svgCanvas,
|
|
||||||
evt.currentTarget.textContent
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
element.addEventListener('mouseout', function(_evt) {
|
element.addEventListener('mouseout', (_evt) => {
|
||||||
self.toggleHighlightLayer(self.editor.svgCanvas);
|
self.toggleHighlightLayer();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
const elements = $id('layerlist').querySelectorAll("td.layervis");
|
const elements = $id('layerlist').querySelectorAll("td.layervis");
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ class LeftPanel {
|
|||||||
updateLeftPanel(button) {
|
updateLeftPanel(button) {
|
||||||
if (button.disabled) return false;
|
if (button.disabled) return false;
|
||||||
// remove the pressed state on other(s) button(s)
|
// remove the pressed state on other(s) button(s)
|
||||||
$qa("#tools_left *[pressed]").forEach(b => {
|
$qa("#tools_left *[pressed]").forEach((b) => {
|
||||||
b.pressed = false;
|
b.pressed = false;
|
||||||
});
|
});
|
||||||
// pressed state for the clicked button
|
// pressed state for the clicked button
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ class TopPanel {
|
|||||||
*/
|
*/
|
||||||
constructor(editor) {
|
constructor(editor) {
|
||||||
this.editor = editor;
|
this.editor = editor;
|
||||||
this.uiStrings = editor.uiStrings;
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @type {module}
|
* @type {module}
|
||||||
@@ -138,7 +137,7 @@ class TopPanel {
|
|||||||
curhref = curhref.startsWith("data:") ? "" : curhref;
|
curhref = curhref.startsWith("data:") ? "" : curhref;
|
||||||
// eslint-disable-next-line no-alert
|
// eslint-disable-next-line no-alert
|
||||||
const url = prompt(
|
const url = prompt(
|
||||||
this.editor.uiStrings.notification.enterNewImgURL,
|
this.editor.i18next.t('notification.enterNewImgURL'),
|
||||||
curhref
|
curhref
|
||||||
);
|
);
|
||||||
if (url) {
|
if (url) {
|
||||||
@@ -152,7 +151,7 @@ class TopPanel {
|
|||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
updateContextPanel() {
|
updateContextPanel() {
|
||||||
const setInputWidth = elem => {
|
const setInputWidth = (elem) => {
|
||||||
const w = Math.min(Math.max(12 + elem.value.length * 6, 50), 300);
|
const w = Math.min(Math.max(12 + elem.value.length * 6, 50), 300);
|
||||||
elem.style.width = w + 'px';
|
elem.style.width = w + 'px';
|
||||||
};
|
};
|
||||||
@@ -313,7 +312,7 @@ class TopPanel {
|
|||||||
const curPanel = panels[tagName];
|
const curPanel = panels[tagName];
|
||||||
$id(tagName + "_panel").style.display = 'block';
|
$id(tagName + "_panel").style.display = 'block';
|
||||||
|
|
||||||
curPanel.forEach(item => {
|
curPanel.forEach((item) => {
|
||||||
let attrVal = elem.getAttribute(item);
|
let attrVal = elem.getAttribute(item);
|
||||||
if (this.editor.configObj.curConfig.baseUnit !== "px" && elem[item]) {
|
if (this.editor.configObj.curConfig.baseUnit !== "px" && elem[item]) {
|
||||||
const bv = elem[item].baseVal.value;
|
const bv = elem[item].baseVal.value;
|
||||||
@@ -352,7 +351,7 @@ class TopPanel {
|
|||||||
if (this.editor.svgCanvas.addedNew) {
|
if (this.editor.svgCanvas.addedNew) {
|
||||||
// Timeout needed for IE9
|
// Timeout needed for IE9
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
$id("text").focus()
|
$id("text").focus();
|
||||||
$id("text").select();
|
$id("text").select();
|
||||||
}, 100);
|
}, 100);
|
||||||
}
|
}
|
||||||
@@ -406,7 +405,7 @@ class TopPanel {
|
|||||||
|
|
||||||
if ((elem && !isNode) || this.multiselected) {
|
if ((elem && !isNode) || this.multiselected) {
|
||||||
// update the selected elements' layer
|
// update the selected elements' layer
|
||||||
$id("selLayerNames").removeAttribute("disabled")
|
$id("selLayerNames").removeAttribute("disabled");
|
||||||
$id("selLayerNames").value = currentLayerName;
|
$id("selLayerNames").value = currentLayerName;
|
||||||
|
|
||||||
// Enable regular menu options
|
// Enable regular menu options
|
||||||
@@ -553,12 +552,12 @@ class TopPanel {
|
|||||||
attrChanger(e) {
|
attrChanger(e) {
|
||||||
const attr = e.target.getAttribute("data-attr");
|
const attr = e.target.getAttribute("data-attr");
|
||||||
let val = e.target.value;
|
let val = e.target.value;
|
||||||
const valid = isValidUnit(attr, val, this.editor.selectedElement);
|
const valid = isValidUnit(attr, val, this.selectedElement);
|
||||||
|
|
||||||
if (!valid) {
|
if (!valid) {
|
||||||
e.target.value = this.editor.selectedElement().getAttribute(attr);
|
e.target.value = this.selectedElement.getAttribute(attr);
|
||||||
// eslint-disable-next-line no-alert
|
// eslint-disable-next-line no-alert
|
||||||
alert(this.uiStrings.notification.invalidAttrValGiven);
|
alert(this.i18next.t('notification.invalidAttrValGiven'));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -619,7 +618,7 @@ class TopPanel {
|
|||||||
if (!isNullish(this.editor.selectedElement) || this.multiselected) {
|
if (!isNullish(this.editor.selectedElement) || this.multiselected) {
|
||||||
// eslint-disable-next-line no-alert
|
// eslint-disable-next-line no-alert
|
||||||
const url = prompt(
|
const url = prompt(
|
||||||
this.uiStrings.notification.enterNewLinkURL,
|
this.i18next.t('notification.enterNewLinkURL'),
|
||||||
"http://"
|
"http://"
|
||||||
);
|
);
|
||||||
if (url) {
|
if (url) {
|
||||||
@@ -742,7 +741,7 @@ class TopPanel {
|
|||||||
init() {
|
init() {
|
||||||
// add Top panel
|
// add Top panel
|
||||||
const template = document.createElement("template");
|
const template = document.createElement("template");
|
||||||
const {i18next} = this.editor
|
const { i18next } = this.editor;
|
||||||
// eslint-disable-next-line no-unsanitized/property
|
// eslint-disable-next-line no-unsanitized/property
|
||||||
template.innerHTML = `
|
template.innerHTML = `
|
||||||
<div id="tools_top">
|
<div id="tools_top">
|
||||||
@@ -1040,7 +1039,7 @@ class TopPanel {
|
|||||||
"click",
|
"click",
|
||||||
this.clickGroup.bind(this)
|
this.clickGroup.bind(this)
|
||||||
);
|
);
|
||||||
$id("tool_position").addEventListener("change", evt =>
|
$id("tool_position").addEventListener("change", (evt) =>
|
||||||
this.clickAlignEle.bind(this)(evt)
|
this.clickAlignEle.bind(this)(evt)
|
||||||
);
|
);
|
||||||
$id("tool_align_left").addEventListener("click", () =>
|
$id("tool_align_left").addEventListener("click", () =>
|
||||||
@@ -1130,7 +1129,7 @@ class TopPanel {
|
|||||||
"image_height",
|
"image_height",
|
||||||
"path_node_x",
|
"path_node_x",
|
||||||
"path_node_y"
|
"path_node_y"
|
||||||
].forEach(attrId =>
|
].forEach((attrId) =>
|
||||||
$id(attrId).addEventListener("change", this.attrChanger.bind(this))
|
$id(attrId).addEventListener("change", this.attrChanger.bind(this))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -471,7 +471,7 @@ input[type=text] {
|
|||||||
border-top: 1px solid var(--border-color);
|
border-top: 1px solid var(--border-color);
|
||||||
border-right: 1px solid #FFFFFF;
|
border-right: 1px solid #FFFFFF;
|
||||||
border-bottom: 1px solid #FFFFFF;
|
border-bottom: 1px solid #FFFFFF;
|
||||||
background-color: #B0B0B0;
|
background-color: #5a6162;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown ul {
|
.dropdown ul {
|
||||||
@@ -495,7 +495,7 @@ input[type=text] {
|
|||||||
width: 120px;
|
width: 120px;
|
||||||
padding: 4px;
|
padding: 4px;
|
||||||
background: #E8E8E8;
|
background: #E8E8E8;
|
||||||
border: 1px solid #B0B0B0;
|
border: 1px solid #5a6162;
|
||||||
margin: 0 0 -1px 0;
|
margin: 0 0 -1px 0;
|
||||||
line-height: 16px;
|
line-height: 16px;
|
||||||
}
|
}
|
||||||
@@ -625,10 +625,6 @@ ul li.current {
|
|||||||
padding-right: .3em;
|
padding-right: .3em;
|
||||||
}
|
}
|
||||||
|
|
||||||
#svg_source_editor {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.overlay {
|
.overlay {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
@@ -640,19 +636,6 @@ ul li.current {
|
|||||||
z-index: 5;
|
z-index: 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
#svg_source_editor #svg_source_container {
|
|
||||||
position: absolute;
|
|
||||||
top: 30px;
|
|
||||||
left: 30px;
|
|
||||||
right: 30px;
|
|
||||||
bottom: 30px;
|
|
||||||
background-color: #B0B0B0;
|
|
||||||
opacity: 1.0;
|
|
||||||
text-align: center;
|
|
||||||
border: 1px outset #777;
|
|
||||||
z-index: 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
#save_output_btns {
|
#save_output_btns {
|
||||||
display: none;
|
display: none;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
@@ -668,20 +651,6 @@ ul li.current {
|
|||||||
margin-left: 30px;
|
margin-left: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#svg_docprops #svg_docprops_container,
|
|
||||||
#svg_prefs #svg_prefs_container {
|
|
||||||
position: absolute;
|
|
||||||
top: 50px;
|
|
||||||
padding: 10px;
|
|
||||||
background-color: #B0B0B0;
|
|
||||||
border: 1px outset #777;
|
|
||||||
opacity: 1.0;
|
|
||||||
/* width: 450px;*/
|
|
||||||
font-family: Verdana, Helvetica, sans-serif;
|
|
||||||
font-size: .8em;
|
|
||||||
z-index: 20001;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------ */
|
/* ------------ */
|
||||||
|
|
||||||
.dropdown li.tool_button {
|
.dropdown li.tool_button {
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ export const copyElem = function (el, getNextId) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (el.dataset.gsvg) {
|
if (el.dataset.gsvg) {
|
||||||
newEl.dataset.gsvg = newEl.firstChild
|
newEl.dataset.gsvg = newEl.firstChild;
|
||||||
} else if (el.dataset.symbol) {
|
} else if (el.dataset.symbol) {
|
||||||
const ref = el.dataset.symbol;
|
const ref = el.dataset.symbol;
|
||||||
newEl.dataset.ref = ref;
|
newEl.dataset.ref = ref;
|
||||||
|
|||||||
@@ -1052,3 +1052,4 @@ export const setContext = function (elem) {
|
|||||||
* @see {@link module:layer.Layer}
|
* @see {@link module:layer.Layer}
|
||||||
*/
|
*/
|
||||||
export { Layer };
|
export { Layer };
|
||||||
|
|
||||||
@@ -318,8 +318,7 @@ export const pathActionsMethod = (function () {
|
|||||||
}
|
}
|
||||||
return element;
|
return element;
|
||||||
};
|
};
|
||||||
// console.log(pathActionsContext_);
|
|
||||||
// const convertPath = pathActionsContext_.getConvertPath();
|
|
||||||
return (/** @lends module:path.pathActions */ {
|
return (/** @lends module:path.pathActions */ {
|
||||||
/**
|
/**
|
||||||
* @param {MouseEvent} evt
|
* @param {MouseEvent} evt
|
||||||
@@ -464,7 +463,6 @@ export const pathActionsMethod = (function () {
|
|||||||
editorContext_.getMouseTarget(evt)
|
editorContext_.getMouseTarget(evt)
|
||||||
)) {
|
)) {
|
||||||
// Clicked outside canvas, so don't make point
|
// Clicked outside canvas, so don't make point
|
||||||
// console.log('Clicked outside canvas');
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -428,7 +428,7 @@ export class Segment {
|
|||||||
*/
|
*/
|
||||||
selectCtrls (y) {
|
selectCtrls (y) {
|
||||||
document.getElementById('ctrlpointgrip_' + this.index + 'c1').setAttribute('fill', y ? '#0FF' : '#EEE');
|
document.getElementById('ctrlpointgrip_' + this.index + 'c1').setAttribute('fill', y ? '#0FF' : '#EEE');
|
||||||
document.getElementById('ctrlpointgrip_' + this.index + 'c2').setAttribute('fill', y ? '#0FF' : '#EEE')
|
document.getElementById('ctrlpointgrip_' + this.index + 'c2').setAttribute('fill', y ? '#0FF' : '#EEE');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -86,7 +86,8 @@ let editorContext_ = null;
|
|||||||
* Object with the following keys/values.
|
* Object with the following keys/values.
|
||||||
* @typedef {PlainObject} module:path.SVGElementJSON
|
* @typedef {PlainObject} module:path.SVGElementJSON
|
||||||
* @property {string} element - Tag name of the SVG element to create
|
* @property {string} element - Tag name of the SVG element to create
|
||||||
* @property {PlainObject<string, string>} attr - Has key-value attributes to assign to the new element. An `id` should be set so that {@link module:utilities.EditorContext#addSVGElementFromJson} can later re-identify the element for modification or replacement.
|
* @property {PlainObject<string, string>} attr - Has key-value attributes to assign to the new element.
|
||||||
|
* An `id` should be set so that {@link module:utilities.EditorContext#addSVGElementFromJson} can later re-identify the element for modification or replacement.
|
||||||
* @property {boolean} [curStyles=false] - Indicates whether current style attributes should be applied first
|
* @property {boolean} [curStyles=false] - Indicates whether current style attributes should be applied first
|
||||||
* @property {module:path.SVGElementJSON[]} [children] - Data objects to be added recursively as children
|
* @property {module:path.SVGElementJSON[]} [children] - Data objects to be added recursively as children
|
||||||
* @property {string} [namespace="http://www.w3.org/2000/svg"] - Indicate a (non-SVG) namespace
|
* @property {string} [namespace="http://www.w3.org/2000/svg"] - Indicate a (non-SVG) namespace
|
||||||
@@ -99,7 +100,8 @@ let editorContext_ = null;
|
|||||||
/**
|
/**
|
||||||
* @function module:path.EditorContext#call
|
* @function module:path.EditorContext#call
|
||||||
* @param {"selected"|"changed"} ev - String with the event name
|
* @param {"selected"|"changed"} ev - String with the event name
|
||||||
* @param {module:svgcanvas.SvgCanvas#event:selected|module:svgcanvas.SvgCanvas#event:changed} arg - Argument to pass through to the callback function. If the event is "changed", an array of `Element`s is passed; if "selected", a single-item array of `Element` is passed.
|
* @param {module:svgcanvas.SvgCanvas#event:selected|module:svgcanvas.SvgCanvas#event:changed} arg - Argument to pass through to the callback function.
|
||||||
|
* If the event is "changed", an array of `Element`s is passed; if "selected", a single-item array of `Element` is passed.
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -707,7 +707,7 @@ export const recalculateDimensions = function (selected) {
|
|||||||
y1: selected.getAttribute('y1'),
|
y1: selected.getAttribute('y1'),
|
||||||
x2: selected.getAttribute('x2'),
|
x2: selected.getAttribute('x2'),
|
||||||
y2: selected.getAttribute('y2'),
|
y2: selected.getAttribute('y2'),
|
||||||
}
|
};
|
||||||
// Fallthrough
|
// Fallthrough
|
||||||
case 'polyline':
|
case 'polyline':
|
||||||
case 'polygon':
|
case 'polygon':
|
||||||
|
|||||||
@@ -733,7 +733,7 @@ export const convertToGroup = function (elem) {
|
|||||||
recalculateDimensions(elem);
|
recalculateDimensions(elem);
|
||||||
elementContext_.call('selected', [ elem ]);
|
elementContext_.call('selected', [ elem ]);
|
||||||
} else if (dataStorage.has($elem, 'symbol')) {
|
} else if (dataStorage.has($elem, 'symbol')) {
|
||||||
elem = dataStorage.get($elem, 'symbol')
|
elem = dataStorage.get($elem, 'symbol');
|
||||||
|
|
||||||
ts = $elem.attr('transform');
|
ts = $elem.attr('transform');
|
||||||
const pos = $elem.attr([ 'x', 'y' ]);
|
const pos = $elem.attr([ 'x', 'y' ]);
|
||||||
|
|||||||
@@ -1140,7 +1140,7 @@ export const getVisibleElements = function (parentElement) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const contentElems = [];
|
const contentElems = [];
|
||||||
const childrens = parentElement.children
|
const childrens = parentElement.children;
|
||||||
Array.prototype.forEach.call(childrens, function (elem) {
|
Array.prototype.forEach.call(childrens, function (elem) {
|
||||||
if (elem.getBBox) {
|
if (elem.getBBox) {
|
||||||
contentElems.push(elem);
|
contentElems.push(elem);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { fromRollup } from '@web/dev-server-rollup';
|
import { fromRollup } from '@web/dev-server-rollup';
|
||||||
|
// eslint-disable-next-line node/no-unpublished-import
|
||||||
import rollupCommonjs from '@rollup/plugin-commonjs';
|
import rollupCommonjs from '@rollup/plugin-commonjs';
|
||||||
|
|
||||||
const commonjs = fromRollup(rollupCommonjs);
|
const commonjs = fromRollup(rollupCommonjs);
|
||||||
|
|||||||