Is it possible to make elements inside a HTML5 Canvas element draggable and resizable. Is there any way to make the dynamic image in the following code to be movable:
var ctx, imgArray;
function initAll() {
ctx = document.getElementById("canvas").getContext("2d");
imgArray = ["http://i46.tinypic.com/nqe1dt.jpg",
"http://i50.tinypic.com/i21phi.jpg",
"http://i49.tinypic.com/1zmfcrq.jpg",
"http://i50.tinypic.com/v8g6mo.jpg",
"http://i49.tinypic.com/21kh7ah.jpg"];
drawCanvas();
document.getElementById("checkgroup").onchange = drawCanvas;
}
function drawCanvas() {
ctx.clearRect(0, 0, 600, 400);
for(var i=0; i < imgArray.length; ++i) {
var img = new Image();
img.posX = (i < 3) ? i*200 : (i-2.5)*200;
img.posY = (i < 3) ? 0 : 200;
img.src = imgArray[i];
img.onload = function() {
ctx.drawImage(this, this.posX, this.posY, 150, 150);
}
}
}
window.onload = initAll;
The project is found at JSBin: http://jsbin.com/welcome/7209/edit
Use KineticJS which provides shape object support for canvas.
KineticJS will provide mouse events for its shapes and thus you can implement drag-like functionality more easily:
http://www.html5canvastutorials.com/kineticjs/html5-canvas-drag-and-drop-tutorial/
Related
I want to visualize my sorting algorithms and redraw the created Canvas each time. My Old Canvas keeps all the old values. It just creates a new Canvas and puts it above the old Canvas. But I thought with the redraw I could solve it. I also tried to delete the canvas via canvas.remove() and create a completly new one and it also didn't worked out.
My setup call:
let canvas;
function setup() {
values = new Array(20);
this.canvas = createCanvas(values.length*w, 640);
createArray(values.length);
var slider = document.getElementById("slider");
slider.oninput = function() {
this.canvas = resizeCanvas(values.length*w, 640);
length = this.value;
createArray(length);
redraw();
}
var button = document.getElementById("btn");
button.onclick = function(){
quickSort(values, 0, values.length - 1);
}
}
And my draw call:
function draw() {
background(0);
for (let i = 0; i < values.length; i++) {
noStroke();
if (states[i] == 0) {
fill('#E0777D');
} else if (states[i] == 1) {
fill('#D6FFB7');
} else {
fill(255);
}
rect(i * w, height - values[i], w, values[i]);
}
}
Thanks for helping me out :).
Try to do canvas=null when you are done using the canvas
I have an image on canvas or a set of images that i draw on the canvas. I can draw them fine but I want to change the window level of the image on canvas by dragging the mouse over it. I've seen a lot of external javascript api's but they're quite huge and i don't want to use them for this purpose.
here's my JSFIDDLE that is basically drawing an image on the canvas
this is how my code looks
// Grab the Canvas and Drawing Context
var canvas = document.getElementById('c');
var ctx = canvas.getContext('2d');
// Create an image element
var img = document.createElement('IMG');
// When the image is loaded, draw it
img.onload = function () {
ctx.drawImage(img, 0, 0);
}
// Specify the src to load the image
img.src = "http://imgsv.imaging.nikon.com/lineup/lens/zoom/normalzoom/af-s_dx_18-140mmf_35-56g_ed_vr/img/sample/sample5_l.jpg";
i need something with basic JS or JQuery. it would be great if you can point me in the right direction using a sample code.
Thanks in advance.
If you want to use JavaScript, try something like:
<script>
var c = document.getElementById("drawingboard");
var ctx = c.getContext("2d");
var mouseDown = 0;
document.body.ontouchstart = function() {
mouseDown+=1;
}
document.body.ontouchend = function() {
mouseDown-=1;
}
function draw(event){
ctx.color='gold';
ctx.fillStyle = "lime";
ctx.drawImage(img,event.clientX,event.clientY);}
</script>
This is what I gained after some research:
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const rangeMin = level - window / 2;
const rangeMax = level + window / 2;
const totalSize = canvas.width * canvas.height;
for (let idx = 0; idx < totalSize; idx++) {
if (imageData.data[idx] < rangeMin) {
imageData.data[idx] = 0;
} else if (imageData.data[idx] > rangeMax) {
imageData.data[idx] = 255;
}
}
ctx.putImageData(imageData, 0, 0);
Using HTML5 canvas I'm trying to load images and create a 'crossfade' effect where the first image fades into view then, after a short delay, the second image fades in over top of first image, etc.
With the help of answers to similar questions on this forum I've got 2 separate bits of code working ... one which loads an array of images and a second which animates a 'fade in' effect. My problem is that I don't know how to combine these 2 scripts to load an array of images AND ALSO have each image in array fade in as it loads.
Here are the 2 separate scripts I've got working:
LOAD IMAGE ARRAY INTO CANVAS:
HTML
<canvas id="canvas" width=600 height=350></canvas>
JS
window.onload = function() {
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
var delay=2000;
var nextTime=0;
var nextImage=0;
var imageURLs=[];
imageURLs.push("img/sunflower0.jpg");
imageURLs.push("img/sunflower1.jpg");
imageURLs.push("img/sunflower2.jpg");
var imgs=[];
var imagesOK=0;
loadAllImages(start);
function loadAllImages(callback){
for (var i=0; i<imageURLs.length; i++) {
var img = new Image();
imgs.push(img);
img.onload = function(){
imagesOK++;
if (imagesOK >= imageURLs.length ) {
callback();
}
};
img.src = imageURLs[i];
}
}
function start(){
requestAnimationFrame(animate);
}
function animate(currentTime){
requestAnimationFrame(animate);
if(currentTime<nextTime){return;}
ctx.clearRect(0,0,cw,ch);
ctx.drawImage(imgs[nextImage],0,0);
nextTime=currentTime+delay;
nextImage++;
if(nextImage>imgs.length-1){nextImage=0;}
}
} // close window.onload
FADE IN IMAGES AS THEY LOAD INTO CANVAS:
I managed to get a separate bit of code working that does this using Canvas and Greensock TweenMax:
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.18.0/TweenMax.min.js"> </script>
<script>
var ctx, img;
function init() {
ctx = document.getElementById("canvas").getContext("2d");
img = new Image();
img.src = "img/sunflower0.jpg";
img.xpos = 0;
img.ypos = 0;
img.globalAlpha = 0;
img.onload = function() {
TweenMax.ticker.addEventListener("tick",loop);
}
TweenMax.to(img, 5 ,{globalAlpha:1});
}
function loop(){
ctx.clearRect(0,0,500,336);
ctx.globalAlpha = img.globalAlpha;
ctx.drawImage(img, img.xpos, img.ypos);
}
init();
Can anyone show me how to combine these two scripts to get a crossfade effect?
Many thanks!
I would use three canvases for this :
var imgs = [];
var rand = Math.random;
var common = "http://lorempixel.com/500/300?";
var imageURLs = [common + rand(), common + rand(), common + rand(), common + rand(), common + rand()];
var imagesOK = 0;
function loadAllImages(callback) {
for (var i = 0; i < imageURLs.length; i++) {
var img = new Image();
imgs.push(img);
img.onload = function() {
imagesOK++;
if (imagesOK >= imageURLs.length) {
callback();
}
};
img.src = imageURLs[i];
}
}
var ctx = main.getContext('2d');
var last = main.cloneNode(true).getContext('2d');
var next = main.cloneNode(true).getContext('2d');
var current = 0;
var op = 1;
function nextImage() {
if (current++ >= imgs.length - 1) current = 0;
op = 1;
fade();
}
function fade() {
op -= .01;
last.clearRect(0, 0, main.width, main.height);
last.globalAlpha = op;
last.drawImage(imgs[current], 0, 0);
next.clearRect(0, 0, main.width, main.height);
next.globalAlpha = 1 - op;
next.drawImage(imgs[(current + 1) % (imgs.length)], 0, 0);
ctx.clearRect(0, 0, main.width, main.height);
ctx.drawImage(last.canvas, 0, 0);
ctx.drawImage(next.canvas, 0, 0);
if (op <= 0) setTimeout(nextImage, 1500);
else requestAnimationFrame(fade);
}
loadAllImages(fade);
<canvas id="main" width="500" height="300"></canvas>
To fill a canvas with several images i am using the following code:
<canvas id="myCanvas"></canvas>
<script>
function loadImages(sources, callback) {
var images = {};
var loadedImages = 0;
var numImages = 0;
// get num of sources
for ( var src in sources) {
numImages++;
}
for ( var src in sources) {
images[src] = new Image();
images[src].onload = function() {
if (++loadedImages >= numImages) {
callback(images);
}
};
images[src].src = sources[src];
}
}
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
fitToContainer(canvas);
var sources = {
darthVader : 'http://www.html5canvastutorials.com/demos/assets/darth-vader.jpg',
yoda : 'http://www.html5canvastutorials.com/demos/assets/yoda.jpg'
};
loadImages(sources, function(images) {
context.drawImage(images.darthVader, 0,0);
context.drawImage(images.yoda, 0, 0);
});
function fitToContainer(canvas) {
canvas.style.width = '100%';
canvas.style.height = '100%';
canvas.width = canvas.offsetWidth;
canvas.height = canvas.offsetHeight;
}
</script>
Although this is in fact filling the canvas with images, i am not able to position the images in order not to overlap them. I dont know ahead of time the sizes of pictures. Is there any library or framework than can easily do this for me or what direction can i go?
And the canvas has a limited size since it is inside a parent html element.
Just keep track of the accumulated width of your images.
Then draw the next image to the right of that accumulated width
loadImages(sources, function(images) {
var nextX=0;
context.drawImage(images.darthVader, nextX,0);
nextX+=images.darthVader.width;
context.drawImage(images.yoda, nextX, 0);
nextX+=images.yoda.width;
// ...and so on...
});
I am using the HTML5 canvas and DrawImage functions to display low rate video. tnt gave excellent advice to get this project off the ground: Trying to use Canvas and DrawImage to display low-rate video at 90 degrees
While tnt's solution worked fine when the camera and angle are known at load time by using onload functions, I need to be able to turn the video off and on between several cameras and change other parameters. To handle that, a number of individual functions are needed, but I haven't been able to first do a setInterval on a camera and then pass the constantly changing image to DrawImage. 'cam_1.jpg' is the video in the example below. The functions shown in body onload below will also have to be called by other routines during runtime. Any advice will be appreciated.
var cam = null;
var c = null;
var ctx = null;
var ra = 0;
function init() {
cam = new Image;
c = document.getElementsByTagName('canvas')[0];
ctx = c.getContext('2d');
}
function draw(cam) {
ctx.save();
ctx.clearRect( 0, 0, 240, 320 );
ctx.translate( 240, 0);
ctx.rotate(1.57);
ctx.drawImage(cam, 0, 0 );
ctx.restore();
}
function inter() {
setInterval(function(){cam.src = 'cam_1.jpg?uniq='+Math.random();},500);
}
</script></head><body onload = "init(), draw(cam), inter()" >
Thank you.
I suggest you use an object array; something like this:
var cams = []; // an array to hold you cams!
function addcam() {
this.image = new Image;
this.setting1 = 0;
this.settingn = 0;
}
cams[1] = addcam();
cams[1].image.src = "cam1.jpg";
cams[1].setting1 = 2;
setInterval(function(){cam.src = '+cams[1].image.src+'?uniq='+Math.random();},500);
#tnt, Are you suggesting the following? Thank you:
var cams = []; // an array to hold you cams!
function addcam() {
this.image = new Image;
this.setting1 = 0;
this.settingn = 0;
}
function draw(camnum){
cams[1] = addcam();
cams[1].image.src = "cam_1.jpg";
cams[1].setting1 = 2;
cam = new Image;
c = document.getElementsByTagName('canvas')[0];
ctx = c.getContext('2d');
}
function inter() {
setInterval(function(){'cam.src = ' +cams[1].image.src+ '?uniq='+Math.random();},500);
}
function draw(cam) {
ctx.save();
ctx.clearRect( 0, 0, 240, 320 );
ctx.translate( 240, 0);
ctx.rotate( 1.57);
ctx.drawImage(this, 0, 0 );
ctx.restore();
}
</script></head><body onload = "draw(cam), inter()" >