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;
|
z-index:0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#tools-menu li button path {
|
#tools-menu li button path, #tools-menu li button ellipse {
|
||||||
fill: $baseicon;
|
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;
|
fill: $basehovericon;
|
||||||
|
stroke: $basehovericon;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -41,7 +43,7 @@
|
|||||||
background: $baseselected !important;
|
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;
|
fill: $baseselectedicon;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
const featureToggles = (function featureTogglesModule() {
|
/*const featureToggles = (function featureTogglesModule() {
|
||||||
|
|
||||||
const ellipseToolLocalStorageKey = 'feature_ellipseTool';
|
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["eraser"] = new EraserTool("eraser", {type: 'html'}, switchTool);
|
||||||
tools["rectangle"] = new RectangleTool("rectangle", {type: 'html'}, switchTool);
|
tools["rectangle"] = new RectangleTool("rectangle", {type: 'html'}, switchTool);
|
||||||
tools["line"] = new LineTool("line", {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["fill"] = new FillTool("fill", {type: 'cursor', style: 'crosshair'}, switchTool);
|
||||||
|
|
||||||
tools["eyedropper"] = new EyeDropperTool("eyedropper", {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/EraserTool.js
|
||||||
//=include tools/LineTool.js
|
//=include tools/LineTool.js
|
||||||
//=include tools/RectangleTool.js
|
//=include tools/RectangleTool.js
|
||||||
|
//=include tools/EllipseTool.js
|
||||||
//=include tools/FillTool.js
|
//=include tools/FillTool.js
|
||||||
//=include tools/EyeDropperTool.js
|
//=include tools/EyeDropperTool.js
|
||||||
//=include tools/PanTool.js
|
//=include tools/PanTool.js
|
||||||
@ -69,7 +70,7 @@ PresetModule.instrumentPresetMenu();
|
|||||||
|
|
||||||
//when the page is done loading, you can get ready to start
|
//when the page is done loading, you can get ready to start
|
||||||
window.onload = function () {
|
window.onload = function () {
|
||||||
featureToggles.onLoad();
|
//featureToggles.onLoad();
|
||||||
|
|
||||||
ToolManager.currentTool().updateCursor();
|
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>
|
</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">
|
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||||
<g>
|
<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
<title>Layer 1</title>
|
<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"
|
||||||
<g id="svg_4"/>
|
viewBox="0 0 18 18" style="enable-background:new 0 0 17 17;" xml:space="preserve">
|
||||||
<g id="svg_5"/>
|
<g>
|
||||||
<g id="svg_6"/>
|
<ellipse stroke="none" cx="9" cy="9" rx="8.5" ry="7.2"/>
|
||||||
<g id="svg_7"/>
|
</g>
|
||||||
<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>
|
|
||||||
|
|
||||||
</svg>
|
</svg>
|
Before Width: | Height: | Size: 528 B After Width: | Height: | Size: 422 B |
@ -24,10 +24,7 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<!-- TODO: [ELLIPSE] Once ellipse is ready for release make it visible by default -->
|
<li class="expanded">
|
||||||
<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. -->
|
|
||||||
<button title="Ellipse Tool (S)" id="ellipse-button">
|
<button title="Ellipse Tool (S)" id="ellipse-button">
|
||||||
{{svg "ellipse.svg" width="24" height="24" id = "ellipse-empty-button-svg"}}
|
{{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"}}
|
{{svg "filledellipse.svg" width="24" height="24" id = "ellipse-full-button-svg" display = "none"}}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user