I have this little code snippet here
var context = new(window.AudioContext || window.webkitAudioContext)();
.....
var source = context.createMediaElementSource(audio);
var analyser = context.createAnalyser();
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
source.connect(analyser);
analyser.connect(context.destination);
analyser.fftSize = 256;
var bufferLength = analyser.frequencyBinCount;
var dataArray = new Uint8Array(bufferLength);
var WIDTH = canvas.width;
var HEIGHT = canvas.height + (canvas.height * 0.7);
var barWidth = (WIDTH / bufferLength) * 2.5;
var barHeight;
var x = 0;
function renderFrame() {
x = 0;
ctx.fillStyle = "#000";
ctx.fillRect(0, 0, WIDTH, HEIGHT);
analyser.getByteFrequencyData(dataArray);
for (var i = 0; i < bufferLength; i++) {
barHeight = dataArray[i];
var r = barHeight + (25 * (i / bufferLength));
var g = 250 * (i / bufferLength);
var b = 50;
ctx.fillStyle = "rgb(" + r + "," + g + "," + b + ")";
ctx.fillRect(x, HEIGHT - barHeight, barWidth, barHeight);
x += barWidth + 1;
}
requestAnimationFrame(renderFrame);
}
requestAnimationFrame(renderFrame);
audio.src = jQuery("source").attr("src");
audio.play();
Full code and demo here: https://jsfiddle.net/6gv39mk0/1/show
That basically shows a dynamic waveform when audio is played
It works on desktop browser, android browser, but no way to make it works on iPhone. Am I missing something or is there something that I must declare/do differently?
I've solved this issue with a transparent button on top of play button. this probably make iPhone browsers understand that there is an interaction. After that the button is hidden (z-index -1)
It's not that elegant as solution, but it work!
var button = document.createElement('button');
jQuery(button).attr('id', 'btn');
jQuery(canva).before(button);
jQuery(button).on('click', function() {
start();
jQuery(button).remove();
})
here it is the fiddle https://jsfiddle.net/L1trwz7o/
Related
onload that create 2 graphs and display them. they both worked when they where onclick="draw1()" but when i change them to onload only the last graph works with the onload
My First Graph
<script>
window.onload = function draw1() {
var n = "114,19,20,21,22,23,24";
var values = n.split(',');
var canvas = document.getElementById('myCanvas1');
var ctx = canvas.getContext('2d');
var width = 26; //bar width
var X = 60 // 60; // first bar position
var base = canvas.height;
var skipint = 0;
for (var i =0; i<values.length; i++) {
skipint ++;
var h = values[i];
var pers = h * (base / 100);
ctx.fillRect(X,canvas.height - pers,width,pers);
}
ctx.fillStyle = '#050505';
ctx.font="22px bold Arial";
ctx.fillText(' 0 %',0,canvas.height);
ctx.fillText(' 50 %',0,canvas.height /2 + 11);
ctx.fillText('100 %',0,canvas.height - canvas.height + 22);
}
</script>
My 1st canvas:
<canvas id="myCanvas1">
</canvas>
My Second graph
<script>
window.onload = function draw2() {
var n = "22,22,23,24";
var values = n.split(',');
//get the myCanvas2 byID
var canvas = document.getElementById('myCanvas2');
var ctx = canvas.getContext('2d');
var width = 26; //bar width
var X = 60 // 60; // first bar position
var base = canvas.height;
var skipint = 0;
//skips evry 3 bars
for (var i =0; i<values.length; i++) {
skipint ++;
var h = values[i];
var pers = h * (base / 100);
ctx.fillRect(X,canvas.height - pers,width,pers);
}
ctx.fillStyle = '#050505';
ctx.font="22px bold Arial";
ctx.fillText(' 0 %',0,canvas.height);
ctx.fillText(' 50 %',0,canvas.height /2 + 11);
ctx.fillText('100 %',0,canvas.height - canvas.height + 22);
}
</script>
My second canvas
<canvas id="myCanvas2">
</canvas>
Question:
How do i get both my graphs to work with window.onload?
You can declare each function, and then create a single function to call them both. I think it's easier to debug if you declare the functions outside of the event handler and then call them with the onload handler.
<script>
function draw1() {
var n = "114,19,20,21,22,23,24";
var values = n.split(',');
var canvas = document.getElementById('myCanvas1');
var ctx = canvas.getContext('2d');
var width = 26; //bar width
var X = 60 // 60; // first bar position
var base = canvas.height;
var skipint = 0;
for (var i = 0; i < values.length; i++) {
skipint++;
var h = values[i];
var pers = h * (base / 100);
ctx.fillRect(X, canvas.height - pers, width, pers);
}
ctx.fillStyle = '#050505';
ctx.font = "22px bold Arial";
ctx.fillText(' 0 %', 0, canvas.height);
ctx.fillText(' 50 %', 0, canvas.height / 2 + 11);
ctx.fillText('100 %', 0, canvas.height - canvas.height + 22);
}
</script>
<p>My first canvas</p>
<canvas id="myCanvas1">
</canvas>
<script>
function draw2() {
var n = "22,22,23,24";
var values = n.split(',');
//get the myCanvas2 byID
var canvas = document.getElementById('myCanvas2');
var ctx = canvas.getContext('2d');
var width = 26; //bar width
var X = 60 // 60; // first bar position
var base = canvas.height;
var skipint = 0;
//skips evry 3 bars
for (var i = 0; i < values.length; i++) {
skipint++;
var h = values[i];
var pers = h * (base / 100);
ctx.fillRect(X, canvas.height - pers, width, pers);
}
ctx.fillStyle = '#050505';
ctx.font = "22px bold Arial";
ctx.fillText(' 0 %', 0, canvas.height);
ctx.fillText(' 50 %', 0, canvas.height / 2 + 11);
ctx.fillText('100 %', 0, canvas.height - canvas.height + 22);
}
</script>
<p>My second canvas</p>
<canvas id="myCanvas2">
</canvas>
<script>
window.onload = function() {
draw1();
draw2();
}
</script>
The following code is my attempt to create a bar chart with javascript and the html 5 canvas:
var canvas = $("#chart");
var ctx = canvas.getContext("2d");
ctx.strokeFill = "green";
var margin = 5;
var bWidth = (canvas.width - (margin * results.length)) / results.length;
var max = results.sort()[results.length - 1];
var yScale = canvas.height / max;
for (result of results)
{
ctx.strokeRect();
}
The data I am trying to visualize looks like this:
[{"choice": "Yes", votes: 2}, {"choice": "No", votes: 1}, {"choice":"maybe", votes: 3}]
The questions are:
How can I compute the x and y axes for each element?
How can I print the choices under the bars?
There can be up to 20 choices and each can be up to 200 characters. How could this be handled?
After additional research the following is the solution:
var results = extractResults($("#results"));
var canvas = $("#chart");
var ctx = canvas.getContext("2d");
var margin = canvas.width * 0.005;
var bWidth = (canvas.width - (margin * results.length)) / results.length;
var max = Math.max.apply( Math, results );
var yScale = canvas.height / max;
var currX = margin;
ctx.font = "20px Arial"
for (i = 0; i < results.length; i++)
{
var bHeight = yScale * results[i];
ctx.fillStyle = "green";
ctx.fillRect(currX, canvas.height - bHeight, bWidth, bHeight);
ctx.fillStyle = "black";
ctx.fillText(i + 1, currX + bWidth / 2, canvas.height - canvas.height * 0.05, bWidth / 2);
currX += bWidth + margin;
}
I'm trying to make a player image move around on a canvas. The player image doesn't show up on load. I used an alert to check the onload and it does seem to be running but the image is not displayed.
The player image does not show up if I only move left and right, and it does not show up if I only move up and down. The image does show up after I have moved in both the X and Y directions which makes me think that the X and Y are not correctly set until my animation function sets them. I can't see what is wrong with the initial X and Y onload though I'm using my own images on my computer but I just plugged in some random pictures so you guys could see something load.
I just put the whole code on here I don't know if that is too much but I'm not sure what I did wrong. I'm very new at this and this is my first time posting a question on here. I would appreciate if someone tells me what I'm doing wrong.
edit: I changed
var destX = xToCenter;
var destY = yToCenter;
to just the actual numbers
var destX = 260;
var destY = 220;
and that works but I don't really understand why. Can someone explain why I can't use xToCenter and yToCenter for onload but it works during the movement function?
here is my jsfiddle
//create canvas
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext('2d');
canvas.width = 600;
canvas.height = 600;
//create background canvas
var worldCanvas = document.getElementById("worldCanvas");
var wctx = worldCanvas.getContext('2d');
worldCanvas.width = 600;
worldCanvas.height = 600;
//player image
var avatar = new Image();
var sourceX = 32;
var sourceY = 32;
var sourceWidth = 16;
var sourceHeight = 32;
var destWidth = sourceWidth * 5;
var destHeight = sourceHeight * 5;
var destX = xToCenter;
var destY = yToCenter;
var speed = 4;
var faceRight = 0;
var faceLeft = 1;
var faceDown = 2;
var faceUp = 3;
var animation = [0, 32, 64];
var i = 0;
//background image
var worldMap = new Image();
var sMapX = 0;
var sMapY = 0;
var sMapWidth = canvas.width;
var sMapHeight = canvas.height;
var dMapX = 0;
var dMapY = 0;
var dMapWidth = canvas.width;
var dMapHeight = canvas.height;
var worldWidth = 1280;
var worldHeight = 873;
//center player
var xToCenter = (0.5 * dMapWidth - 0.5 * destWidth);
var yToCenter = (0.5 * dMapHeight - 0.5 * destHeight);
//load and draw background
worldMap.src = "http://img06.deviantart.net/75db/i/2013/332/5/2/random_background_by_electriczerox-d6vyp1u.png";
worldMap.onload = function() {
wctx.drawImage(worldMap, sMapX, sMapY, sMapWidth, sMapHeight, dMapX, dMapY, dMapWidth, dMapHeight);
alert("worldMap loaded");
}
//load and draw avatar
avatar.src = "http://www.somerandomfacts.com/wp-content/uploads/2013/11/jpg1";
avatar.onload = function() {
ctx.drawImage(avatar, sourceX, sourceY, sourceWidth, sourceHeight, destX, destY, destWidth, destHeight);
alert("avatar loaded");
}
//clear and redraw
;
(function() {
function main() {
window.requestAnimationFrame(main);
wctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.clearRect(0, 0, canvas.width, canvas.height);
wctx.drawImage(worldMap, sMapX, sMapY, sMapWidth, sMapHeight, dMapX, dMapY, dMapWidth, dMapHeight);
ctx.drawImage(avatar, sourceX, sourceY, sourceWidth, sourceHeight, destX, destY, destWidth, destHeight);
}
main();
})();
//move avatar
window.addEventListener('keydown', function(event) {
var keyPressed = event.keyCode;
switch (keyPressed) {
//a moves left
case 65:
if (sMapX > 0) sMapX -= speed;
destX = xToCenter;
sourceX = faceLeft * sourceWidth;
animationLoop();
sourceY = animation[i];
break;
//w moves up
case 87:
if (sMapY > 0) sMapY -= speed;
destY = yToCenter;
sourceX = faceUp * sourceWidth;
animationLoop();
sourceY = animation[i];
break;
//d moves right
case 68:
if (sMapX < worldWidth - dMapWidth) sMapX += speed;
destX = xToCenter;
sourceX = faceRight * sourceWidth;
animationLoop();
sourceY = animation[i];
break;
//s moves down
case 83:
if (sMapY < worldHeight - dMapHeight) sMapY += speed;
destY = yToCenter;
sourceX = faceDown * sourceWidth;
animationLoop();
sourceY = animation[i];
break;
}
});
//animate while moving
function animationLoop() {
window.requestAnimationFrame(changeI);
}
function changeI() {
if (i <= animation.length) i += 1;
animation[i];
if (i == animation.length) i = 0;
}
.canvas {
border: 1px solid;
position: fixed;
top: 0;
left: 0;
}
.worldCanvas {
border: 1px solid;
z-index: -1;
position: fixed;
top: 0;
left: 0;
}
<canvas class="canvas" id="canvas"></canvas>
<canvas class="worldCanvas" id="worldCanvas"></canvas>
I'm still learning but I think I can answer my own question. When I create a variable I should give it an initial value before I set it equal to another variable.
I would like to create and add textual watermark to a webpage. It should be created in pure javascript.
EDIT:
Explanation: Take current page as an example and I wish I could display semi-transparent text "STACKOVERFLOW" in the middle of this page.
Making a watermark with pure JS is long, but easier with jQuery:
$(document).ready(function(){
var Html = "<div id='myDiv'>My Watermark</div>";
$("body").append(Html);
$("#myDiv").css({
"color":"#bbb","font-size":"100px",
"position":"absolute","top":"0px","left":"0px",
"z-index":"-1","transform":"rotate(45deg)"
});
});
See this jsfiddle: http://jsfiddle.net/jondinham/agz5tytb/
With pure JavaScript, it's harder because the 'transform' css is not a standard in old browsers. Anyway, it can be done this way:
var div = document.createElement("div");
document.getElementsByTagName("body")[0].appendChild(div);
div.innerHTML = "My Watermark";
div.style.color = "#bbb";
div.style.fontSize = "100px";
div.style.position = "absolute";
div.style.top = "0px";
div.style.left = "0px";
div.style.zIndex = "-1";
div.style.transform = "rotate(45deg)"; //standard
div.style.msTransform = "rotate(45deg)"; //IE
div.style.mozTransform = "rotate(45deg)"; //Firefox
div.style.webkitTransform = "rotate(45deg)"; //Chrome
div.style.oTransform = "rotate(45deg)"; //Opera
See jsfiddle: http://jsfiddle.net/jondinham/7fqg9n6w/
https://codepen.io/emrahaydemir/pen/OJZYwYz
async function addWatermarkToImage(file) {
return new Promise(async (resolve, reject) => {
const image = await fileToDataURL(file);
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
canvas.width = image.width;
canvas.height = image.height;
ctx.drawImage(image, 0, 0);
const fontSize =
(canvas.width + canvas.height) / ctx.measureText(text).width;
ctx.font = fontSize + "px verdana";
const textSize = ctx.measureText(text);
ctx.globalAlpha = watermarkOpacity;
ctx.fillStyle = waterMarkColor;
ctx.textAlign = "center";
let startY = -canvas.height / 2;
let startX = -canvas.width / 2;
const xGap = canvas.width * 0.07;
const yGap = canvas.height * 0.07;
for (let index = 0; startX < canvas.width; index++) {
for (let yIndex = 0; startY < canvas.height; index++) {
ctx.strokeText(text, startX, startY);
startY += fontSize + yGap;
}
startY = 0;
startX += textSize.width + xGap;
}
resolve(canvas.toDataURL());
});
}
I'm looking to build an image transform tool with Javascript. Something that utilizes handles around the image similar to Photoshop and allows the user to scale and rotate. I'm looking to make this work in IE 6 and up and Firefox 3+ and Safari 3+.
Does anyone know of a library or tool that could help with this? I've seen a lot of tools that utilize the Canvas element but that leaves out IT. I've also seen the Raphael library which might work. Any other options out there?
Have a look at this rotorzoom.
It rotates it zooms it's fast and i can do with a few more hits.
http://codepen.io/hex2bin/pen/tHwhF
var requestId = 0;
var animationStartTime = 0;
var img = new Image();
initimg(img);
dst = document.getElementById("dst").getContext("2d");
dst.drawImage(img, 0, 0, 256, 256);
// read the width and height of the canvas
i = 0;
var imageDataDst = dst.getImageData(0, 0, 1024, 512);
var bufDst = new ArrayBuffer(imageDataDst.data.length);
var buf8Dst = new Uint8ClampedArray(bufDst);
var data32Dst = new Uint32Array(bufDst);
var data32Src = new Uint32Array(256*256);
var scan1=0;
var scan4=0
// fill the source array with the image
for (var y = 0; y < 256; ++y) {
scan4=y*1024*4;
for (var x = 0; x < 256; ++x) {
data32Src[scan1++] =
(255 << 24) + // alpha
(imageDataDst.data[scan4+2] << 16) + // blue
(imageDataDst.data[scan4+1] << 8) + // green
imageDataDst.data[scan4]; // red
scan4=scan4+4;
}
}
animationStartTime = window.performance.now();
requestId = window.requestAnimationFrame(animate);
var j=0;
function animate(time) {
var height=512;
var width=1024;
j=j+1;
var timestamp = j / 100;
var pos;
var startY = 128;
var startX = 128;
var i=0;
var scaledHeight = 512 + Math.sin(timestamp*1.4) * 500;
var scaledWidth = 512 + Math.sin(timestamp*1.4) * 500
var angleRadians = timestamp;
var deltaX1 = Math.cos(angleRadians) * scaledHeight / 256;
var deltaY1 = Math.sin(angleRadians) * scaledHeight / 256;
var deltaY1x256=deltaY1*256;
var deltaX2 =Math.sin(angleRadians ) * scaledWidth / 256;
var deltaY2 =- Math.cos(angleRadians ) * scaledWidth / 256;
var h = height;
while (h--) {
var x =262144+ startX+deltaX1*-512+deltaX2*-256;
var y =262144+ startY+deltaY1*-512+deltaY2*-256;
var y256=y*256;
var w = width;
while (w--) {
//Optimised inner loop. Can it be done better?
pos =(y256>>0&0xff00)+(x>>0&0xff);
data32Dst[i++] =data32Src[pos];
x += deltaX1;
y256 += deltaY1x256;
//end of inner loop
}
startX += deltaX2
startY += deltaY2;
}
imageDataDst.data.set(buf8Dst);
dst.putImageData(imageDataDst, 0, 0);
requestId = window.requestAnimationFrame(animate);
}
function initimg(image1)
{
image1.src = 'data:image/jpeg;base64,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';
}
<body>
<canvas id="dst" width="1024", height="512">
Random Canvas
</canvas>
</body>
Check out Raphael library on Github: https://github.com/DmitryBaranovskiy/raphael