I'm trying to implement the Raphael image rotation demo:
http://raphaeljs.com/image-rotation.html
as a slider within the Foundation framework, but I can't get it to centre without cutting the sides off when it rotates, please see here
http://jcfolio.co.uk/current/index-raphael.html
<script>
window.onload = function () {
var src = document.getElementById("bee").src,
angle = 0;
document.getElementById("globe-holder").innerHTML = "";
var R = Raphael("globe-holder", 1000 , 500);
var img = R.image(src,-535, -150, 2000, 2000);
var butt1 = R.set(),
butt2 = R.set();
butt1.push(R.circle(24.833, 26.917, 26.667).attr({stroke: "none", fill: "#66c100", "fill-opacity": .5 }),
R.path("M12.582,9.551C3.251,16.237,0.921,29.021,7.08,38.564l-2.36,1.689l4.893,2.262l4.893,2.262l-0.568-5.36l-0.567-5.359l-2.365,1.694c-4.657-7.375-2.83-17.185,4.352-22.33c7.451-5.338,17.817-3.625,23.156,3.824c5.337,7.449,3.625,17.813-3.821,23.152l2.857,3.988c9.617-6.893,11.827-20.277,4.935-29.896C35.591,4.87,22.204,2.658,12.582,9.551z").attr({stroke: "none", fill: "#fff"}),
R.circle(24.833, 26.917, 26.667).attr({fill: "#fff", opacity: 0, cursor: "pointer" }));
butt2.push(R.circle(24.833, 26.917, 26.667).attr({stroke: "none", fill: "#66c100", "fill-opacity": .5 }),
R.path("M37.566,9.551c9.331,6.686,11.661,19.471,5.502,29.014l2.36,1.689l-4.893,2.262l-4.893,2.262l0.568-5.36l0.567-5.359l2.365,1.694c4.657-7.375,2.83-17.185-4.352-22.33c-7.451-5.338-17.817-3.625-23.156,3.824C6.3,24.695,8.012,35.06,15.458,40.398l-2.857,3.988C2.983,37.494,0.773,24.109,7.666,14.49C14.558,4.87,27.944,2.658,37.566,9.551z").attr({stroke: "none", fill: "#fff"}),
R.circle(24.833, 26.917, 26.667).attr({fill: "#fff", opacity: 0, cursor: "pointer" }));
butt1.translate(35, 380);
butt2.translate(850, 380);
butt1[2].click(function () {
angle -= 120;
img.stop().animate({transform: "r" + angle}, 1000, "backOut");
}).mouseover(function () {
butt1[1].animate({fill: "#66c100"}, 300);
}).mouseout(function () {
butt1[1].stop().attr({fill: "#fff"});
});
butt2[2].click(function () {
angle += 120;
img.animate({transform: "r" + angle}, 1000, "backOut");
}).mouseover(function () {
butt2[1].animate({fill: "#66c100"}, 300);
}).mouseout(function () {
butt2[1].stop().attr({fill: "#fff"});
});
// setTimeout(function () {R.safari();});
};
</script>
When I increase the globe-holder width to 2000px (the full width of the png), it won't centre!
Think it's probably something simple I've missed! Any help greatly appreciated.
James
Related
I am trying to migrate this chart made by excel into chartJS:
important features:
having a horizontal bar showing a range
let range be from 'lower' (0%) til 'upper' (100%)
median is shown in by a vertical line (50%)
place one single point somewhere on the range (e.g. at 23%)
the single point is the only dynamic component here, everything else always looks the same
I know thats not a typical chart and a bit special.
Closest charts I found are:
1)
a simple stacked bar chart were instead of the bright obvious star I just another bar-stack
not very pretty the same
a mixed chart
with an line using the annotations plugin (here I draw the line with paint by hand)
in css the whole chart needs to be rotated by 90° (already done in the image shown below)
Another option my be creating it by using plane css stuff. But Id rather make it using chart js since there are some more charts and all my framework is made for it.
Any idea is appreciated.
Thanks.
Charts.js allows you to access the canvas and draw custom stuff, using a simple mechanism.
We could start with just the bar, as a horizontal bar chart with one item and most other stuff disabled:
const data = {
labels: [""],
datasets: [{
label: '100%',
data: [100],
backgroundColor: '#4af',
barThickness: 100
}]
};
const options = {
type: 'bar',
data,
options: {
animation: {duration: 0},
indexAxis: 'y',
layout: {
padding:{
left: 10,
right: 10
}
},
scales: {
x: {
display: false
},
y: {
display: false
}
},
plugins: {
legend: {
display: false
},
tooltip:{
enabled: false
}
}
}
};
const chart = new Chart(document.getElementById("myChart"), options);
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.2.0/chart.umd.min.js" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<body>
<canvas id="myChart" style="height:250px; width: 90vw; border: 1px solid #ddd "></canvas>
</body>
Now we can access the canvas through a plugin a draw all the rest:
const plugin = {
id: 'customDraw', // to identify the plugin in the chart options
afterDraw: (chart, args, options) => {
const {ctx} = chart;
// read plugin options
const lineWidth = options.lineWidth || 1,
lineColor = options.lineColor || '#000',
textColor = options.textColor || '#000',
textFont = options.textFont,
starAt = options.starAt,
starColor = options.starColor || '#f44';
// get pixel coordinates for our bar, that is
// positioned at y = 0, from x = 0 to x = 100
const yCenter = chart.scales.y.getPixelForValue(0),
yTop = yCenter-50,
yBottom = yCenter+50,
x0 = chart.scales.x.getPixelForValue(0),
x50 = chart.scales.x.getPixelForValue(50),
x100 = chart.scales.x.getPixelForValue(100),
xStar = chart.scales.x.getPixelForValue(starAt);
ctx.save();
ctx.strokeStyle = lineColor;
ctx.lineWidth = lineWidth;
ctx.beginPath();
ctx.moveTo(x50, yTop);
ctx.lineTo(x50, yBottom);
ctx.stroke();
ctx.fillStyle = starColor;
drawStar(ctx, xStar, yCenter, 10);
ctx.textBaseline = "top";
ctx.fillStyle = textColor;
if(textFont){
ctx.font = textFont;
}
ctx.textAlign = "start";
ctx.fillText("Lower", x0, yBottom + 2);
ctx.textAlign = "center";
ctx.fillText("Median", x50, yBottom + 2);
ctx.textAlign = "right";
ctx.fillText("Upper", x100, yBottom + 2);
ctx.restore();
}
};
Full code:
function drawStar(ctx, x0, y0, radius){
//https://stackoverflow.com/a/58043598/16466946
const nSpikes = 5;
ctx.beginPath();
for(let i = 0; i < nSpikes*2; i++){
let rotation = Math.PI/2;
let angle = (i/(nSpikes*2))*Math.PI*2+rotation;
let dist = radius*(i%2)+radius;
let x = x0+Math.cos(angle)*dist;
let y = y0+Math.sin(angle)*dist;
if(i === 0) {
ctx.moveTo(x, y);
continue; //skip
}
ctx.lineTo(x, y);
}
ctx.closePath();
ctx.fill();
}
const plugin = {
id: 'customDraw',
afterDraw: (chart, args, options) => {
const {ctx} = chart;
// read plugin options
const lineWidth = options.lineWidth || 1,
lineColor = options.lineColor || '#000',
textColor = options.textColor || '#000',
textFont = options.textFont,
starAt = options.starAt,
starColor = options.starColor || '#f44';
// get pixel coordinates for our bar, that is
// positioned at y = 0, from x = 0 to x = 100
const yCenter = chart.scales.y.getPixelForValue(0),
yTop = yCenter-50,
yBottom = yCenter+50,
x0 = chart.scales.x.getPixelForValue(0),
x50 = chart.scales.x.getPixelForValue(50),
x100 = chart.scales.x.getPixelForValue(100),
xStar = chart.scales.x.getPixelForValue(starAt);
ctx.save();
ctx.strokeStyle = lineColor;
ctx.lineWidth = lineWidth;
ctx.beginPath();
ctx.moveTo(x50, yTop);
ctx.lineTo(x50, yBottom);
ctx.stroke();
ctx.fillStyle = starColor;
drawStar(ctx, xStar, yCenter, 10);
ctx.textBaseline = "top";
ctx.fillStyle = textColor;
if(textFont){
ctx.font = textFont;
}
ctx.textAlign = "start";
ctx.fillText("Lower", x0, yBottom + 2);
ctx.textAlign = "center";
ctx.fillText("Median", x50, yBottom + 2);
ctx.textAlign = "right";
ctx.fillText("Upper", x100, yBottom + 2);
ctx.restore();
}
};
const data = {
labels: [""],
datasets: [{
label: '100%',
data: [100],
backgroundColor: '#4af',
barThickness: 100
}]
};
const options = {
type: 'bar',
data,
options: {
animation: {duration: 0},
indexAxis: 'y',
layout: {
padding:{
left: 10,
right: 10
}
},
scales: {
x: {
display: false
},
y: {
display: false
}
},
plugins: {
legend: {
display: false
},
tooltip:{
enabled: false
},
customDraw:{
lineWidth: 3,
textFont: '20px serif',
starAt: 23
}
}
},
plugins: [plugin],
};
new Chart(document.getElementById("myChart"), options);
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.2.0/chart.umd.js" integrity="sha512-B51MzT4ksAo6Y0TcUpmvZnchoPYfIcHadIaFqV5OR5JAh6dneYAeYT1xIlaNHhhFAALd5FLDTWNt/fkxhwE/oQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<body>
<canvas id="myChart" style="height:250px; width: 90vw; border: 1px solid #ddd "></canvas>
</body>
Next step would be to add custom interaction - tooltips, click events and everything...
I would like to recreate this chart color scheme in Chart.js.
So far I've succeeded in creating the horizontal linear gradient for both the stroke and background colors, but I can't find a way to create the opacity mask for the background color to 'blend' it into the page background.
This is my chart so far
Note:
I can create an opacity mask on the canvas itself using css property:
-webkit-mask-image: -webkit-gradient(linear, left 50%, left bottom, from(rgba(0,0,0,1)), to(rgba(0,0,0,0)))
But this method masks the whole lower bottom of the chart, i.e the stroke of the chart, for example
How would I go about masking only the background color of the chart?
Chart.js setup
data = {
labels: labels,
datasets: [
{
label: 'Dataset 1',
fill: true,
data: Utils.numbers(NUMBER_CFG),
borderColor: getGradient,
pointBorderColor: getGradient,
pointBackgroundColor: getGradient,
pointHoverBackgroundColor: getGradient,
pointHoverBorderColor: getGradient,
backgroundColor: getGradient
},
]
};
let width, height, gradient;
function gradient(ctx, chartArea) {
const chartWidth = chartArea.right - chartArea.left;
const chartHeight = chartArea.bottom - chartArea.top;
if (!gradient || width !== chartWidth || height !== chartHeight) {
// Create the gradient because this is either the first render
// or the size of the chart has changed
width = chartWidth;
height = chartHeight;
var gradientStroke = ctx.createLinearGradient(chartArea.right, chartArea.top, chartArea.left, chartArea.top);
gradientStroke.addColorStop(0, "#80b6f4");
gradientStroke.addColorStop(1, "#f49080");
}
return gradientStroke;
}
function getGradient(context) {
const chart = context.chart;
const {ctx, chartArea} = chart;
if (!chartArea) {
// This case happens on initial chart load
return;
}
return gradient(ctx, chartArea);
}
I hope you have solved that by now. In any case, I think you should try to change the values you pass to createLinearGradient function. See this example (it's not mine, but helped me to understand that).
var ctx = document.getElementById("chart").getContext("2d");
/*** Gradient ***/
var gradient = ctx.createLinearGradient(0, 0, 0, 200);
gradient.addColorStop(0, 'rgba(250,174,50,1)');
gradient.addColorStop(1, 'rgba(250,174,50,0)');
/***************/
var data = {
labels : ["02:00","04:00","06:00","08:00","10:00","12:00","14:00","16:00","18:00","20:00","22:00","00:00"],
datasets: [
{
fillColor : gradient, // Put the gradient here as a fill color
strokeColor : "#ff6c23",
pointColor : "#fff",
pointStrokeColor : "#ff6c23",
pointHighlightFill: "#fff",
pointHighlightStroke: "#ff6c23",
data : [25.0,32.4,22.2,39.4,34.2,22.0,23.2,24.1,20.0,18.4,19.1,17.4]
}
]
};
var options = {
responsive: true,
datasetStrokeWidth : 3,
pointDotStrokeWidth : 4,
tooltipFillColor: "rgba(0,0,0,0.8)",
tooltipFontStyle: "bold",
tooltipTemplate: "<%if (label){%><%=label + ' hod' %>: <%}%><%= value + '°C' %>",
scaleLabel : "<%= Number(value).toFixed(0).replace('.', ',') + '°C'%>"
};
var myLineChart = new Chart(ctx).Line(data, options);
<canvas id="chart" width="800" height="400"></canvas>
I was using ChartJS v2 on a former project to create gauges looking like this:
During a React integration, I need to do the same thing but the freshly installed v3 version of this library, starting by the Doughnut modification itself.
Here is the current configuration:
export const GaugeChart: VFC<GaugeChartProps> = ({
value,
max = 100,
}) => {
const percent = value / max;
return <ChartJS
type="doughnut"
data={{
datasets: [
{
backgroundColor: [
'rgb(255, 99, 132)',
'#ccc',
],
data: [
percent * 100,
100 - (percent * 100),
],
},
],
}}
options={{
rotation: -1.0 * Math.PI, // start angle in radians
circumference: Math.PI, // sweep angle in radians
}}
/>
};
Note: type, data and options props are part of the ChartJS configuration itself, the component is just a wrapper.
Here is what I get:
What I am missing?
As per the migration guide in v3 the rotation and circumference options are in degrees instead of in radians, if you place them as degrees it works just fine:
var options = {
type: 'doughnut',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
backgroundColor: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"]
}]
},
options: {
rotation: 270, // start angle in degrees
circumference: 180, // sweep angle in degrees
}
}
var ctx = document.getElementById('chartJSContainer').getContext('2d');
new Chart(ctx, options);
<body>
<canvas id="chartJSContainer" width="600" height="400"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.5.1/chart.js"></script>
</body>
Here is an example that I use and it works fine with version 3.5.1
HTML
<div class="chartBox">
<canvas id="gauge"></canvas>
</div>
CSS
.chartBox {
width: 400px;
padding: 20px;
border-radius: 20px;
}
JavaScript
// setup
const data = {
labels: ["Safe", "Risky", "High Risk"],
datasets: [
{
label: "Gauge",
data: [100, 65, 35],
backgroundColor: [
"rgba(75, 192, 192, 0.8)",
"rgba(255, 206, 86, 0.8)",
"rgba(255, 26, 104, 0.8)",
],
needleValue: 50,
borderColor: "white",
borderWidth: 2,
cutout: "95%",
circumference: 180,
rotation: 270,
borderRadius: 5,
},
],
};
//gaugeNeedle
const gaugeNeedle = {
id: "gaugeNeedle",
afterDatasetDraw(chart, args, options) {
const {
ctx,
config,
data,
chartArea: { top, right, bottom, left, width, height },
} = chart;
ctx.save();
const needleValue = data.datasets[0].needleValue;
const dataTotal = data.datasets[0].data.reduce((a, b) => a + b, 0);
if (needleValue <= 100) {
var angle = Math.PI + (1 / 200) * needleValue * Math.PI;
console.log(angle);
} else if (needleValue <= 10000) {
var angle =
Math.PI +
(1 / 200) * 100 * Math.PI +
((1 / 200) * needleValue * Math.PI * 65) / 10000;
} else if (needleValue <= 1000000) {
var angle =
Math.PI +
(1 / 200) * 100 * Math.PI +
((1 / 200) * 10000 * Math.PI * 65) / 10000 +
((1 / 200) * needleValue * Math.PI * 35) / 1000000;
} else {
var angle = 0;
}
const cx = width / 2;
const cy = chart._metasets[0].data[0].y;
//needle
ctx.translate(cx, cy);
ctx.rotate(angle);
ctx.beginPath();
ctx.moveTo(0, -2);
ctx.lineTo(height - ctx.canvas.offsetTop - 160, 0); // change 160 value if the needle size gets changed
ctx.lineTo(0, 2);
ctx.fillStyle = "#444";
ctx.fill();
//needle dot
ctx.translate(-cx, -cy);
ctx.beginPath();
ctx.arc(cx, cy, 5, 0, 10);
ctx.fill();
ctx.restore();
//text
ctx.font = "20px Ubuntu";
ctx.fillStyle = "#444";
ctx.fillText(needleValue + " CPM", cx, cy + 50);
ctx.font = "10px Ubuntu";
ctx.fillText(0, 5, cy + 20);
ctx.fillText(100, cx, 90);
ctx.fillText("10k", cx + 185, 200); // change values if the position gets changed
ctx.fillText("1M", cx + 193, 320); // change values if the position gets changed
ctx.textAlign = "center";
ctx.restore();
},
};
// config
const config = {
type: "doughnut",
data,
options: {
plugins: {
legend: {
display: false,
},
tooltip: {
yAlign: "bottom",
displayColors: false,
callbacks: {
label: function (tooltipItem, data, value) {
return tooltipItem.label;
},
},
},
},
},
plugins: [gaugeNeedle],
};
// render init block
const myChart = new Chart(document.getElementById("gauge"), config);
Note: This works fine when the width is set 400px. If you change this value other parameters need to be changed accordingly. However, The affected locations are commented in the JavaScript.
In Google Charts, the 'hAxis': {'gridlines': {'count': 3} } statement seems to work, but when I'm using chartWrapper as part of an interactive plot, it does not. I don't really care about vertical gridlines, but I want to control how many labels are on the X axis. I think labels are usually attached to gridlines - one label per gridline.
I have an example from the Google Charts website, where the only thing I changed was to put try and put in 3 gridlines:
https://jsfiddle.net/emorris/gLcq1h2j/
chart option ticks is only supported by a continuous axis
in the fiddle you shared, the view placed on the chart,
converts the first column from type 'date' to 'string',
which results in a discrete axis
// Convert the first column from 'date' to 'string'.
'view': {
'columns': [{
'calc': function(dataTable, rowIndex) {
return dataTable.getFormattedValue(rowIndex, 0);
},
'type': 'string'
}, 1, 2, 3, 4]
}
to control how many labels are on the X axis, remove the view
to build the ticks dynamically here, use the state of the range filter,
to know the date range currently displayed on the chart
the chart will need to be redrawn when the control's 'statechange' event fires
see following working snippet, an axis label is created for every 5 days...
google.charts.load('current', {
callback: drawChartRangeFilter,
packages: ['corechart', 'controls']
});
function drawChartRangeFilter() {
var data = new google.visualization.DataTable();
data.addColumn('date', 'Date');
data.addColumn('number', 'Stock low');
data.addColumn('number', 'Stock open');
data.addColumn('number', 'Stock close');
data.addColumn('number', 'Stock high');
var open, close = 300;
var low, high;
for (var day = 1; day < 121; ++day) {
var change = (Math.sin(day / 2.5 + Math.PI) + Math.sin(day / 3) - Math.cos(day * 0.7)) * 150;
change = change >= 0 ? change + 10 : change - 10;
open = close;
close = Math.max(50, open + change);
low = Math.min(open, close) - (Math.cos(day * 1.7) + 1) * 15;
low = Math.max(0, low);
high = Math.max(open, close) + (Math.cos(day * 1.3) + 1) * 15;
var date = new Date(2012, 0, day);
data.addRow([date, Math.round(low), Math.round(open), Math.round(close), Math.round(high)]);
}
var dashboard = new google.visualization.Dashboard(
document.getElementById('dashboard')
);
var control = new google.visualization.ControlWrapper({
controlType: 'ChartRangeFilter',
containerId: 'control',
options: {
filterColumnIndex: 0,
ui: {
chartType: 'LineChart',
chartOptions: {
chartArea: {
width: '92%'
},
hAxis: {
baselineColor: 'none'
},
height: 72
},
chartView: {
columns: [0, 3]
},
minRangeSize: 86400000
}
},
state: {
range: {
start: new Date(2012, 1, 9),
end: new Date(2012, 2, 20)
}
}
});
var chart = new google.visualization.ChartWrapper({
chartType: 'CandlestickChart',
containerId: 'chart',
options: {
chartArea: {
height: '100%',
width: '100%',
top: 12,
left: 48,
bottom: 48,
right: 48
},
vAxis: {
viewWindow: {
min: 0,
max: 2000
}
},
legend: {
position: 'none'
}
}
});
google.visualization.events.addListener(control, 'statechange', setAxisTicks);
function setAxisTicks() {
var oneDay = (1000 * 60 * 60 * 24);
var dateRange = control.getState().range;
var ticksAxisH = [];
for (var i = dateRange.start.getTime(); i <= dateRange.end.getTime(); i = i + (oneDay * 5)) {
ticksAxisH.push(new Date(i));
}
if (ticksAxisH.length > 0) {
ticksAxisH.push(new Date(ticksAxisH[ticksAxisH.length - 1].getTime() + (oneDay * 5)));
}
chart.setOption('hAxis.ticks', ticksAxisH);
if (chart.getDataTable() !== null) {
chart.draw();
}
}
setAxisTicks();
dashboard.bind(control, chart);
drawDashboard();
$(window).resize(drawDashboard);
function drawDashboard() {
dashboard.draw(data);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="dashboard">
<div id="chart"></div>
<div id="control"></div>
</div>
I have a raphael circle and I want to attach a mouse event that launches a function. The function is called PlayAudioFile() and is inaccessible to the Raphael.js code block. I don't know how to modify the code below to make it's scope available.
window.onload = function () {
var R = Raphael(0, 0, "200px", "200px"),
r = R.circle(100, 100, 50).attr({fill: "hsb(0, 1, 1)", stroke: "none", opacity: .5}).click(function(){
alert("Wish I was an audio file being triggered instead"); // this needs to launch the playAudioFile() function. That function is not accessible however. So how do I modify playAudioFile()'s scope so that it is?
});
var start = function () {
this.ox = this.attr("cx");
this.oy = this.attr("cy");
this.animate({r: 70, opacity: .25}, 500, ">");
},
move = function (dx, dy) {
this.attr({cx: this.ox + dx, cy: this.oy + dy});
},
up = function () {
this.animate({r: 50, opacity: .5}, 500, ">");
};
R.set(r).drag(move, start, up);
};
var context = new webkitAudioContext(),
savedBuffer;
var nameOfAudioFile = new XMLHttpRequest();
nameOfAudioFile.open('GET', 'A.mp3', true);
nameOfAudioFile.responseType = 'arraybuffer';
nameOfAudioFile.onload = function () {
context.decodeAudioData(nameOfAudioFile.response,
function(incomingBuffer) {
//save the buffer, we'll reuse it
savedBuffer = incomingBuffer;
//once the file has been loaded, we can start listening for click on the div, and use playAudioFile since it no longer requires a buffer to be passed to it
var myDiv= document.getElementById("myDiv");
myDiv.addEventListener("click", playAudioFile , false);
}
);
playAudioFile = function () {
var source = context.createBufferSource();
source.buffer = savedBuffer;
source.connect(context.destination);
source.noteOn(0); // Play sound immediately
};
};
nameOfAudioFile.send();
</script>
<div id="myDiv">This div triggers playAudioFile() when clicked. Good!</div>
<style>
#myDiv {
position:relative;
left:150px;
top:240px;
background-color: green;
width:160px;
height:100px;
}
</style>
Try moving the playAudioFile function outside the onload-listener of nameOfAudioFile. Also, you could wrap the whole thing within the window.onload function to keep it all within that scope.
window.onload = function() {
var context = new webkitAudioContext(),
savedBuffer,
playAudioFile = function() {
var source = context.createBufferSource();
source.buffer = savedBuffer;
source.connect(context.destination);
source.noteOn(0); // Play sound immediately
};
var nameOfAudioFile = new XMLHttpRequest();
nameOfAudioFile.open('GET', 'A.mp3', true);
nameOfAudioFile.responseType = 'arraybuffer';
nameOfAudioFile.onload = function() {
context.decodeAudioData(nameOfAudioFile.response, function(incomingBuffer) {
savedBuffer = incomingBuffer;
var myDiv = document.getElementById("myDiv");
myDiv.addEventListener("click", playAudioFile, false);
//at this point we know that the buffer has loaded and it should be safe to draw the button
var R = Raphael(0, 0, "200px", "200px"),
r = R.circle(100, 100, 50).attr({
fill: "hsb(0, 1, 1)",
stroke: "none",
opacity: .5
}).click(function() {
playAudioFile();
});
var start = function() {
this.ox = this.attr("cx");
this.oy = this.attr("cy");
this.animate({
r: 70,
opacity: .25
}, 500, ">");
},
move = function(dx, dy) {
this.attr({
cx: this.ox + dx,
cy: this.oy + dy
});
},
up = function() {
this.animate({
r: 50,
opacity: .5
}, 500, ">");
};
R.set(r).drag(move, start, up);
});
};
nameOfAudioFile.send();
};