
<
Even 3-Dimensional Crossword Puzzles (!!)
And the winner is...
- Installed Everywhere
- Rich Media Capabilities
- Great Editing Tools and more
| Firefox | Opera | Safari | Internet Explorer |
| DOM | ALL |
| Vector Graphics | SVG | SVG | SVG | VML |
| Bitmap Canvas | Canvas | Canvas | Canvas | Direct Animation* |
- CSS Properties
- Bitmap Images
- Text
- Declarative
- Access via Javascript
- Walter Zorn's Crazy Library (Hello, world!)
function drawShapes()
{
// get the canvas:
var ctx = new jsGraphics('gfx');
// Circle parameters:
var r = 50; var cx = 150; var cy = 100;
var strokeWeight = 15;
// Draw the solid circle:
ctx.setColor("#ff0000");
ctx.fillEllipse(cx - r, cy - r,
r * 2, r * 2);
// Draw the stroked outline:
ctx.setColor("#ffbb00");
ctx.setStroke(strokeWeight);
var strokeOffset = strokeWeight / 2;
ctx.drawEllipse(cx - r - strokeOffset,
cy - r - strokeOffset, r * 2, r * 2);
ctx.paint(); // <--- forces DIVs to render
...
function drawShapes()
{
// get the canvas:
var ctx = new jsGraphics('gfx');
// Circle parameters:
var r = 50; var cx = 150; var cy = 100;
var strokeWeight = 15;
// Draw the solid circle:
ctx.setColor("#ff0000");
ctx.fillEllipse(cx - r, cy - r,
r * 2, r * 2);
// Draw the stroked outline:
ctx.setColor("#ffbb00");
ctx.setStroke(strokeWeight);
var strokeOffset = strokeWeight / 2;
ctx.drawEllipse(cx - r - strokeOffset,
cy - r - strokeOffset, r * 2, r * 2);
ctx.paint(); // <--- forces DIVs to render
...
...
var ctx = new jsGraphics('gfx2');
ctx.setColor("#00ff00");
//draw the filled ellipse
ctx.fillEllipse(cx - rx, cy - ry,
rx * 2 , ry * 2);
strokeWeight = 5;
ctx.setStroke(strokeWeight);
ctx.setColor("#00ffbb");
strokeOffset = strokeWeight / 2;
// draw the stroked ellipse
ctx.drawEllipse(cx - rx - strokeOffset,
cy - ry - strokeOffset, rx * 2, ry * 2);
// paint everything
ctx.paint();
setOpacity(document.getElementById('gfx2'), 0.5);
}
...
var ctx = new jsGraphics('gfx2');
ctx.setColor("#00ff00");
//draw the filled ellipse
ctx.fillEllipse(cx - rx, cy - ry,
rx * 2 , ry * 2);
strokeWeight = 5;
ctx.setStroke(strokeWeight);
ctx.setColor("#00ffbb");
strokeOffset = strokeWeight / 2;
// draw the stroked ellipse
ctx.drawEllipse(cx - rx - strokeOffset,
cy - ry - strokeOffset, rx * 2, ry * 2);
// paint everything
ctx.paint();
setOpacity(document.getElementById('gfx2'), 0.5);
}
<script>
function setOpacity(aDiv, aVal)
{
for (var i = 0; i < aDiv.childNodes.length; ++i) {
aDiv.childNodes[i].style['opacity'] = aVal;
}
}
</script>
<!--[if gte IE 6]><script>
function setOpacity(aDiv, aVal) // IE version of transparency fixer:
{
for (var i = 0; i < aDiv.childNodes.length; ++i) {
var node = aDiv.childNodes[i];
if (node && node.style) {
node.style.filter = "Alpha(Opacity=" + aVal * 100 + ")";
}
}
}</script><![endif]-->
- Drawing Shapes
- Paths
- Fancy Filling and Clipping
- Affine Transforms
<svg version="1.1"
baseProfile="full"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
height="275px" width="275px">
<circle cx="150px" cy="100px"
r="50px" fill="#ff0000"
stroke="#ffbb00" stroke-width="15px"/>
<ellipse cx="200px" cy="120px"
rx="50px" ry="100px" fill="#00ff00"
stroke="#00ffbb" stroke-width="5px"
opacity="0.5"/>
</svg>
<svg version="1.1"
baseProfile="full"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
height="275px" width="275px">
<circle cx="150px" cy="100px"
r="50px" fill="#ff0000"
stroke="#ffbb00" stroke-width="15px"/>
<ellipse cx="200px" cy="120px"
rx="50px" ry="100px" fill="#00ff00"
stroke="#00ffbb" stroke-width="5px"
opacity="0.5"/>
</svg>
function drawShapes()
{
var gfx = document.getElementById('gfx');
var svg = document.createElementNS(
"http://www.w3.org/2000/svg", 'svg');
svg.setAttribute('width', 275);
svg.setAttribute('height', 275);
gfx.appendChild(svg);
var circle = document.createElementNS(
"http://www.w3.org/2000/svg", 'circle');
circle.setAttribute('cx', "150px");
circle.setAttribute('cy', "100px");
circle.setAttribute('r', "50px");
circle.setAttribute("stroke", "#ffbb00");
circle.setAttribute("stroke-width", "15px");
circle.setAttribute('fill', '#ff0000');
svg.appendChild(circle);
function drawShapes()
{
var gfx = document.getElementById('gfx');
var svg = document.createElementNS(
"http://www.w3.org/2000/svg", 'svg');
svg.setAttribute('width', 275);
svg.setAttribute('height', 275);
gfx.appendChild(svg);
var circle = document.createElementNS(
"http://www.w3.org/2000/svg", 'circle');
circle.setAttribute('cx', "150px");
circle.setAttribute('cy', "100px");
circle.setAttribute('r', "50px");
circle.setAttribute("stroke", "#ffbb00");
circle.setAttribute("stroke-width", "15px");
circle.setAttribute('fill', '#ff0000');
svg.appendChild(circle);
var ellipse = document.createElementNS(
"http://www.w3.org/2000/svg", 'ellipse');
ellipse.setAttribute('cx', "200px");
ellipse.setAttribute('cy', "120px");
ellipse.setAttribute('rx', "50px");
ellipse.setAttribute('ry', "100px");
ellipse.setAttribute('fill', "#00ff00");
ellipse.setAttribute('stroke', "#00ffbb");
ellipse.setAttribute('stroke-width', "5px");
ellipse.setAttribute('opacity', "0.5");
svg.appendChild(ellipse);
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:v="urn:schemas-microsoft.com:vml"
xml:lang="en">
<head>
<!--[if gte IE 6]>
<object id="VMLRender"
classid="CLSID:10072CEC-8CC1-11D1-986E-00A0C955B42E">
</object>
<style type="text/css">
v\:* { behavior: url(#VMLRender) }
</style>
<![endif]-->
</head>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:v="urn:schemas-microsoft.com:vml"
xml:lang="en">
<head>
<!--[if gte IE 6]>
<object id="VMLRender"
classid="CLSID:10072CEC-8CC1-11D1-986E-00A0C955B42E">
</object>
<style type="text/css">
v\:* { behavior: url(#VMLRender) }
</style>
<![endif]-->
</head>
<body>
<div id="gfx" width="300px" height="300px">
<v:group style="width: 300px; height: 300px;"
coordsize="30,30"> <!-- local coordinate space for group -->
<v:oval style="position: absolute;
left: 10; top: 5;
width: 10; height: 10"
fill="true" fillcolor="#ff0000"
strokeweight="15px"
strokecolor="#ffbb00"/>
<v:oval style="position: absolute;
left: 15; top: 2;
width: 10; height: 20;"/>
</v:group>
</div>
</body>
<body>
<div id="gfx" width="300px" height="300px">
<v:group style="width: 300px; height: 300px;"
coordsize="30,30"> <!-- local coordinate space for group -->
<v:oval style="position: absolute;
left: 10; top: 5;
width: 10; height: 10"
fill="true" fillcolor="#ff0000"
strokeweight="15px"
strokecolor="#ffbb00"/>
<v:oval style="position: absolute;
left: 15; top: 2;
width: 10; height: 20;"/>
</v:group>
</div>
</body>
<body>
<div id="gfx" width="300px" height="300px">
<v:group style="width: 300px; height: 300px;"
coordsize="30,30"> <!-- local coordinate space for group -->
<v:oval style="position: absolute;
left: 10; top: 5;
width: 10; height: 10"
fill="true" fillcolor="#ff0000"
strokeweight="15px"
strokecolor="#ffbb00"/>
<v:oval style="position: absolute;
left: 15; top: 2;
width: 10; height: 20;"/>
</v:group>
</div>
</body>
<body>
<div id="gfx" width="300px" height="300px">
<v:group style="width: 300px; height: 300px;"
coordsize="30,30"> <!-- local coordinate space for group -->
<v:oval style="position: absolute;
left: 10; top: 5;
width: 10; height: 10"
fill="true" fillcolor="#ff0000"
strokeweight="15px"
strokecolor="#ffbb00"/>
<v:oval style="position: absolute;
left: 15; top: 2;
width: 10; height: 20;">
<v:stroke opacity="0.5" color="#00ffbb" weight="5px"/>
<v:fill opacity="0.5" color="#00ff00"/>
</v:oval>
</v:group>
</div>
</body>
- Imperative
- Familiar to Programmers
- Lightweight
- Like an <img> tag you can draw on
- Javascript API
- Similar to GDI, Java Graphics, X Drawable
- WHATWG standard
- Not in IE
Hello, World!
<body onload="drawShapes();">
<div id="gfx">
<canvas id="canvas" width="275px" height="275px">
</canvas>
<!-- end tag is required so it works in both safari and ffox -->
</div>
</body>
function drawShapes()
{
// Used to compute control points
var KAPPA = 4 * ((Math.sqrt(2) -1) / 3);
// Total number of radians in a circle
var RADIANS = 2*Math.PI;
// Get the canvas element
var canvas = document.getElementById('canvas');
// Get the 2D context from the element
var ctx = canvas.getContext('2d');
// Draw the circle
var cx = 150; var cy = 100; var r = 50;
...
...
ctx.save();
ctx.fillStyle = "#ff0000";
ctx.strokeStyle = "#ffbb00"
ctx.lineWidth = 15;
ctx.translate(cx, cy);
ctx.beginPath();
// Move to outer edge before stroking,
// or Opera draws a line:
ctx.moveTo(r, 0);
ctx.arc(0,0, r, 0, RADIANS ,1);
ctx.fill(); // closes the path
ctx.stroke();
...
...
ctx.save();
ctx.fillStyle = "#ff0000";
ctx.strokeStyle = "#ffbb00"
ctx.lineWidth = 15;
ctx.translate(cx, cy);
ctx.beginPath();
// Move to outer edge before stroking,
// or Opera draws a line:
ctx.moveTo(r, 0);
ctx.arc(0,0, r, 0, RADIANS ,1);
ctx.fill(); // closes the path
ctx.stroke();
...
...
ctx.save();
ctx.fillStyle = "#ff0000";
ctx.strokeStyle = "#ffbb00"
ctx.lineWidth = 15;
ctx.translate(cx, cy);
ctx.beginPath();
// Move to outer edge before stroking,
// or Opera draws a line:
ctx.moveTo(r, 0);
ctx.arc(0,0, r, 0, RADIANS ,1);
ctx.fill(); // closes the path
ctx.stroke();
...
...
cx = 200; cy = 120; var rx = 50; var ry = 100;
ctx.fillStyle = '#00ff00'; ctx.lineWidth = 5;
ctx.strokeStyle = "#00ffbb"; ctx.globalAlpha = 0.5;
// No oval primitive, so draw with bezier curves
ctx.save();
ctx.beginPath();
ctx.moveTo(cx, cy - ry);
ctx.bezierCurveTo(cx + (KAPPA * rx), cy - ry,
cx + rx, cy - (KAPPA * ry), cx + rx, cy);
ctx.bezierCurveTo(cx + rx, cy + (KAPPA * ry),
cx + (KAPPA * rx), cy + ry, cx, cy + ry);
ctx.bezierCurveTo(cx - (KAPPA * rx), cy + ry,
cx - rx, cy + (KAPPA * ry), cx - rx, cy);
ctx.bezierCurveTo(cx - rx, cy - (KAPPA * ry),
cx - (KAPPA * rx), cy - ry, cx, cy - ry);
ctx.fill();
ctx.stroke();
ctx.restore();
}
...
cx = 200; cy = 120; var rx = 50; var ry = 100;
ctx.fillStyle = '#00ff00'; ctx.lineWidth = 5;
ctx.strokeStyle = "#00ffbb"; ctx.globalAlpha = 0.5;
// No oval primitive, so draw with bezier curves
ctx.save();
ctx.beginPath();
ctx.moveTo(cx, cy - ry);
ctx.bezierCurveTo(cx + (KAPPA * rx), cy - ry,
cx + rx, cy - (KAPPA * ry), cx + rx, cy);
ctx.bezierCurveTo(cx + rx, cy + (KAPPA * ry),
cx + (KAPPA * rx), cy + ry, cx, cy + ry);
ctx.bezierCurveTo(cx - (KAPPA * rx), cy + ry,
cx - rx, cy + (KAPPA * ry), cx - rx, cy);
ctx.bezierCurveTo(cx - rx, cy - (KAPPA * ry),
cx - (KAPPA * rx), cy - ry, cx, cy - ry);
ctx.fill();
ctx.stroke();
ctx.restore();
}
...
cx = 200; cy = 120; var rx = 50; var ry = 100;
ctx.fillStyle = '#00ff00'; ctx.lineWidth = 5;
ctx.strokeStyle = "#00ffbb"; ctx.globalAlpha = 0.5;
// No oval primitive, so draw with bezier curves
ctx.save();
ctx.beginPath();
ctx.moveTo(cx, cy - ry);
ctx.bezierCurveTo(cx + (KAPPA * rx), cy - ry,
cx + rx, cy - (KAPPA * ry), cx + rx, cy);
ctx.bezierCurveTo(cx + rx, cy + (KAPPA * ry),
cx + (KAPPA * rx), cy + ry, cx, cy + ry);
ctx.bezierCurveTo(cx - (KAPPA * rx), cy + ry,
cx - rx, cy + (KAPPA * ry), cx - rx, cy);
ctx.bezierCurveTo(cx - rx, cy - (KAPPA * ry),
cx - (KAPPA * rx), cy - ry, cx, cy - ry);
ctx.fill();
ctx.stroke();
ctx.restore();
}
...
cx = 200; cy = 120; var rx = 50; var ry = 100;
ctx.fillStyle = '#00ff00'; ctx.lineWidth = 5;
ctx.strokeStyle = "#00ffbb"; ctx.globalAlpha = 0.5;
// No oval primitive, so draw with bezier curves
ctx.save();
ctx.beginPath();
ctx.moveTo(cx, cy - ry);
ctx.bezierCurveTo(cx + (KAPPA * rx), cy - ry,
cx + rx, cy - (KAPPA * ry), cx + rx, cy);
ctx.bezierCurveTo(cx + rx, cy + (KAPPA * ry),
cx + (KAPPA * rx), cy + ry, cx, cy + ry);
ctx.bezierCurveTo(cx - (KAPPA * rx), cy + ry,
cx - rx, cy + (KAPPA * ry), cx - rx, cy);
ctx.bezierCurveTo(cx - rx, cy - (KAPPA * ry),
cx - (KAPPA * rx), cy - ry, cx, cy - ry);
ctx.fill();
ctx.stroke();
ctx.restore();
}
- Javascript-accessible COM interface
- IE-only
- On its way out, even from IE
Hello, World!
function drawShapes()
{
var gfx = document.getElementById('gfx');
var width = 275; var height = 275;
// Init the control (can also declare)
var daControl = document.createElement('Object');
daControl.setAttribute('id', 'DAControl');
daControl.setAttribute('classid',
"CLSID:B6FFC24C-7E13-11D0-9B47-00C04FC2F51D");
daControl.style.cssText = "position: absolute; left: 0; top: 0; width: "
+ width + "px; height: " + height + "px;";
gfx.appendChild(daControl);
// The DirectAnimation library
lib = DAControl.PixelLibrary; // as opposed to MeterLibrary
function drawShapes()
{
var gfx = document.getElementById('gfx');
var width = 275; var height = 275;
// Init the control (can also declare)
var daControl = document.createElement('Object');
daControl.setAttribute('id', 'DAControl');
daControl.setAttribute('classid',
"CLSID:B6FFC24C-7E13-11D0-9B47-00C04FC2F51D");
daControl.style.cssText = "position: absolute; left: 0; top: 0; width: "
+ width + "px; height: " + height + "px;";
gfx.appendChild(daControl);
// The DirectAnimation library
var lib = DAControl.PixelLibrary; // as opposed to MeterLibrary
...
...
var fillColor = lib.ColorRgb(1.0, 0.0, 0.0);// red
var strokeColor = lib.ColorRgb(1.0, 0.73, 0.0); // orange
var fill = lib.SolidColorImage(fillColor);
var ls = lib.DefaultLineStyle.
color(strokeColor).
AntiAliasing(1).width(15 / 2);
var radius = 50; var cx = 50; var cy = 100;
var xform = lib.Translate2(-10, -30);
var p = lib.Oval(radius * 2, radius * 2);
var circleImg = p.Fill(ls, fill).Transform(xform);
...
...
// Now draw the green ellipse:
fillColor = lib.ColorRgb(0.0, 1.0, 0.0); // green
strokeColor = lib.ColorRgb(0.0, 1.0, 0.73); // blue-green
fill = lib.SolidColorImage(fillColor);
ls = lib.DefaultLineStyle.
color(strokeColor).
AntiAliasing(1).width(5 / 2);
xform = lib.Translate2(40, 0);
p = lib.Oval(100, 200);
var ellipseImg = p.Fill(ls, fill).
Transform(xform).Opacity(0.5);
...
...
var finalImg = lib.Overlay(ellipseImg, circleImg);
// set the image to be displayed
DAControl.Image = finalImg;
// start the animation
DAControl.Start();
}
...
var finalImg = lib.Overlay(ellipseImg, circleImg);
// set the image to be displayed
DAControl.Image = finalImg;
// start the animation
DAControl.Start();
}
- IE7 + Vista/IE7 + .NET 3.0 define unified graphics model: Windows Presentation Foundation
- WPF API available for Windows applications and IE 7
- XAML: XUL for Windows
- XAML maps WPF API directly into XML
- WPF API and XAML DOM are accessible to Javascript
<body onload="fixTransparency('gfx');">
<div id="gfx">
<img src="/oscon/ellipse?rx=50&ry=50&
fill=ff0000&stroke=ffbb00&strokeWeight=15&opacity=1.0"
style="position: absolute; left: 120px; top: 70px;">
<img src="/oscon/ellipse?rx=50&ry=100&
fill=00ff00&stroke=00ffbb&strokeWeight=5&opacity=0.5"
style="position: absolute; left: 180px; top: 50px;">
</div>
</body>
<body onload="fixTransparency('gfx');">
<div id="gfx">
<img src="/oscon/ellipse?rx=50&ry=50&
fill=ff0000&stroke=ffbb00&strokeWeight=15&opacity=1.0"
style="position: absolute; left: 120px; top: 70px;">
<img src="/oscon/ellipse?rx=50&ry=100&
fill=00ff00&stroke=00ffbb&strokeWeight=5&opacity=0.5"
style="position: absolute; left: 180px; top: 50px;">
</div>
</body>
<body onload="fixTransparency('gfx');">
<div id="gfx">
<img src="/oscon/ellipse?rx=50&ry=50&
fill=ff0000&stroke=ffbb00&strokeWeight=15&opacity=1.0"
style="position: absolute; left: 120px; top: 70px;">
<img src="/oscon/ellipse?rx=50&ry=100&
fill=00ff00&stroke=00ffbb&strokeWeight=5&opacity=0.5"
style="position: absolute; left: 180px; top: 50px;">
</div>
</body>
def ellipse
uri = request.request_uri
filename = 'public' + uri + '.png'
if !FileTest.exists?(filename)
p = request.parameters
r = (p['r'] || 100).to_f
rx = (p['rx'] || r).to_f
ry = (p['ry'] || rx).to_f
strokeWeight = (p['strokeWeight'] || 1.0).to_f
width = (strokeWeight * 2) + (rx * 2.0)
height = (strokeWeight * 2) + (ry * 2.0)
cx = width / 2
cy = height / 2
...
...
fill = (p['fill'] || 'ffffff')
fill = "\##{fill}"
stroke = p['stroke'] || '000000'
stroke = "\##{stroke}"
opacity = (p['opacity'] || 1.0).to_f
gc = Magick::Draw.new
canvas = Magick::Image.new(width, height)
gc.fill('white')
render_ellipse(gc, canvas, false, cx, cy,
rx, ry, stroke, fill, strokeWeight, opacity)
gc.draw(canvas)
...
def render_ellipse(gc, image, ismatte,
cx, cy, rx, ry, stroke, fill,
strokeWeight, opacity)
if ismatte
gc.fill_opacity(opacity)
gc.stroke_opacity(opacity)
gc.stroke('transparent')
gc.stroke_width(strokeWeight);
opacityVal = 255 * opacity;
gc.fill("rgb(#{opacityVal}, #{opacityVal}, #{opacityVal})");
else
gc.stroke(stroke);
gc.stroke_width(strokeWeight);
gc.fill(fill)
end
gc.ellipse(cx, cy, rx, ry, 0, 360);
gc.draw(image)
end
...
alpha = Magick::Image.new(canvas.columns, canvas.rows)
{self.background_color = 'black'}
render_ellipse(gc, alpha, true, cx, cy,
rx, ry, stroke, fill, strokeWeight, opacity)
canvas.matte = true
alpha.matte = false
canvas = canvas.composite(alpha,
Magick::CenterGravity,
Magick::CopyOpacityCompositeOp)
canvas.write(filename)
end
response.headers['content-type'] = 'image/png'
render :file => filename
end
function fixTransparency(anId)
{
var aDiv = document.getElementById(anId);
for (var i = 0; i < aDiv.childNodes.length; ++i) {
var node = aDiv.childNodes[i];
var src = node['src'];
if (src) {
var opacity = node.opacity;
var filterStr = "progid:DXImageTransform.
Microsoft.AlphaImageLoader(src='"
+ src + ", sizingMethod='scale')";
node.src = '/images/transparentpixel.gif';
node.style.filter = filterStr;
}
}
}
function updateImg(aUrl)
{
gImg.setAttribute('src', aUrl);
}
function updateDrawing() {
// send points collected onmousemove
// to be rendered
var str = pointsToPath(gDrawPoints);
dojo.io.bind({
url: "/oscon/renderpath?pathid=" +
gPathId + "&width=800&height=500&path=" + str,
load: function(type, evaldObj){
updateImg(evaldObj);},
mimetype: "text/plain", // get plain text, don't eval()
transport: "XMLHTTPTransport",
method: 'post'
});
}
- Drawing Object Javascript API
- Normalizes SVG and VML
- Architecture can support Canvas, WZ
<html>
<head>
<title>Hello, Dojo</title>
<script type="text/javascript">djConfig = { isDebug: false };</script>
<script type="text/javascript" src="/dojo-dev/dojo.js"></script>
<script type="text/javascript">
dojo.require("dojo.gfx.*");
dojo.addOnLoad(drawShapes);
function drawShapes(){...}
</script>
</head>
<body>
<div id="gfx" width="300" height="300"></div>
</body>
</html>
function drawShapes()
{
var gfx = dojo.byId('gfx');
var g = dojo.gfx.defaultRenderer;
var surface = g.createSurface(gfx, 300, 300);
var redCircle = surface.
createCircle({ cx: 150, cy: 100, r: 50}).
setFill([255, 0, 0, 1]).
setStroke({color: "#ffbb00", width: 15});
var greenEllipse = surface.
createEllipse({cx: 200, cy: 120, rx: 50, ry: 100}).
setFill([0, 255, 0, 0.5]).
setStroke({color: [0, 255, 187, 0.5], width: 5});
}
function drawShapes()
{
var gfx = dojo.byId('gfx');
var g = dojo.gfx.defaultRenderer;
var surface = g.createSurface(gfx, 300, 300);
var redCircle = surface.
createCircle({ cx: 150, cy: 100, r: 50}).
setFill([255, 0, 0, 1]).
setStroke({color: "#ffbb00", width: 15});
var greenEllipse = surface.
createEllipse({cx: 200, cy: 120, rx: 50, ry: 100}).
setFill([0, 255, 0, 0.5]).
setStroke({color: [0, 255, 187, 0.5], width: 5});
}
- Primarily DOM events
- Issues with canvas graphics
- SVG declarative animation
- Direct Animation, HTML+TIME
- SMIL declarative animation
- setTimeout()/setInterval() in Javascript
function drawShapes()
{
var gfx = document.getElementById('gfx');
var svg = document.createElementNS("http://www.w3.org/2000/svg", 'svg');
// do all the svg setup
setTimeout(animate, 50);
}
function randomWalk(c) {
var diry = 1 - (2 * Math.floor(Math.random() * 2));
var dirx = 1 - (2 * Math.floor(Math.random() * 2));
var dy = diry * Math.floor(Math.random() * 3);
var dx = dirx * Math.floor(Math.random() * 3);
var cx = c.cx.baseVal.value + dx;
var cy = c.cy.baseVal.value + dy;
c.setAttribute('cx', cx + "px");
c.setAttribute('cy', cy + "px");
}
function animate()
{
randomWalk(document.getElementById('circle'));
randomWalk(document.getElementById('ellipse'));
setTimeout(animate, 50);
}
- Video
- Sound
- Input (webcams and microphones)
- Authoring Tools