function curvyCorners() { if (typeof (arguments[0]) != "object") throw newCurvyError("First parameter of curvyCorners() must be an object."); if (typeof (arguments[1]) != "object" && typeof (arguments[1]) != "string") throw newCurvyError("Second parameter of curvyCorners() must be an object or a class name."); if (typeof (arguments[1]) == "string") { var startIndex = 0; var boxCol = $$("." + arguments[1]) } else { var startIndex = 1; var boxCol = arguments } var curvyCornersCol = new Array(); if (arguments[0].validTags) var validElements = arguments[0].validTags; else var validElements = ["div"]; for (var i = startIndex, j = boxCol.length; i < j; i++) { var currentTag = boxCol[i].tagName.toLowerCase(); if (validElements.indexOf[currentTag] !== -1) curvyCornersCol[curvyCornersCol.length] = new curvyObject(arguments[0], boxCol[i]) } this.objects = curvyCornersCol; this.applyCornersToAll = function() { for (var x = 0, k = this.objects.length; x < k; x++) this.objects[x].applyCorners() } } function curvyObject() { this.box = arguments[1]; this.settings = arguments[0]; this.topContainer = null; this.bottomContainer = null; this.masterCorners = new Array(); this.boxHeight = this.box.getStyle("height").toInt(); this.boxWidth = this.box.getStyle("width").toInt(); this.borderWidth = this.box.getStyle("border-top-width").toInt(); this.boxColor = this.box.getStyle("background-color"); this.boxPadding = this.box.getStyle("padding-top").toInt(); this.borderColor = this.box.getStyle("border-top-color"); this.borderString = this.borderWidth + "px" + " solid " + this.borderColor; this.backgroundImage = this.box.getStyle("background-image"); if (this.box.getStyle("position") != "absolute") this.box.setStyle('position', 'relative'); this.box.setStyle('padding', 0); if (window.opera) { this.boxHeight = this.box.getStyle("height").toInt(); this.boxWidth = this.box.getStyle("width").toInt() } if (this.settings.autoPad === true && this.boxPadding > 0) { var topMaxRadius = Math.max(this.settings.tl ? this.settings.tl.radius : 0, this.settings.tr ? this.settings.tr.radius : 0); var botMaxRadius = Math.max(this.settings.bl ? this.settings.bl.radius : 0, this.settings.br ? this.settings.br.radius : 0); this.box = this.box.clone().empty().injectBefore(this.box).adopt(this.box); var properties = ["style", "class", "name", "id"]; for (var i = 0; i < properties.length; i++) this.box.getFirst().removeProperty(properties[i]); this.box.getFirst().setStyles({ 'padding-left': this.boxPadding, 'padding-right': this.boxPadding }); if (topMaxRadius < this.boxPadding) this.box.getFirst().setStyle('padding-top', (topMaxRadius - this.boxPadding)); if (botMaxRadius < this.boxPadding) this.box.getFirst().setStyle('padding-bottom', (botMaxRadius - this.boxPadding)) } this.applyCorners = function() { if (this.settings.tl || this.settings.tr) { var topMaxRadius = Math.max(this.settings.tl ? this.settings.tl.radius : 0, this.settings.tr ? this.settings.tr.radius : 0); var topMainContainer = new Element('div', { 'styles': { 'width': '100%', 'fontSize': '1px', 'overflow': 'hidden', 'position': 'absolute', 'paddingLeft': this.borderWidth, 'paddingRight': this.borderWidth, 'height': topMaxRadius, 'top': -topMaxRadius, 'left': -this.borderWidth} }); this.topContainer = topMainContainer.injectTop(this.box) } if (this.settings.bl || this.settings.br) { var botMaxRadius = Math.max(this.settings.bl ? this.settings.bl.radius : 0, this.settings.br ? this.settings.br.radius : 0); var botMainContainer = new Element('div', { 'styles': { 'width': '100%', 'fontSize': '1px', 'overflow': 'hidden', 'position': 'absolute', 'paddingLeft': this.borderWidth, 'paddingRight': this.borderWidth, 'height': botMaxRadius, 'bottom': -botMaxRadius, 'left': -this.borderWidth} }); this.bottomContainer = botMainContainer.injectInside(this.box) } if (this.topContainer) this.box.style.borderTopWidth = "0px"; if (this.bottomContainer) this.box.style.borderBottomWidth = "0px"; var corners = ["tr", "tl", "br", "bl"]; for (var i in corners) { var cc = corners[i]; if (!this.settings[cc]) { if (((cc == "tr" || cc == "tl") && this.topContainer != null) || ((cc == "br" || cc == "bl") && this.bottomContainer != null)) { var newCorner = new Element('div', { 'styles': { 'position': 'relative', 'fontSize': '1px', 'overflow': 'hidden'} }); if (this.backgroundImage == "none") newCorner.setStyle('background-color', this.boxColor); else newCorner.setStyle('background-image', this.backgroundImage); switch (cc) { case "tl": newCorner.setStyles({ 'height': topMaxRadius - this.borderWidth, 'margin-right': this.settings.tr.radius - (this.borderWidth * 2), 'border-left': this.borderString, 'border-top': this.borderString, 'left': -this.borderWidth }); break; case "tr": newCorner.setStyles({ 'height': topMaxRadius - this.borderWidth, 'margin-left': this.settings.tl.radius - (this.borderWidth * 2), 'border-right': this.borderString, 'border-top': this.borderString, 'background-position': -(topMaxRadius + this.borderWidth) + "px 0px", 'left': this.borderWidth }); break; case "bl": newCorner.setStyles({ 'height': botMaxRadius - this.borderWidth, 'margin-right': this.settings.br.radius - (this.borderWidth * 2), 'border-left': this.borderString, 'border-bottom': this.borderString, 'background-position': (-this.borderWidth) + "px " + (-this.boxHeight - botMaxRadius - this.borderWidth) + "px", 'left': this.borderWidth }); break; case "br": newCorner.setStyles({ 'height': botMaxRadius - this.borderWidth, 'margin-left': this.settings.bl.radius - (this.borderWidth * 2), 'border-right': this.borderString, 'border-bottom': this.borderString, 'background-position': (-width + botMaxRadius + this.borderWidth) + "px " + (-this.boxHeight - botMaxRadius - this.borderWidth) + "px", 'left': this.borderWidth }); break } } } else { if (this.masterCorners[this.settings[cc].radius]) { var newCorner = this.masterCorners[this.settings[cc].radius].cloneNode(true) } else { var newCorner = new Element('div', { 'styles': { 'height': this.settings[cc].radius, 'width': this.settings[cc].radius, 'position': 'absolute', 'overflow': 'visible'} }); var borderRadius = this.settings[cc].radius - this.borderWidth; for (var intx = 0, j = this.settings[cc].radius; intx < j; intx++) { if ((intx + 1) >= borderRadius) var y1 = -1; else var y1 = Math.floor(Math.sqrt(Math.pow(borderRadius, 2) - Math.pow((intx + 1), 2))) - 1; if (borderRadius != j) { if (intx >= borderRadius) var y2 = -1; else var y2 = Math.ceil(Math.sqrt(Math.pow(borderRadius, 2) - Math.pow(intx, 2))); if ((intx + 1) >= j) var y3 = -1; else var y3 = Math.floor(Math.sqrt(Math.pow(j, 2) - Math.pow((intx + 1), 2))) - 1 } if (intx >= j) var y4 = -1; else var y4 = Math.ceil(Math.sqrt(Math.pow(j, 2) - Math.pow(intx, 2))); if (y1 > -1) this.drawPixel(intx, 0, this.boxColor, 1, (y1 + 1), newCorner, -1, this.settings[cc].radius); if (borderRadius != j) { for (var inty = (y1 + 1); inty < y2; inty++) { if (this.settings.antiAlias) { if (this.backgroundImage != "none") { var borderFract = pixelFraction(intx, inty, borderRadius); if (borderFract < .30) this.drawPixel(intx, inty, this.borderColor, 1, 1, newCorner, 0, this.settings[cc].radius); else this.drawPixel(intx, inty, this.borderColor, 1, 1, newCorner, -1, this.settings[cc].radius) } else { if (this.boxColor == "transparent") { this.drawPixel(intx, inty, this.borderColor, 1 - pixelFraction(intx, inty, borderRadius), 1, newCorner, 0, this.settings[cc].radius) } else { var pixelcolor = new Color(this.borderColor).mix(this.boxColor, pixelFraction(intx, inty, borderRadius) * 100); this.drawPixel(intx, inty, pixelcolor, 1, 1, newCorner, 0, this.settings[cc].radius) } } } } if (this.settings.antiAlias) { if (y3 >= y2) { if (y2 == -1) y2 = 0; this.drawPixel(intx, y2, this.borderColor, 1, (y3 - y2 + 1), newCorner, 0, 0) } } else { if (y3 >= y1) this.drawPixel(intx, (y1 + 1), this.borderColor, 1, (y3 - y1), newCorner, 0, 0) } var outsideColor = this.borderColor } else { var outsideColor = this.boxColor; var y3 = y1 } if (this.settings.antiAlias) { for (var inty = (y3 + 1); inty < y4; inty++) { this.drawPixel(intx, inty, outsideColor, pixelFraction(intx, inty, j), 1, newCorner, ((this.borderWidth > 0) ? 0 : -1), this.settings[cc].radius) } } } this.masterCorners[this.settings[cc].radius] = newCorner.cloneNode(true) } if (cc != "br") { for (var t = 0, k = newCorner.childNodes.length; t < k; t++) { var pixelBar = newCorner.childNodes[t]; var pixelBarTop = pixelBar.getStyle("top").toInt(); var pixelBarLeft = pixelBar.getStyle("left").toInt(); var pixelBarHeight = pixelBar.getStyle("height").toInt(); if (cc == "tl" || cc == "bl") pixelBar.setStyle('left', this.settings[cc].radius - pixelBarLeft - 1); if (cc == "tr" || cc == "tl") pixelBar.setStyle('top', this.settings[cc].radius - pixelBarHeight - pixelBarTop); switch (cc) { case "tr": pixelBar.setStyle('background-position', -Math.abs((this.boxWidth - this.settings[cc].radius + this.borderWidth) + pixelBarLeft) + "px " + -Math.abs(this.settings[cc].radius - pixelBarHeight - pixelBarTop - this.borderWidth) + "px"); break; case "tl": pixelBar.setStyle('background-position', -Math.abs((this.settings[cc].radius - pixelBarLeft - 1) - this.borderWidth) + "px " + -Math.abs(this.settings[cc].radius - pixelBarHeight - pixelBarTop - this.borderWidth) + "px"); break; case "bl": pixelBar.setStyle('background-position', -Math.abs((this.settings[cc].radius - pixelBarLeft - 1) - this.borderWidth) + "px " + -Math.abs((this.boxHeight + this.settings[cc].radius + pixelBarTop) - this.borderWidth) + "px"); break } } } } if (newCorner) { switch (cc) { case "tl": if (newCorner.getStyle('position') == "absolute") { newCorner.setStyle('top', '0px'); newCorner.setStyle('left', '0px') } if (this.topContainer) newCorner.injectInside(this.topContainer); break; case "tr": if (newCorner.getStyle('position') == "absolute") { newCorner.setStyle('top', '0px'); newCorner.setStyle('right', '0px') } if (this.topContainer) newCorner.injectInside(this.topContainer); break; case "bl": if (newCorner.getStyle('position') == "absolute") { newCorner.setStyle('bottom', '0px'); newCorner.setStyle('left', '0px') } if (this.bottomContainer) newCorner.injectInside(this.bottomContainer); break; case "br": if (newCorner.getStyle('position') == "absolute") { newCorner.setStyle('bottom', '0px'); newCorner.setStyle('right', '0px') } if (this.bottomContainer) newCorner.injectInside(this.bottomContainer); break } } } var radiusDiff = new Array(); radiusDiff["t"] = Math.abs(this.settings.tl.radius - this.settings.tr.radius); radiusDiff["b"] = Math.abs(this.settings.bl.radius - this.settings.br.radius); for (var z in radiusDiff) { if (z == "t" || z == "b") { if (radiusDiff[z]) { var smallerCornerType = ((this.settings[z + "l"].radius < this.settings[z + "r"].radius) ? z + "l" : z + "r"); var newFiller = new Element('div', { 'styles': { 'height': radiusDiff[z], 'width': this.settings[smallerCornerType].radius, 'position': 'absolute', 'overflow': 'hidden', 'background-color': this.boxColor} }); switch (smallerCornerType) { case "tl": newFiller.setStyles({ 'bottom': '0px', 'left': '0px', 'border-left': this.borderString }); newFiller.injectInside(this.topContainer); break; case "tr": newFiller.setStyles({ 'bottom': '0px', 'right': '0px', 'border-right': this.borderString }); newFiller.injectInside(this.topContainer); break; case "bl": newFiller.setStyles({ 'top': '0px', 'left': '0px', 'border-left': this.borderString }); newFiller.injectInside(this.bottomContainer); break; case "br": newFiller.setStyles({ 'top': '0px', 'right': '0px', 'border-right': this.borderString }); newFiller.injectInside(this.bottomContainer); break } } var newFillerBar = new Element('div', { 'styles': { 'position': 'relative', 'overflow': 'hidden', 'background-color': this.boxColor, 'background-image': this.backgroundImage} }); switch (z) { case "t": if (this.topContainer) { if (this.settings.tl.radius && this.settings.tr.radius) { newFillerBar.setStyles({ 'height': topMaxRadius - this.borderWidth, 'margin-left': this.settings.tl.radius - this.borderWidth, 'margin-right': this.settings.tr.radius - this.borderWidth, 'border-top': this.borderString }); if (this.backgroundImage != "none") newFillerBar.setStyle('background-position', (-topMaxRadius - this.borderWidth) + "px 0px"); newFillerBar.injectInside(this.topContainer) } this.box.setStyle('background-position', "0px " + (-topMaxRadius + this.borderWidth) + "px") } break; case "b": if (this.bottomContainer) { if (this.settings.bl.radius && this.settings.br.radius) { newFillerBar.setStyles({ 'height': botMaxRadius - this.borderWidth, 'margin-left': this.settings.bl.radius - this.borderWidth, 'margin-right': this.settings.br.radius - this.borderWidth, 'border-bottom': this.borderString }); if (this.backgroundImage != "none") newFillerBar.setStyle('background-position', (-botMaxRadius - this.borderWidth) + "px " + (-this.boxHeight - topMaxRadius - this.borderWidth) + "px"); newFillerBar.injectInside(this.bottomContainer) } } break } } } }; this.drawPixel = function(intx, inty, color, transAmount, height, newCorner, image, cornerRadius) { var pixel = new Element('div', { 'styles': { 'height': height, 'width': '1px', 'position': 'absolute', 'overflow': 'hidden'} }); var topMaxRadius = Math.max(this.settings.tl ? this.settings.tl.radius : 0, this.settings.tr ? this.settings.tr.radius : 0); if (image == -1 && this.backgroundImage != "none") { pixel.setStyles({ 'background-image': this.backgroundImage, 'background-position': (-this.boxWidth + cornerRadius - intx - this.borderWidth) + "px " + (-this.boxHeight - topMaxRadius - inty + this.borderWidth) + "px" }) } else { pixel.setStyle('background-color', color) } if (transAmount != 1) { pixel.setOpacity(transAmount) } pixel.setStyles({ 'top': inty, 'left': intx }); pixel.injectInside(newCorner) } } function pixelFraction(x, y, r) { var pixelfraction = 0; var xvalues = []; var yvalues = []; var whatsides = ""; var intersect = Math.sqrt((Math.pow(r, 2) - Math.pow(x, 2))); if ((intersect >= y) && (intersect < (y + 1))) { whatsides += "Left"; xvalues.extend([0]); yvalues.extend([intersect - y]) } var intersect = Math.sqrt((Math.pow(r, 2) - Math.pow(y + 1, 2))); if ((intersect >= x) && (intersect < (x + 1))) { whatsides += "Top"; xvalues.extend([intersect - x]); yvalues.extend([1]) } var intersect = Math.sqrt((Math.pow(r, 2) - Math.pow(x + 1, 2))); if ((intersect >= y) && (intersect < (y + 1))) { whatsides += "Right"; xvalues.extend([1]); yvalues.extend([intersect - y]) } var intersect = Math.sqrt((Math.pow(r, 2) - Math.pow(y, 2))); if ((intersect >= x) && (intersect < (x + 1))) { whatsides += "Bottom"; xvalues.extend([intersect - x]); yvalues.extend([0]) } switch (whatsides) { case "LeftRight": pixelfraction = Math.min(yvalues[0], yvalues[1]) + Math.abs(yvalues[0] - yvalues[1]) / 2; break; case "TopRight": pixelfraction = 1 - (((1 - xvalues[0]) * (1 - yvalues[1])) / 2); break; case "TopBottom": pixelfraction = Math.min(xvalues[0], xvalues[1]) + Math.abs(xvalues[0] - xvalues[1]) / 2; break; case "LeftBottom": pixelfraction = (yvalues[0] * xvalues[1]) / 2; break; default: pixelfraction = 1 } return pixelfraction } function newCurvyError(errorMessage) { return new Error("curvyCorners Error:\n" + errorMessage) }