Created
July 28, 2017 07:10
-
-
Save cajus/9e99c497a0717afe5231a25091c4a857 to your computer and use it in GitHub Desktop.
Playground snippet for making radial gradient decorators
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
qx.Mixin.define("foo.MRadialBackgroundGradient", | |
{ | |
/* | |
***************************************************************************** | |
PROPERTIES | |
***************************************************************************** | |
*/ | |
properties : | |
{ | |
/** | |
* Start color of the background gradient. | |
* Note that alpha transparency (rgba) is not supported in IE 8. | |
*/ | |
radialStartColor : | |
{ | |
check : "Color", | |
nullable : true, | |
apply : "_applyRadialBackgroundGradient" | |
}, | |
/** | |
* End color of the background gradient. | |
* Note that alpha transparency (rgba) is not supported in IE 8. | |
*/ | |
radialEndColor : | |
{ | |
check : "Color", | |
nullable : true, | |
apply : "_applyRadialBackgroundGradient" | |
}, | |
/** The orientation of the gradient. */ | |
shape : | |
{ | |
check : ["circle", "ellipse"], | |
init : "ellipse", | |
apply : "_applyRadialBackgroundGradient" | |
}, | |
/** The orientation of the gradient. */ | |
radialMode : | |
{ | |
check : ["cover", "farthest-corner", "farthest-side", "closest-corner", "closest-side"], | |
init : "cover", | |
apply : "_applyRadialBackgroundGradient" | |
}, | |
/** The orientation of the gradient. */ | |
positionX : | |
{ | |
check : "Integer", | |
init : null, | |
nullable : true, | |
apply : "_applyRadialBackgroundGradient" | |
}, | |
/** The orientation of the gradient. */ | |
positionY : | |
{ | |
check : "Integer", | |
init : null, | |
nullable : true, | |
apply : "_applyRadialBackgroundGradient" | |
}, | |
/** Property group to set the start color including its start position. */ | |
position : | |
{ | |
group : ["positionX", "positionY"], | |
mode : "shorthand" | |
}, | |
/** Position in percent where to start the color. */ | |
radialStartColorPosition : | |
{ | |
check : "Number", | |
init : 0, | |
apply : "_applyRadialBackgroundGradient" | |
}, | |
/** Position in percent where to start the color. */ | |
radialEndColorPosition : | |
{ | |
check : "Number", | |
init : 100, | |
apply : "_applyRadialBackgroundGradient" | |
}, | |
/** Defines if the given positions are in % or px.*/ | |
radialColorPositionUnit : | |
{ | |
check : ["px", "%"], | |
init : "%", | |
apply : "_applyRadialBackgroundGradient" | |
} | |
}, | |
/* | |
***************************************************************************** | |
MEMBERS | |
***************************************************************************** | |
*/ | |
members : | |
{ | |
__rcanvas : null, | |
/** | |
* Takes a styles map and adds the radial background styles in place to the | |
* given map. This is the needed behavior for | |
* {@link qx.ui.decoration.Decorator}. | |
* | |
* @param styles {Map} A map to add the styles. | |
*/ | |
_styleRadialBackgroundGradient : function(styles) | |
{ | |
var colors = this.__getRadialColors(); | |
var radialStartColor = colors.start; | |
var radialEndColor = colors.end; | |
var value; | |
if (!radialStartColor || !radialEndColor) { | |
return; | |
} | |
var unit = this.getRadialColorPositionUnit(); | |
var where = ""; | |
// new implementation for webkit is available since chrome 10 --> version | |
if (qx.core.Environment.get("css.gradient.legacywebkit")) | |
{ | |
// webkit uses px values if non are given | |
unit = unit === "px" ? "" : unit; | |
if (this.getPositionY()) { | |
where += this.getPositionY(); | |
} | |
if (this.getPositionX()) { | |
where += where === "" ? this.getPositionX() : " " + this.getPositionX(); | |
} | |
if (where === "") { | |
where = "center"; | |
} | |
value = "-webkit-gradient(" + where + "," + this.getShape() + " " + this.getRadialMode() + "," + radialStartColor + " " + this.getRadialStartColorPosition() + unit + "," + radialEndColor + " " + this.getRadialEndColorPosition() + unit + ")"; | |
styles.background = value; | |
// IE9 canvas solution | |
} else if (qx.core.Environment.get("css.gradient.filter") && !qx.core.Environment.get("css.gradient.radial") && qx.core.Environment.get("css.borderradius")) | |
{ | |
if (!this.__rcanvas) { | |
this.__rcanvas = document.createElement("canvas"); | |
} | |
var radius = 200; | |
var range = Math.max(100, this.getRadialEndColorPosition() - this.getRadialStartColorPosition()); | |
//// use the px difference as dimension | |
if (unit === "px") { | |
radius = Math.max(radius, this.getRadialEndColorPosition() - this.getRadialStartColorPosition()); | |
} else { | |
radius = Math.max(radius, (this.getRadialEndColorPosition() - this.getRadialStartColorPosition()) * 2); | |
} | |
this.__rcanvas.width = radius * 2; | |
this.__rcanvas.height = radius * 2; | |
var ctx = this.__rcanvas.getContext('2d'); | |
var radgrad = ctx.createRadialGradient(radius, radius, 0, radius, radius, radius); | |
// don't allow negative start values | |
if (unit === "%") | |
{ | |
radgrad.addColorStop(Math.max(0, this.getRadialStartColorPosition()) / range, colors.start); | |
radgrad.addColorStop(this.getRadialEndColorPosition() / range, colors.end); | |
} else | |
{ | |
radgrad.addColorStop(Math.max(0, this.getRadialStartColorPosition()) / radius, colors.start); | |
radgrad.addColorStop(this.getRadialEndColorPosition() / radius, colors.end); | |
} | |
ctx.fillStyle = radgrad; | |
ctx.fillRect(0, 0, radius * 2, radius * 2); | |
styles["background-image"] = "url(" + this.__rcanvas.toDataURL() + ")"; | |
if (unit === "%") { | |
styles["background-size"] = range + "% " + range + "%"; | |
} else { | |
styles["background-size"] = radius + "px " + radius + "px"; | |
} | |
} else if (!(qx.core.Environment.get("css.gradient.filter") && !qx.core.Environment.get("css.gradient.radial"))) | |
{ | |
// WebKit, Opera and Gecko interpret 0deg as "to right" | |
var prefixedName = qx.core.Environment.get("css.gradient.radial"); | |
where = ""; | |
if (this.getPositionY()) { | |
where += "at " + this.getPositionY(); | |
} | |
if (this.getPositionX()) { | |
where += where === "" ? "at " + this.getPositionX() : " " + this.getPositionX(); | |
} | |
value = prefixedName + "(" + this.getShape() + " " + this.getRadialMode() + where + "," + radialStartColor + " " + this.getRadialStartColorPosition() + unit + "," + radialEndColor + " " + this.getRadialEndColorPosition() + unit + ")"; | |
if (styles["background-image"]) { | |
styles["background-image"] += ", " + value; | |
} else { | |
styles["background-image"] = value; | |
} | |
} | |
}, | |
/** | |
* Helper to get start and end color. | |
* @return {Map} A map containing start and end color. | |
*/ | |
__getRadialColors : function() | |
{ | |
var radialStartColor, radialEndColor; | |
if (qx.core.Environment.get("qx.theme")) | |
{ | |
var color = qx.theme.manager.Color.getInstance(); | |
radialStartColor = color.resolve(this.getRadialStartColor()); | |
radialEndColor = color.resolve(this.getRadialEndColor()); | |
} else | |
{ | |
radialStartColor = this.getRadialStartColor(); | |
radialEndColor = this.getRadialEndColor(); | |
} | |
return { | |
start : radialStartColor, | |
end : radialEndColor | |
}; | |
}, | |
// property apply | |
_applyRadialBackgroundGradient : function() { | |
if (qx.core.Environment.get("qx.debug")) { | |
if (this._isInitialized()) { | |
throw new Error("This decorator is already in-use. Modification is not possible anymore!"); | |
} | |
} | |
} | |
} | |
}); | |
// Needed to make it run multiple times in the playground | |
try { | |
qx.Class.patch(qx.ui.decoration.Decorator, foo.MRadialBackgroundGradient); | |
}catch(e){}; | |
var radial = new qx.ui.decoration.Decorator().set({ | |
width: 0, | |
shadowLength: [0, 2], | |
shadowBlurRadius: 4, | |
shadowSpreadRadius: 2, | |
shadowColor: "rgba(0,0,0,0.5)", | |
radialStartColor: "#FFFF00", | |
radialEndColor: "#00FF00", | |
shape: "ellipse", | |
radius: 6 | |
} | |
); | |
// Create a button | |
var button1 = new qx.ui.form.Button("First Button", "icon/22/apps/internet-web-browser.png"); | |
button1.setDecorator(radial); | |
button1.setPadding(18); | |
// Document is the application root | |
var doc = this.getRoot(); | |
// Add button to document at fixed coordinates | |
doc.add(button1, | |
{ | |
left : 100, | |
top : 50 | |
}); | |
// Add an event listener | |
button1.addListener("execute", function(e) { | |
alert("Hello World!"); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment