Skip to content
Permalink
Browse files

Silverlight:

Add a div overlay so that mouse events works.

Add support for rgba, hsl and hsla and fix an issue with globalAlpha

git-svn-id: https://explorercanvas.googlecode.com/svn/trunk@70 fd59bba8-8519-0410-9389-e36bf2bdbbd6
  • Loading branch information...
erik.arvidsson@gmail.com
erik.arvidsson@gmail.com committed Nov 12, 2009
1 parent 9d308a9 commit 66c289676ff1e36616d603d8a64f3720fa23c88d
Showing with 197 additions and 22 deletions.
  1. +116 −22 silverlight/excanvas.js
  2. +81 −0 testcases/overlay.html
@@ -67,8 +67,13 @@ if (!window.CanvasRenderingContext2D) {
ss.cssText = 'canvas{display:inline-block;overflow:hidden;' +
// default size is 300x150 in Gecko and Opera
'text-align:left;width:300px;height:150px}' +
'canvas object{width:100%;height:100%;border:0;' +
'background:transparen;margin:0}';
'canvas *{width:100%;height:100%;border:0;' +
'background:transparen;margin:0}' +
'canvas div {position:relative}' +
// Place a div on top of the plugin.
'canvas div div{position:absolute;top:0;' +
// needs to be "non transparent"
'filter:alpha(opacity=0);background:red}';

// find all canvas elements
var els = doc.getElementsByTagName('canvas');
@@ -157,11 +162,11 @@ if (!window.CanvasRenderingContext2D) {
}

function getObjectHtml(fn) {
return '<object type="application/x-silverlight" >' +
return '<div><object type="application/x-silverlight" >' +
'<param name="windowless" value="true">' +
'<param name="background" value="transparent">' +
'<param name="source" value="#' + xamlId + '">' +
'</object>';
'</object><div></div></div>';
}

function hasSilverlight() {
@@ -246,25 +251,113 @@ if (!window.CanvasRenderingContext2D) {
o2.arcScaleY_ = o1.arcScaleY_;
}

function translateColor(s) {
var rgbaMatch = /rgba\(([^)]+)\)/gi.exec(s);
if (rgbaMatch) {
var parts = rgbaMatch[1].split(',');
return '#' + dec2hex[Math.floor(Number(parts[3]) * 255)] +
dec2hex[Number(parts[0])] +
dec2hex[Number(parts[1])] +
dec2hex[Number(parts[2])];
// precompute "00" to "FF"
var decToHex = [];
for (var i = 0; i < 16; i++) {
for (var j = 0; j < 16; j++) {
decToHex[i * 16 + j] = i.toString(16) + j.toString(16);
}
}

var rgbMatch = /rgb\(([^)]+)\)/gi.exec(s);
if (rgbMatch) {
var parts = rgbMatch[1].split(',');
return '#FF' + dec2hex[Number(parts[0])] +
dec2hex[Number(parts[1])] +
dec2hex[Number(parts[2])];
// Silverlight does not support spelling gray as grey.
var colorData = {
darkgrey: '#A9A9A9',
darkslategrey: '#2F4F4F',
dimgrey: '#696969',
grey: '#808080',
lightgrey: '#D3D3D3',
lightslategrey: '#778899',
slategrey: '#708090'
};


function getRgbHslContent(styleString) {
var start = styleString.indexOf('(', 3);
var end = styleString.indexOf(')', start + 1);
var parts = styleString.substring(start + 1, end).split(',');
// add alpha if needed
if (parts.length == 4 && styleString.substr(3, 1) == 'a') {
alpha = +parts[3];
} else {
parts[3] = 1;
}
return parts;
}

return s;
function percent(s) {
return parseFloat(s) / 100;
}

function clamp(v, min, max) {
return Math.min(max, Math.max(min, v));
}

function hslToRgb(parts){
var r, g, b;
h = parseFloat(parts[0]) / 360 % 360;
if (h < 0)
h++;
s = clamp(percent(parts[1]), 0, 1);
l = clamp(percent(parts[2]), 0, 1);
if (s == 0) {
r = g = b = l; // achromatic
} else {
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
var p = 2 * l - q;
r = hueToRgb(p, q, h + 1 / 3);
g = hueToRgb(p, q, h);
b = hueToRgb(p, q, h - 1 / 3);
}

return decToHex[Math.floor(r * 255)] +
decToHex[Math.floor(g * 255)] +
decToHex[Math.floor(b * 255)];
}

function hueToRgb(m1, m2, h) {
if (h < 0)
h++;
if (h > 1)
h--;

if (6 * h < 1)
return m1 + (m2 - m1) * 6 * h;
else if (2 * h < 1)
return m2;
else if (3 * h < 2)
return m1 + (m2 - m1) * (2 / 3 - h) * 6;
else
return m1;
}

function translateColor(styleString) {
var str, alpha = 1;

styleString = String(styleString);
if (styleString.charAt(0) == '#') {
return styleString;
} else if (/^rgb/.test(styleString)) {
var parts = getRgbHslContent(styleString);
var str = '', n;
for (var i = 0; i < 3; i++) {
if (parts[i].indexOf('%') != -1) {
n = Math.floor(percent(parts[i]) * 255);
} else {
n = +parts[i];
}
str += decToHex[clamp(n, 0, 255)];
}
alpha = parts[3];
} else if (/^hsl/.test(styleString)) {
var parts = getRgbHslContent(styleString);
str = hslToRgb(parts);
alpha = parts[3];
} else if (styleString in colorData) {
return colorData[styleString];
} else {
return styleString;
}
return '#' + dec2hex[Math.floor(alpha * 255)] + str;
}

function processLineCap(lineCap) {
@@ -280,18 +373,18 @@ if (!window.CanvasRenderingContext2D) {
}

function getRoot(ctx) {
return ctx.canvas.firstChild.content.findName('root');
return ctx.canvas.firstChild.firstChild.content.findName('root');
}

function create(ctx, s, opt_args) {
if (opt_args) {
s = s.replace(/\%(\d+)/g, function(match, index) {
return opt_args[Number(index) - 1];
return opt_args[+index - 1];
});
}

try {
return ctx.canvas.firstChild.content.createFromXaml(s);
return ctx.canvas.firstChild.firstChild.content.createFromXaml(s);
} catch (ex) {
throw Error('Could not create XAML from: ' + s);
}
@@ -570,6 +663,7 @@ if (!window.CanvasRenderingContext2D) {
// The spec says to use non zero but Silverlight uses EvenOdd by defaul
path.data.fillRule = 'NonZero';
path.fill = createBrushObject(this, this.fillStyle);
path.fill.opacity = this.globalAlpha;
// TODO: What about even-odd etc?
};

@@ -0,0 +1,81 @@
<!DOCTYPE html>
<html>
<head>
<title>Overlay animation</title>
<style>
</style>
<!--[if IE]><script src="../excanvas.js"></script><![endif]-->
<script>
Date.now = Date.now || function() {
return new Date().getTime();
};
var points = [];
var startTime = Date.now();
function addPointAtEvent(e) {
var x = e.offsetX || e.layerX;
var y = e.offsetY || e.layerY;
if (!isNaN(x) && !isNaN(y)) {
points.push([x, y, Date.now()]);
}
if (points.length == 1) {
draw();
}
}
var AGE_TO_LIVE = 1500;
function draw() {
var ctx = document.getElementById('c').getContext('2d');
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
var now = Date.now();
var itemsToRemove = 0;
for (var i = 0; i < points.length; i++) {
var x = points[i][0];
var y = points[i][1];
var createTime = points[i][2];
var age = now - createTime;
if (age > AGE_TO_LIVE) {
itemsToRemove++;
} else {
var d = (AGE_TO_LIVE - age) / AGE_TO_LIVE;
var r = d * 50;
var hue = (createTime - startTime) / 10 % 360;
ctx.fillStyle = 'hsl(' + hue + ',100%,50%)';
ctx.globalAlpha = .5 * d;
ctx.beginPath();
ctx.arc(x, y, r, 0, 2 * Math.PI, true);
ctx.fill();
ctx.closePath();
}
}
if (itemsToRemove) {
points = points.slice(itemsToRemove);
}
if (points.length) {
window.setTimeout(draw, 10);
}
}
window.onload = function() {
document.getElementById('c').onmousedown = function(e) {
addPointAtEvent(e || window.event);
};
};
</script>
</head>
<body>

<canvas id=c width=500 height=500 onmousemove="addPointAtEvent(event)"></canvas>

</body>
</html>

0 comments on commit 66c2896

Please sign in to comment.
You can’t perform that action at this time.