You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
125 lines
4.3 KiB
125 lines
4.3 KiB
define([ |
|
"dojo/_base/window", |
|
"dojo/dom-style", |
|
"./sniff" |
|
], function(win, domStyle, has){ |
|
|
|
has.add("mask-image-css", function(global, doc, elt){ |
|
return typeof doc.getCSSCanvasContext === "function" && typeof elt.style.webkitMaskImage !== "undefined"; |
|
}); |
|
|
|
// Indicates whether image mask is available (either via css mask image or svg) |
|
has.add("mask-image", function(){ |
|
return has("mask-image-css") || has("svg"); |
|
}); |
|
|
|
var cache = {}; |
|
|
|
return { |
|
// summary: |
|
// Utility methods to clip rounded corners of various elements (Switch, ScrollablePane, scrollbars in scrollable widgets). |
|
// Uses -webkit-mask-image on webkit, or SVG on other browsers. |
|
|
|
createRoundMask: function(/*DomNode*/node, x, y, r, b, w, h, rx, ry, e){ |
|
// summary: |
|
// Creates and sets a mask for the specified node. |
|
|
|
var tw = x + w + r; |
|
var th = y + h + b; |
|
|
|
if(has("mask-image-css")){ // use -webkit-mask-image |
|
var id = ("DojoMobileMask" + x + y + w + h + rx + ry).replace(/\./g, "_"); |
|
if (!cache[id]) { |
|
cache[id] = 1; |
|
var ctx = win.doc.getCSSCanvasContext("2d", id, tw, th); |
|
ctx.beginPath(); |
|
if (rx == ry) { |
|
// round arc |
|
if(rx == 2 && w == 5){ |
|
// optimized case for vertical scrollbar |
|
ctx.fillStyle = "rgba(0,0,0,0.5)"; |
|
ctx.fillRect(1, 0, 3, 2); |
|
ctx.fillRect(0, 1, 5, 1); |
|
ctx.fillRect(0, h - 2, 5, 1); |
|
ctx.fillRect(1, h - 1, 3, 2); |
|
ctx.fillStyle = "rgb(0,0,0)"; |
|
ctx.fillRect(0, 2, 5, h - 4); |
|
}else if(rx == 2 && h == 5){ |
|
// optimized case for horizontal scrollbar |
|
ctx.fillStyle = "rgba(0,0,0,0.5)"; |
|
ctx.fillRect(0, 1, 2, 3); |
|
ctx.fillRect(1, 0, 1, 5); |
|
ctx.fillRect(w - 2, 0, 1, 5); |
|
ctx.fillRect(w - 1, 1, 2, 3); |
|
ctx.fillStyle = "rgb(0,0,0)"; |
|
ctx.fillRect(2, 0, w - 4, 5); |
|
}else{ |
|
// general case |
|
ctx.fillStyle = "#000000"; |
|
ctx.moveTo(x+rx, y); |
|
ctx.arcTo(x, y, x, y+rx, rx); |
|
ctx.lineTo(x, y+h - rx); |
|
ctx.arcTo(x, y+h, x+rx, y+h, rx); |
|
ctx.lineTo(x+w - rx, y+h); |
|
ctx.arcTo(x+w, y+h, x+w, y+rx, rx); |
|
ctx.lineTo(x+w, y+rx); |
|
ctx.arcTo(x+w, y, x+w - rx, y, rx); |
|
} |
|
} else { |
|
// elliptical arc |
|
var pi = Math.PI; |
|
ctx.scale(1, ry / rx); |
|
ctx.moveTo(x+rx, y); |
|
ctx.arc(x+rx, y+rx, rx, 1.5 * pi, 0.5 * pi, true); |
|
ctx.lineTo(x+w - rx, y+2 * rx); |
|
ctx.arc(x+w - rx, y+rx, rx, 0.5 * pi, 1.5 * pi, true); |
|
} |
|
ctx.closePath(); |
|
ctx.fill(); |
|
} |
|
node.style.webkitMaskImage = "-webkit-canvas(" + id + ")"; |
|
}else if(has("svg")){ // add an SVG image to clip the corners. |
|
if(node._svgMask){ |
|
node.removeChild(node._svgMask); |
|
} |
|
var bg = null; |
|
for(var p = node.parentNode; p; p = p.parentNode){ |
|
bg = domStyle.getComputedStyle(p).backgroundColor; |
|
if(bg && bg != "transparent" && !bg.match(/rgba\(.*,\s*0\s*\)/)){ |
|
break; |
|
} |
|
} |
|
var svgNS = "http://www.w3.org/2000/svg"; |
|
var svg = win.doc.createElementNS(svgNS, "svg"); |
|
svg.setAttribute("width", tw); |
|
svg.setAttribute("height", th); |
|
svg.style.position = "absolute"; |
|
svg.style.pointerEvents = "none"; |
|
svg.style.opacity = "1"; |
|
svg.style.zIndex = "2147483647"; // max int |
|
var path = win.doc.createElementNS(svgNS, "path"); |
|
e = e || 0; |
|
rx += e; |
|
ry += e; |
|
// TODO: optimized cases for scrollbars as in webkit case? |
|
var d = " M" + (x + rx - e) + "," + (y - e) + " a" + rx + "," + ry + " 0 0,0 " + (-rx) + "," + ry + " v" + (-ry) + " h" + rx + " Z" + |
|
" M" + (x - e) + "," + (y + h - ry + e) + " a" + rx + "," + ry + " 0 0,0 " + rx + "," + ry + " h" + (-rx) + " v" + (-ry) + " z" + |
|
" M" + (x + w - rx + e) + "," + (y + h + e) + " a" + rx + "," + ry + " 0 0,0 " + rx + "," + (-ry) + " v" + ry + " h" + (-rx) + " z" + |
|
" M" + (x + w + e) + "," + (y + ry - e) + " a" + rx + "," + ry + " 0 0,0 " + (-rx) + "," + (-ry) + " h" + rx + " v" + ry + " z"; |
|
if(y > 0){ |
|
d += " M0,0 h" + tw + " v" + y + " h" + (-tw) + " z"; |
|
} |
|
if(b > 0){ |
|
d += " M0," + (y + h) + " h" + tw + " v" + b + " h" + (-tw) + " z"; |
|
} |
|
path.setAttribute("d", d); |
|
path.setAttribute("fill", bg); |
|
path.setAttribute("stroke", bg); |
|
path.style.opacity = "1"; |
|
svg.appendChild(path); |
|
node._svgMask = svg; |
|
node.appendChild(svg); |
|
} |
|
} |
|
}; |
|
});
|
|
|