- Breaking change: Require `new` with `EmbeddedSVGEdit` (allows us to use `class` internally)
- Breaking change: If `svgcanvas.setUiStrings` must now be called if not using editor in order
to get strings (for sake of i18n) (and if using path.js alone, must also have its `setUiStrings` called)
- Breaking change (ext-overview-window): Avoid global `overviewWindowGlobals`
- Breaking change (ext-imagelib): Change to object-based encoding for namespacing of
messages (though keep stringifying/parsing ourselves until we remove IE9 support)
- Breaking change: Rename `jquery.js` to `jquery.min.js`
- Breaking change: Remove `scoped` attribute from `style`; it is now deprecated and
obsolete; also move to head (after other stylesheets)
- Enhancement: Make SpinButton plugin independent of SVGEdit via
generic state object for tool_scale
- Enhancement: Remove now unused Python l10n scripts (#238)
- Enhancement: ES6 Modules (including jQuery plugins but not jQuery)
- Enhancement: Further JSDoc (incomplete)
- Enhancement (Optimization): Compress images using imageoptim (and add
npm script) (per #215)
- Fix: i18nize path.js strings and canvas notifications
- Fix: Attempt i18n for ext-markers
- Refactoring (ext-storage): Move locale info to own file imported by the extension (toward modularity; still should be split into separate files by language and *dynamically* imported, but we'll wait for better `import` support to refactor this)
- Refactoring: For imagelib, add local jQuery copy (using old 1.4.4 as had
been using from server)
- Refactoring: For MathJax, add local copy (using old 2.3 as had been using from
server); server had not been working
- Refactoring: Remove `use strict` (implicit in modules)
- Refactoring: Remove trailing whitespace, fix some code within comments
- Refactoring: Expect `jQuery` global rather than `$` for better modularity
(also to adapt line later once available via `import`)
- Refactoring: Prefer `const` (and then `let`)
- Refactoring: Add block scope keywords closer to first block in which they appear
- Refactoring: Use ES6 `class`
- Refactoring `$.isArray` -> `Array.isArray` and avoid some other jQuery core methods
with simple VanillaJS replacements
- Refactoring: Use abbreviated object property syntax
- Refactoring: Object destructuring
- Refactoring: Remove `uiStrings` contents in svg-editor.js (obtains from locale)
- Refactoring: Add favicon to embedded API file
- Refactoring: Use arrow functions for brief functions (incomplete)
- Refactoring: Use `Array.prototype.includes`/`String.prototype.includes`;
`String.prototype.startsWith`, `String.prototype.trim`
- Refactoring: Remove now unnecessary svgutils do/while resetting of variables
- Refactoring: Use shorthand methods for object literals (avoid ": function")
- Refactoring: Avoid quoting object property keys where unnecessary
- Refactoring: Just do truthy/falsey check for lengths in place of comparison to 0
- Refactoring (Testing): Avoid jQuery usage within most test files (defer script,
also in preparation for future switch to ES6 modules for tests)
- Refactoring: Make jpicker variable declaration indent bearable
- Refactoring (Linting): Finish svgcanvas.js
- Docs: Mention in comment no longer an entry file as before
- Docs: Migrate old config, extensions, and FAQ docs
- Licensing: Indicate MIT is license type of rgbcolor; rename/add license file name for
jgraduate and screencast to reflect type (Apache 2.0); rename file to reflect it
contains license information (of type MIT) for Raphael icons
163 lines
4.1 KiB
JavaScript
163 lines
4.1 KiB
JavaScript
/* globals jQuery, svgEditor, svgCanvas */
|
|
/*
|
|
* ext-grid.js
|
|
*
|
|
* Licensed under the Apache License, Version 2
|
|
*
|
|
* Copyright(c) 2010 Redou Mine
|
|
* Copyright(c) 2010 Alexis Deveria
|
|
*
|
|
*/
|
|
|
|
// Dependencies:
|
|
// 1) units.js
|
|
// 2) everything else
|
|
|
|
import {NS} from './svgedit.js';
|
|
import {getTypeMap} from './units.js';
|
|
|
|
svgEditor.addExtension('view_grid', function () {
|
|
const $ = jQuery;
|
|
const svgdoc = document.getElementById('svgcanvas').ownerDocument,
|
|
{assignAttributes} = svgCanvas,
|
|
hcanvas = document.createElement('canvas'),
|
|
canvBG = $('#canvasBackground'),
|
|
units = getTypeMap(),
|
|
intervals = [0.01, 0.1, 1, 10, 100, 1000];
|
|
let showGrid = svgEditor.curConfig.showGrid || false;
|
|
|
|
$(hcanvas).hide().appendTo('body');
|
|
|
|
const canvasGrid = svgdoc.createElementNS(NS.SVG, 'svg');
|
|
assignAttributes(canvasGrid, {
|
|
id: 'canvasGrid',
|
|
width: '100%',
|
|
height: '100%',
|
|
x: 0,
|
|
y: 0,
|
|
overflow: 'visible',
|
|
display: 'none'
|
|
});
|
|
canvBG.append(canvasGrid);
|
|
|
|
// grid-pattern
|
|
const gridPattern = svgdoc.createElementNS(NS.SVG, 'pattern');
|
|
assignAttributes(gridPattern, {
|
|
id: 'gridpattern',
|
|
patternUnits: 'userSpaceOnUse',
|
|
x: 0, // -(value.strokeWidth / 2), // position for strokewidth
|
|
y: 0, // -(value.strokeWidth / 2), // position for strokewidth
|
|
width: 100,
|
|
height: 100
|
|
});
|
|
|
|
const gridimg = svgdoc.createElementNS(NS.SVG, 'image');
|
|
assignAttributes(gridimg, {
|
|
x: 0,
|
|
y: 0,
|
|
width: 100,
|
|
height: 100
|
|
});
|
|
gridPattern.appendChild(gridimg);
|
|
$('#svgroot defs').append(gridPattern);
|
|
|
|
// grid-box
|
|
const gridBox = svgdoc.createElementNS(NS.SVG, 'rect');
|
|
assignAttributes(gridBox, {
|
|
width: '100%',
|
|
height: '100%',
|
|
x: 0,
|
|
y: 0,
|
|
'stroke-width': 0,
|
|
stroke: 'none',
|
|
fill: 'url(#gridpattern)',
|
|
style: 'pointer-events: none; display:visible;'
|
|
});
|
|
$('#canvasGrid').append(gridBox);
|
|
|
|
function updateGrid (zoom) {
|
|
// TODO: Try this with <line> elements, then compare performance difference
|
|
const unit = units[svgEditor.curConfig.baseUnit]; // 1 = 1px
|
|
const uMulti = unit * zoom;
|
|
// Calculate the main number interval
|
|
const rawM = 100 / uMulti;
|
|
let multi = 1;
|
|
for (let i = 0; i < intervals.length; i++) {
|
|
const num = intervals[i];
|
|
multi = num;
|
|
if (rawM <= num) {
|
|
break;
|
|
}
|
|
}
|
|
const bigInt = multi * uMulti;
|
|
|
|
// Set the canvas size to the width of the container
|
|
hcanvas.width = bigInt;
|
|
hcanvas.height = bigInt;
|
|
const ctx = hcanvas.getContext('2d');
|
|
const curD = 0.5;
|
|
const part = bigInt / 10;
|
|
|
|
ctx.globalAlpha = 0.2;
|
|
ctx.strokeStyle = svgEditor.curConfig.gridColor;
|
|
for (let i = 1; i < 10; i++) {
|
|
const subD = Math.round(part * i) + 0.5;
|
|
// const lineNum = (i % 2)?12:10;
|
|
const lineNum = 0;
|
|
ctx.moveTo(subD, bigInt);
|
|
ctx.lineTo(subD, lineNum);
|
|
ctx.moveTo(bigInt, subD);
|
|
ctx.lineTo(lineNum, subD);
|
|
}
|
|
ctx.stroke();
|
|
ctx.beginPath();
|
|
ctx.globalAlpha = 0.5;
|
|
ctx.moveTo(curD, bigInt);
|
|
ctx.lineTo(curD, 0);
|
|
|
|
ctx.moveTo(bigInt, curD);
|
|
ctx.lineTo(0, curD);
|
|
ctx.stroke();
|
|
|
|
const datauri = hcanvas.toDataURL('image/png');
|
|
gridimg.setAttribute('width', bigInt);
|
|
gridimg.setAttribute('height', bigInt);
|
|
gridimg.parentNode.setAttribute('width', bigInt);
|
|
gridimg.parentNode.setAttribute('height', bigInt);
|
|
svgCanvas.setHref(gridimg, datauri);
|
|
}
|
|
|
|
function gridUpdate () {
|
|
if (showGrid) {
|
|
updateGrid(svgCanvas.getZoom());
|
|
}
|
|
$('#canvasGrid').toggle(showGrid);
|
|
$('#view_grid').toggleClass('push_button_pressed tool_button');
|
|
}
|
|
return {
|
|
name: 'view_grid',
|
|
svgicons: svgEditor.curConfig.extPath + 'grid-icon.xml',
|
|
|
|
zoomChanged (zoom) {
|
|
if (showGrid) { updateGrid(zoom); }
|
|
},
|
|
callback () {
|
|
if (showGrid) {
|
|
gridUpdate();
|
|
}
|
|
},
|
|
buttons: [{
|
|
id: 'view_grid',
|
|
type: 'context',
|
|
panel: 'editor_panel',
|
|
title: 'Show/Hide Grid',
|
|
events: {
|
|
click () {
|
|
svgEditor.curConfig.showGrid = showGrid = !showGrid;
|
|
gridUpdate();
|
|
}
|
|
}
|
|
}]
|
|
};
|
|
});
|