From 501a8c13eb59274744c7a4b591122d3af5d0051c Mon Sep 17 00:00:00 2001 From: Mark MacKay Date: Mon, 28 Jun 2021 16:02:21 -0500 Subject: [PATCH] support for userSpaceOnUse gradients --- src/css/jgraduate.css | 18 +++++++++++++++ src/js/PaintBox.js | 42 ++++++++++++++++++++++++++++++---- src/js/lib/jquery.jgraduate.js | 4 +++- src/js/svgcanvas.js | 2 ++ 4 files changed, 61 insertions(+), 5 deletions(-) diff --git a/src/css/jgraduate.css b/src/css/jgraduate.css index dea7ba2..5129279 100644 --- a/src/css/jgraduate.css +++ b/src/css/jgraduate.css @@ -23,6 +23,24 @@ color: var(--z8); } + +/* Remove editing options for radial gradients with userspaceonuse which will do nothing */ + #color_picker.radialUserSpace div.grad_coord, + #color_picker.radialUserSpace .jGraduate_Form { + display: none !important; + } + + #color_picker.radialUserSpace .jGraduate_gradPick:after { + content: 'Click on the color drops to change the color of the gradient'; + position: absolute; + right: var(--x8); + width: 250px; + color: var(--z12); + bottom: 50%; + font-size: 1.2em; + line-height: 1.5em; + } + #color_picker input { color: var(--z14); } diff --git a/src/js/PaintBox.js b/src/js/PaintBox.js index e727403..1386020 100644 --- a/src/js/PaintBox.js +++ b/src/js/PaintBox.js @@ -14,9 +14,13 @@ MD.PaintBox = function(container, type){ if (!e.target.closest("#color_picker")) $("#color_picker").hide(); }) + + const unsupportedGradient = getUnsupportedGradient(picker); $("#color_picker") .removeAttr("style") + .toggleClass("radialUserSpace", unsupportedGradient) + .attr("data-radialUserSpace", Boolean(unsupportedGradient)) .css(pos) .jGraduate( { @@ -27,10 +31,17 @@ MD.PaintBox = function(container, type){ }, function(p) { paint = new $.jGraduate.Paint(p); - editor.paintBox[picker].setPaint(paint, true); - svgCanvas.setPaint(picker, paint); - //if (paint.radialGradient) paint.radialGradient = paint.radialGradient.outerHTML - //if (paint.linearGradient) paint.linearGradient = paint.linearGradient.outerHTML + if (unsupportedGradient) { + // remove current gradient stops + while (unsupportedGradient.firstChild) unsupportedGradient.removeChild(unsupportedGradient.lastChild); + Array.from(paint.radialGradient.children).forEach(stop => { + unsupportedGradient.appendChild(stop); + }); + } + else { + editor.paintBox[picker].setPaint(paint, true); + svgCanvas.setPaint(picker, paint); + } if (picker === "fill") state.set("canvasFill", paint); if (picker === "stroke") state.set("canvasStroke", paint); if (picker === "canvas") state.set("canvasBackground", paint); @@ -61,6 +72,27 @@ MD.PaintBox = function(container, type){ this.paint = new $.jGraduate.Paint({solidColor: cur.color}); this.type = type; + function getUnsupportedGradient(type){ + const selectedElems = svgCanvas.getSelectedElems().filter(Boolean); + if (!selectedElems.length) return false; + const elem = selectedElems[0]; + // fill or stroke + var url = elem.getAttribute(type); + if (url.includes("(")) { + url = url.split("(")[1].split(")")[0]; + } + // not a gradient + else return false; + const originalGradient = svgCanvas.svgroot.querySelector(url); + if (!originalGradient) return false + const isRadial = originalGradient.tagName === "radialGradient" + // not a radial gradient + if (!isRadial) return false; + const isUserSpaceOnUse = originalGradient.getAttribute("gradientUnits") === "userSpaceOnUse"; + if (!isUserSpaceOnUse) return false; + return originalGradient; + } + this.setPaint = function(paint, apply, noUndo) { this.paint = paint; var fillAttr = "none"; @@ -81,6 +113,7 @@ MD.PaintBox = function(container, type){ this.grad = this.defs.appendChild(paint[ptype]); var id = this.grad.id = 'gradbox_' + this.type; fillAttr = "url(#" + id + ')'; + if (this.grad.getAttribute('gradientUnits') === "userSpaceOnUse") { const gradient = this.grad; ["userSpaceOnUse", "gradientTransform", "gradientUnits", "cx", "cy", "fx", "fy", "r"].forEach(attr => { @@ -96,6 +129,7 @@ MD.PaintBox = function(container, type){ } if(apply) { + svgCanvas.setColor(this.type, fillAttr, true); svgCanvas.setPaintOpacity(this.type, opac, true); } diff --git a/src/js/lib/jquery.jgraduate.js b/src/js/lib/jquery.jgraduate.js index b836730..417d12f 100644 --- a/src/js/lib/jquery.jgraduate.js +++ b/src/js/lib/jquery.jgraduate.js @@ -853,7 +853,7 @@ jQuery.fn.jGraduate = // bind GUI elements $('#'+id+'_jGraduate_Ok').bind('click touchstart', function() { $this.paint.type = curType; - $this.paint[curType] = curGradient.cloneNode(true);; + $this.paint[curType] = curGradient.cloneNode(true); $this.paint.solidColor = null; okClicked(); }); @@ -1134,6 +1134,8 @@ jQuery.fn.jGraduate = var type = $(this).attr('data-type'); var container = $(idref + ' .jGraduate_gradPick').show(); if(type === 'rg' || type === 'lg') { + const isRadialUserSpaceOnUse = $("#color_picker").attr("data-radialUserSpace") === "true"; + $("#color_picker").toggleClass("radialUserSpace", isRadialUserSpaceOnUse && type === 'rg'); // Show/hide appropriate fields $('.jGraduate_' + type + '_field').show(); $('.jGraduate_' + (type === 'lg' ? 'rg' : 'lg') + '_field').hide(); diff --git a/src/js/svgcanvas.js b/src/js/svgcanvas.js index 1204987..3a728e6 100644 --- a/src/js/svgcanvas.js +++ b/src/js/svgcanvas.js @@ -6885,11 +6885,13 @@ var findDefs = function() { // Parameters // type - String indicating "fill" or "stroke" to apply to an element var setGradient = this.setGradient = function(type) { + if(!cur_properties[type + '_paint'] || cur_properties[type + '_paint'].type == "solidColor") return; var grad = canvas[type + 'Grad']; // find out if there is a duplicate gradient already in the defs var duplicate_grad = findDuplicateGradient(grad); var defs = findDefs(); + // no duplicate found, so import gradient into defs if (!duplicate_grad) { var orig_grad = grad;