mirror of
https://github.com/lospec/pixel-editor.git
synced 2023-08-10 21:12:51 +03:00
Added ellipse tool setup
This commit is contained in:
parent
6900ecb0c0
commit
832f36992b
@ -28,12 +28,14 @@
|
||||
z-index:0;
|
||||
}
|
||||
|
||||
#tools-menu li button path {
|
||||
#tools-menu li button path, #tools-menu li button ellipse {
|
||||
fill: $baseicon;
|
||||
stroke: $baseicon;
|
||||
}
|
||||
|
||||
#tools-menu li:hover button:first-child path {
|
||||
#tools-menu li:hover button:first-child path, #tools-menu li:hover button:first-child ellipse {
|
||||
fill: $basehovericon;
|
||||
stroke: $basehovericon;
|
||||
}
|
||||
|
||||
|
||||
@ -41,7 +43,7 @@
|
||||
background: $baseselected !important;
|
||||
}
|
||||
|
||||
#tools-menu li.selected button:first-child path {
|
||||
#tools-menu li.selected button:first-child path, #tools-menu li.selected button:first-child ellipse {
|
||||
fill: $baseselectedicon;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
const featureToggles = (function featureTogglesModule() {
|
||||
/*const featureToggles = (function featureTogglesModule() {
|
||||
|
||||
const ellipseToolLocalStorageKey = 'feature_ellipseTool';
|
||||
|
||||
@ -30,4 +30,4 @@ const featureToggles = (function featureTogglesModule() {
|
||||
}
|
||||
|
||||
})();
|
||||
|
||||
*/
|
||||
|
@ -6,6 +6,7 @@ const ToolManager = (() => {
|
||||
tools["eraser"] = new EraserTool("eraser", {type: 'html'}, switchTool);
|
||||
tools["rectangle"] = new RectangleTool("rectangle", {type: 'html'}, switchTool);
|
||||
tools["line"] = new LineTool("line", {type: 'html'}, switchTool);
|
||||
tools["ellipse"] = new EllipseTool("ellipse", {type: 'html'}, switchTool);
|
||||
tools["fill"] = new FillTool("fill", {type: 'cursor', style: 'crosshair'}, switchTool);
|
||||
|
||||
tools["eyedropper"] = new EyeDropperTool("eyedropper", {type: 'cursor', style: 'crosshair'}, switchTool);
|
||||
|
@ -37,6 +37,7 @@
|
||||
//=include tools/EraserTool.js
|
||||
//=include tools/LineTool.js
|
||||
//=include tools/RectangleTool.js
|
||||
//=include tools/EllipseTool.js
|
||||
//=include tools/FillTool.js
|
||||
//=include tools/EyeDropperTool.js
|
||||
//=include tools/PanTool.js
|
||||
@ -69,7 +70,7 @@ PresetModule.instrumentPresetMenu();
|
||||
|
||||
//when the page is done loading, you can get ready to start
|
||||
window.onload = function () {
|
||||
featureToggles.onLoad();
|
||||
//featureToggles.onLoad();
|
||||
|
||||
ToolManager.currentTool().updateCursor();
|
||||
|
||||
|
143
js/tools/EllipseTool.js
Normal file
143
js/tools/EllipseTool.js
Normal file
@ -0,0 +1,143 @@
|
||||
class EllipseTool extends DrawingTool {
|
||||
// Saving the empty rect svg
|
||||
emptyEllipseSVG = document.getElementById("ellipse-empty-button-svg");
|
||||
// and the full rect svg so that I can change them when the user changes rect modes
|
||||
fullEllipseSVG = document.getElementById("ellipse-full-button-svg");
|
||||
// Current fill mode
|
||||
currFillMode = 'empty';
|
||||
|
||||
switchFunction = null;
|
||||
|
||||
constructor(name, options, switchFunction) {
|
||||
super(name, options);
|
||||
|
||||
this.switchFunction = switchFunction;
|
||||
Events.on('click', this.mainButton, this.changeFillType.bind(this));
|
||||
Events.on('click', this.biggerButton, this.increaseSize.bind(this));
|
||||
Events.on('click', this.smallerButton, this.decreaseSize.bind(this));
|
||||
}
|
||||
|
||||
changeFillType() {
|
||||
if (this.isSelected)
|
||||
if (this.currFillMode == 'empty') {
|
||||
this.currFillMode = 'fill';
|
||||
this.emptyEllipseSVG.setAttribute('display', 'none');
|
||||
this.fullEllipseSVG.setAttribute('display', 'visible');
|
||||
}
|
||||
else {
|
||||
this.currFillMode = 'empty'
|
||||
this.emptyEllipseSVG.setAttribute('display', 'visible');
|
||||
this.fullEllipseSVG.setAttribute('display', 'none');
|
||||
}
|
||||
else
|
||||
this.switchFunction(this);
|
||||
}
|
||||
|
||||
onStart(mousePos) {
|
||||
super.onStart(mousePos);
|
||||
|
||||
// Putting the tmp layer on top of everything
|
||||
currFile.TMPLayer.canvas.style.zIndex = parseInt(currFile.currentLayer.canvas.style.zIndex, 10) + 1;
|
||||
|
||||
this.startMousePos[0] = Math.floor(mousePos[0] / currFile.zoom) + 0.5;
|
||||
this.startMousePos[1] = Math.floor(mousePos[1] / currFile.zoom) + 0.5;
|
||||
|
||||
new HistoryState().EditCanvas();
|
||||
}
|
||||
|
||||
onDrag(mousePos, cursorTarget) {
|
||||
|
||||
// Drawing the rect at the right position
|
||||
this.drawRect(Math.floor(mousePos[0] / currFile.zoom) + 0.5, Math.floor(mousePos[1] / currFile.zoom) + 0.5);
|
||||
}
|
||||
|
||||
/** Finishes drawing the rect, decides the end coordinates and moves the preview rectangle to the
|
||||
* current layer
|
||||
*
|
||||
* @param {*} mousePos The position of the mouse when the user stopped dragging
|
||||
*/
|
||||
onEnd(mousePos) {
|
||||
super.onEnd(mousePos);
|
||||
let tmpContext = currFile.TMPLayer.context;
|
||||
|
||||
let endRectX = Math.floor(mousePos[0] / currFile.zoom) + 0.5;
|
||||
let endRectY = Math.floor(mousePos[1] / currFile.zoom) + 0.5;
|
||||
let startRectX = this.startMousePos[0];
|
||||
let startRectY = this.startMousePos[1];
|
||||
|
||||
// Inverting end and start (start must always be the top left corner)
|
||||
if (endRectX < startRectX) {
|
||||
let tmp = endRectX;
|
||||
endRectX = startRectX;
|
||||
startRectX = tmp;
|
||||
}
|
||||
// Same for the y
|
||||
if (endRectY < startRectY) {
|
||||
let tmp = endRectY;
|
||||
endRectY = startRectY;
|
||||
startRectY = tmp;
|
||||
}
|
||||
|
||||
// Drawing the rect
|
||||
startRectY -= 0.5;
|
||||
endRectY -= 0.5;
|
||||
endRectX -= 0.5;
|
||||
startRectX -= 0.5;
|
||||
|
||||
// Setting the correct linewidth and colour
|
||||
currFile.currentLayer.context.lineWidth = this.currSize;
|
||||
|
||||
// Drawing the rect using 4 lines
|
||||
currFile.currentLayer.drawLine(startRectX, startRectY, endRectX, startRectY, this.currSize);
|
||||
currFile.currentLayer.drawLine(endRectX, startRectY, endRectX, endRectY, this.currSize);
|
||||
currFile.currentLayer.drawLine(endRectX, endRectY, startRectX, endRectY, this.currSize);
|
||||
currFile.currentLayer.drawLine(startRectX, endRectY, startRectX, startRectY, this.currSize);
|
||||
|
||||
// If I have to fill it, I do so
|
||||
if (this.currFillMode == 'fill') {
|
||||
currFile.currentLayer.context.fillRect(startRectX, startRectY, endRectX - startRectX, endRectY - startRectY);
|
||||
}
|
||||
|
||||
// Update the layer preview
|
||||
currFile.currentLayer.updateLayerPreview();
|
||||
// Clearing the tmp canvas
|
||||
tmpContext.clearRect(0, 0, currFile.TMPLayer.canvas.width, currFile.TMPLayer.canvas.height);
|
||||
}
|
||||
|
||||
onSelect() {
|
||||
super.onSelect();
|
||||
}
|
||||
|
||||
onDeselect() {
|
||||
super.onDeselect();
|
||||
}
|
||||
|
||||
/** Draws a rectangle with end coordinates given by x and y on the tmp layer (draws
|
||||
* the preview for the rectangle tool)
|
||||
*
|
||||
* @param {*} x The current end x of the rectangle
|
||||
* @param {*} y The current end y of the rectangle
|
||||
*/
|
||||
drawRect(x, y) {
|
||||
// Getting the tmp context
|
||||
let tmpContext = currFile.TMPLayer.context;
|
||||
|
||||
// Clearing the tmp canvas
|
||||
tmpContext.clearRect(0, 0, currFile.TMPLayer.canvas.width, currFile.TMPLayer.canvas.height);
|
||||
|
||||
// Drawing the rect
|
||||
tmpContext.lineWidth = this.currSize;
|
||||
|
||||
// Drawing the rect
|
||||
tmpContext.beginPath();
|
||||
if ((this.currSize % 2 ) == 0) {
|
||||
tmpContext.rect(this.startMousePos[0] - 0.5, this.startMousePos[1] - 0.5, x - this.startMousePos[0], y - this.startMousePos[1]);
|
||||
}
|
||||
else {
|
||||
tmpContext.rect(this.startMousePos[0], this.startMousePos[1], x - this.startMousePos[0], y - this.startMousePos[1]);
|
||||
}
|
||||
|
||||
tmpContext.setLineDash([]);
|
||||
tmpContext.stroke();
|
||||
}
|
||||
}
|
@ -1,144 +0,0 @@
|
||||
// Saving the empty rect svg
|
||||
var emptyEllipseSVG = document.getElementById("ellipse-empty-button-svg");
|
||||
// and the full rect svg so that I can change them when the user changes rect modes
|
||||
var fullEllipseSVG = document.getElementById("ellipse-full-button-svg");
|
||||
|
||||
// The start mode is empty ellipse
|
||||
var ellipseDrawMode = 'empty';
|
||||
// I'm not drawing a ellipse at the beginning
|
||||
var isDrawingEllipse = false;
|
||||
|
||||
// Ellipse coordinates
|
||||
let startEllipseX;
|
||||
let startEllipseY;
|
||||
let endEllipseX;
|
||||
let endEllipseY;
|
||||
|
||||
// TODO: [ELLIPSE] Make it draw ellipse instead of copy-pasted rectangle
|
||||
/** Starts drawing the ellipse, saves the start coordinates
|
||||
*
|
||||
* @param {*} mouseEvent
|
||||
*/
|
||||
function startEllipseDrawing(mouseEvent) {
|
||||
// Putting the vfx layer on top of everything
|
||||
VFXLayer.canvas.style.zIndex = parseInt(currentLayer.canvas.style.zIndex, 10) + 1;;
|
||||
// Updating flag
|
||||
isDrawingEllipse = true;
|
||||
|
||||
// Saving the start coords of the ellipse
|
||||
let cursorPos = Input.getCursorPosition(mouseEvent);
|
||||
startEllipseX = Math.floor(cursorPos[0] / zoom) + 0.5;
|
||||
startEllipseY = Math.floor(cursorPos[1] / zoom) + 0.5;
|
||||
|
||||
drawEllipse(startEllipseX, startEllipseY);
|
||||
}
|
||||
|
||||
// TODO: [ELLIPSE] Make it draw ellipse instead of copy-pasted rectangle
|
||||
/** Updates the ellipse preview depending on the position of the mouse
|
||||
*
|
||||
* @param {*} mouseEvent The mouseEvent from which we'll get the mouse position
|
||||
*/
|
||||
function updateEllipseDrawing(mouseEvent) {
|
||||
let pos = Input.getCursorPosition(mouseEvent);
|
||||
|
||||
// Drawing the ellipse at the right position
|
||||
drawEllipse(Math.round(pos[0] / zoom) + 0.5, Math.round(pos[1] / zoom) + 0.5);
|
||||
}
|
||||
|
||||
// TODO: [ELLIPSE] Make it draw ellipse instead of copy-pasted rectangle
|
||||
/** Finishes drawing the ellipse, decides the end coordinates and moves the preview ellipse to the
|
||||
* current layer
|
||||
*
|
||||
* @param {*} mouseEvent event from which we'll get the mouse position
|
||||
*/
|
||||
function endEllipseDrawing(mouseEvent) {
|
||||
// Getting the end position
|
||||
let currentPos = Input.getCursorPosition(mouseEvent);
|
||||
let vfxContext = VFXLayer.context;
|
||||
|
||||
endEllipseX = Math.round(currentPos[0] / zoom) + 0.5;
|
||||
endEllipseY = Math.round(currentPos[1] / zoom) + 0.5;
|
||||
|
||||
// Inverting end and start (start must always be the top left corner)
|
||||
if (endEllipseX < startEllipseX) {
|
||||
let tmp = endEllipseX;
|
||||
endEllipseX = startEllipseX;
|
||||
startEllipseX = tmp;
|
||||
}
|
||||
// Same for the y
|
||||
if (endEllipseY < startEllipseY) {
|
||||
let tmp = endEllipseY;
|
||||
endEllipseY = startEllipseY;
|
||||
startEllipseY = tmp;
|
||||
}
|
||||
|
||||
// Resetting this
|
||||
isDrawingEllipse = false;
|
||||
// Drawing the ellipse
|
||||
startEllipseY -= 0.5;
|
||||
endEllipseY -= 0.5;
|
||||
endEllipseX -= 0.5;
|
||||
startEllipseX -= 0.5;
|
||||
|
||||
// Setting the correct linewidth
|
||||
currentLayer.context.lineWidth = tool.ellipse.brushSize;
|
||||
|
||||
// Drawing the ellipse using 4 lines
|
||||
currentLayer.drawLine(startEllipseX, startEllipseY, endEllipseX, startEllipseY, tool.ellipse.brushSize);
|
||||
currentLayer.drawLine(endEllipseX, startEllipseY, endEllipseX, endEllipseY, tool.ellipse.brushSize);
|
||||
currentLayer.drawLine(endEllipseX, endEllipseY, startEllipseX, endEllipseY, tool.ellipse.brushSize);
|
||||
currentLayer.drawLine(startEllipseX, endEllipseY, startEllipseX, startEllipseY, tool.ellipse.brushSize);
|
||||
|
||||
// If I have to fill it, I do so
|
||||
if (ellipseDrawMode == 'fill') {
|
||||
currentLayer.context.fillRect(startEllipseX, startEllipseY, endEllipseX - startEllipseX, endEllipseY - startEllipseY);
|
||||
}
|
||||
|
||||
// Clearing the vfx canvas
|
||||
vfxContext.clearRect(0, 0, VFXLayer.canvas.width, VFXLayer.canvas.height);
|
||||
}
|
||||
|
||||
// TODO: [ELLIPSE] Make it draw ellipse instead of copy-pasted rectangle
|
||||
/** Draws a ellipse with end coordinates given by x and y on the VFX layer (draws
|
||||
* the preview for the ellipse tool)
|
||||
*
|
||||
* @param {*} x The current end x of the ellipse
|
||||
* @param {*} y The current end y of the ellipse
|
||||
*/
|
||||
function drawEllipse(x, y) {
|
||||
// Getting the vfx context
|
||||
let vfxContext = VFXLayer.context;
|
||||
|
||||
// Clearing the vfx canvas
|
||||
vfxContext.clearRect(0, 0, VFXLayer.canvas.width, VFXLayer.canvas.height);
|
||||
|
||||
// Drawing the ellipse
|
||||
vfxContext.lineWidth = tool.ellipse.brushSize;
|
||||
|
||||
// Drawing the ellipse
|
||||
vfxContext.beginPath();
|
||||
if ((tool.ellipse.brushSize % 2 ) == 0) {
|
||||
vfxContext.rect(startEllipseX - 0.5, startEllipseY - 0.5, x - startEllipseX, y - startEllipseY);
|
||||
}
|
||||
else {
|
||||
vfxContext.rect(startEllipseX, startEllipseY, x - startEllipseX, y - startEllipseY);
|
||||
}
|
||||
|
||||
vfxContext.setLineDash([]);
|
||||
vfxContext.stroke();
|
||||
}
|
||||
|
||||
/** Sets the correct tool icon depending on its mode
|
||||
*
|
||||
*/
|
||||
function setEllipseToolSvg() {
|
||||
console.log("set eilipse svg");
|
||||
if (ellipseDrawMode == 'empty') {
|
||||
emptyEllipseSVG.setAttribute('display', 'visible');
|
||||
fullEllipseSVG.setAttribute('display', 'none');
|
||||
}
|
||||
else {
|
||||
emptyEllipseSVG.setAttribute('display', 'none');
|
||||
fullEllipseSVG.setAttribute('display', 'visible');
|
||||
}
|
||||
}
|
@ -1,6 +1,9 @@
|
||||
<svg width="512" height="512" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg">
|
||||
<g>
|
||||
<ellipse stroke="#000" stroke-width="32" fill="none" cx="255.50001" cy="255.5" id="svg_20" rx="239" ry="187.5"/>
|
||||
</g>
|
||||
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 18 18" style="enable-background:new 0 0 17 17;" xml:space="preserve">
|
||||
<g>
|
||||
<ellipse cx="9" cy="9" rx="7.5" ry="6.2" stroke="black" stroke-width="2" fill="none" fill-opacity="0"/>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 221 B After Width: | Height: | Size: 471 B |
@ -1,22 +1,8 @@
|
||||
<svg width="512" height="512" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg">
|
||||
<g>
|
||||
<title>Layer 1</title>
|
||||
<g id="svg_4"/>
|
||||
<g id="svg_5"/>
|
||||
<g id="svg_6"/>
|
||||
<g id="svg_7"/>
|
||||
<g id="svg_8"/>
|
||||
<g id="svg_9"/>
|
||||
<g id="svg_10"/>
|
||||
<g id="svg_11"/>
|
||||
<g id="svg_12"/>
|
||||
<g id="svg_13"/>
|
||||
<g id="svg_14"/>
|
||||
<g id="svg_15"/>
|
||||
<g id="svg_16"/>
|
||||
<g id="svg_17"/>
|
||||
<g id="svg_18"/>
|
||||
<ellipse stroke="#000" stroke-width="32" fill="#000000" cx="255.50001" cy="255.5" id="svg_20" rx="239" ry="187.5"/>
|
||||
</g>
|
||||
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 18 18" style="enable-background:new 0 0 17 17;" xml:space="preserve">
|
||||
<g>
|
||||
<ellipse stroke="none" cx="9" cy="9" rx="8.5" ry="7.2"/>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 528 B After Width: | Height: | Size: 422 B |
@ -24,10 +24,7 @@
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<!-- TODO: [ELLIPSE] Once ellipse is ready for release make it visible by default -->
|
||||
<li class="expanded" id="tools-menu--ellipse" style="display: none">
|
||||
<!-- TODO: [ELLIPSE] Decide on a shortcut to use. "S" was chosen without any in-team consultation. -->
|
||||
<!-- TODO: [ELLIPSE] Decide on icons to use. Current ones are quickly prepared drafts and display with incorrect color. -->
|
||||
<li class="expanded">
|
||||
<button title="Ellipse Tool (S)" id="ellipse-button">
|
||||
{{svg "ellipse.svg" width="24" height="24" id = "ellipse-empty-button-svg"}}
|
||||
{{svg "filledellipse.svg" width="24" height="24" id = "ellipse-full-button-svg" display = "none"}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user