Canvas multiply hover effect - javascript

I´m trying to make a hover multiply effect over an image. I´m following this tutorial:
Demo:
http://albertogasparin.it/demo/multiply-filter/
http://albertogasparin.it/articles/2011/05/html5-multiply-filter-canvas/
The problem I have is that I don´t know how to pass to function so it works just on hover over the "id="multiply_hover", because right now the multiply filter is shown after page load.
This is my markup:
<div class="item">
<img id="multiply_hover" src="img/coleccionesII_1.jpg" alt="coleccionesII_1" width="195" height="343">
<div class="item_info">
<div class="item_text">
SEDA BLOUSE BOLSILLOS
CREP PANTALÓN
Zapato Rojo
</div>
</div>
</div>
With this script:
var multiplyFilter = (function() {
//** private vars **//
var multiplyColor,
imageBottom, imageId,
canvas;
//** private functions **//
function createCanvas() {
canvas = document.createElement('canvas');
canvas.width = imageBottom.width;
canvas.height = imageBottom.height;
imageBottom.parentNode.insertBefore(canvas, imageBottom);
// no canvas support?
if (!canvas.getContext) { return; }
draw();
}
function draw() {
var context, imgData, pix,
w = imageBottom.width,
h = imageBottom.height;
// get 2d context
context = canvas.getContext('2d');
// draw the image on the canvas
context.drawImage(imageBottom, 0, 0);
// Get the CanvasPixelArray from the given coordinates and dimensions.
imgData = context.getImageData(0, 0, w, h);
pix = imgData.data;
// Loop over each pixel and change the color.
for (var i = 0, n = pix.length; i < n; i += 4) {
pix[i ] = multiplyPixels(multiplyColor[0], pix[i ]); // red
pix[i+1] = multiplyPixels(multiplyColor[1], pix[i+1]); // green
pix[i+2] = multiplyPixels(multiplyColor[2], pix[i+2]); // blue
// pix[i+3] is alpha channel (ignored)
// another check to see if image is still empty
if(i < 5 && !pix[i] && !pix[i+1] && !pix[i+2] && !pix[i+3]) {
canvas.parentNode.removeChild(canvas);
setTimeout(function() { multiplyFilter.init(imageId, multiplyColor); }, 500);
return false;
}
}
// Draw the result on the canvas
context.putImageData(imgData, 0, 0);
}
//** helper function **//
function multiplyPixels(topValue, bottomValue) {
// the multiply formula
return topValue * bottomValue / 255;
}
//** public functions **//
return {
init : function(imgId, color) {
imageId = imgId;
imageBottom = document.getElementById(imageId);
multiplyColor = color;
// lauch the draw function as soon as the image is loaded
if(imageBottom && imageBottom.clientWidth > 50) { // image loaded
createCanvas();
} else { // not yet ready
setTimeout(function() { multiplyFilter.init(imageId, color); }, 1000);
}
}
}
})();
multiplyFilter.init('multiply_hover', [0, 0, 210]);
I tried using something like this, which on hover works but not well at all, cause it creates on every hover a new canvas element:
// Hover effect
$(".item").bind('mouseenter', function() {
$(this).children(".item_info").fadeIn();
multiplyFilter.init('multiply_hover', [0, 0, 210]);
});
$(".item").bind('mouseleave', function() {
$(this).children(".item_info").fadeOut();
});
Any ideas on how to properly pass the function on hover ?

Try this code:
<!DOCTYPE html>
<html>
<body>
<div class="item">
<img id="multiply_hover" src="img/coleccionesII_1.jpg" alt="coleccionesII_1">
<div class="item_info">
<div class="item_text">
SEDA BLOUSE BOLSILLOS
CREP PANTALÓN
Zapato Rojo
</div>
</div>
</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
var multiplyFilter = (function() {
//** private vars **//
var multiplyColor,
imageBottom, imageId,
canvas;
//** private functions **//
function createCanvas() {
canvas = document.createElement('canvas');
canvas.width = imageBottom.width;
canvas.height = imageBottom.height;
imageBottom.parentNode.insertBefore(canvas, imageBottom);
// no canvas support?
if (!canvas.getContext) { return; }
draw();
}
function draw() {
var context, imgData, pix,
w = imageBottom.width,
h = imageBottom.height;
// get 2d context
context = canvas.getContext('2d');
// draw the image on the canvas
context.drawImage(imageBottom, 0, 0);
// Get the CanvasPixelArray from the given coordinates and dimensions.
imgData = context.getImageData(0, 0, w, h);
pix = imgData.data;
// Loop over each pixel and change the color.
for (var i = 0, n = pix.length; i < n; i += 4) {
pix[i ] = multiplyPixels(multiplyColor[0], pix[i ]); // red
pix[i+1] = multiplyPixels(multiplyColor[1], pix[i+1]); // green
pix[i+2] = multiplyPixels(multiplyColor[2], pix[i+2]); // blue
// pix[i+3] is alpha channel (ignored)
// another check to see if image is still empty
if(i < 5 && !pix[i] && !pix[i+1] && !pix[i+2] && !pix[i+3]) {
canvas.parentNode.removeChild(canvas);
setTimeout(function() { multiplyFilter.init(imageId, multiplyColor); }, 500);
return false;
}
}
// Draw the result on the canvas
context.putImageData(imgData, 0, 0);
}
//** helper function **//
function multiplyPixels(topValue, bottomValue) {
// the multiply formula
return topValue * bottomValue / 255;
}
//** public functions **//
return {
init : function(imgId, color) {
imageId = imgId;
imageBottom = document.getElementById(imageId);
multiplyColor = color;
// lauch the draw function as soon as the image is loaded
if(imageBottom && imageBottom.clientWidth > 50) { // image loaded
createCanvas();
} else { // not yet ready
setTimeout(function() { multiplyFilter.init(imageId, color); }, 1000);
}
//Hide the original image
$('#'+imgId).hide();
}
}
})();
// Hover effect
$(".item").bind('mouseenter', function() {
$(this).children(".item_info").fadeIn();
multiplyFilter.init('multiply_hover', [0, 0, 210]);
});
$(".item").bind('mouseleave', function() {
$(this).children(".item_info").fadeOut();
$('canvas').hide(); //hide the canvas
$('#multiply_hover').show(); //show the original image
});
</script>
</body>
</html>
I modified the multiply script to make it hide the original image, and the hover effect to make it hide the canvas and show the original image

Do you try this http://api.jquery.com/hover/ ?
You can use this to add a function to $("#multiply_hover"). Hover Jquery has handler IN and OUT

Related

Similar images displaying using canvas

I am trying to display multiple images on canvas. The most recently added image on canvas must be draggable. This is the HTML code.
<canvas id="panoramaCanvas" width=1500 height=1000></canvas>
I am using an object to keep the track of already added images. Each time I drag Image on canvas then this method gets called. storeData stores currently added image data.
var storeData = []; // Object
var panoramaImg = new Image();
var imgNumber = 0;
function handleDrop(e) {
e.stopPropagation();
e.preventDefault();
//
var url = e.dataTransfer.getData('text/plain');
// for img elements, url is the img src so
// create an Image Object & draw to canvas
if (url) {
panoramaImg.onload = function () {
panoramaCtx.globalAlpha = 0.4;
panoramaCtx.drawImage(panoramaImg, 0, 0, this.width, this.height, 0, 0, 500, 500);
panoramaCtx.globalAlpha = 1.0;
storeData.push({
imgData: panoramaImg,
imgNo: imgNumber + 1,
xPoint: 0,
yPoint: 0,
});
imgNumber = imgNumber + 1;
}
//img.width, img.height, 0, 0, rangeWidth.value, rangeHeight.value
panoramaImg.src = url;
// for img file(s), read the file & draw to canvas
} else {
handleFiles(e.dataTransfer.files);
}
}
On mouse event this method is called.
var canvasOffset1 = $("#panoramaCanvas").offset();
var offsetX1 = canvasOffset1.left;
var offsetY1 = canvasOffset1.top;
var canvasWidth = panoramaCanvas.width;
var canvasHeight = panoramaCanvas.height;
var isDragging = false;
function handleMouseDownEvent(e) {
canMouseX = parseInt(e.clientX - offsetX1);
canMouseY = parseInt(e.clientY - offsetY1);
// set the drag flag
isDragging = true;
}
function handleMouseUpEvent(e) {
canMouseX = parseInt(e.clientX - offsetX1);
canMouseY = parseInt(e.clientY - offsetY1);
// clear the drag flag
isDragging = false;
}
function handleMouseOutEvent(e) {
canMouseX = parseInt(e.clientX - offsetX1);
canMouseY = parseInt(e.clientY - offsetY1);
// user has left the canvas, so clear the drag flag
//isDragging=false;
}
function handleMouseMoveEvent(e) {
canMouseX = parseInt(e.clientX - offsetX1);
canMouseY = parseInt(e.clientY - offsetY1);
// if the drag flag is set, clear the canvas and draw the image
if (isDragging) {
panoramaCtx.clearRect(0, 0, canvasWidth, canvasHeight);
panoramaCtx.globalAlpha = 0.4;
if (storeData.length > 1)
{
for (var i = 0; i <= storeData.length - 2; i++) {
panoramaCtx.drawImage(storeData[i].imgData, storeData[i].xPoint, storeData[i].yPoint,
500, 500);
}
}
panoramaCtx.drawImage(panoramaImg, canMouseX - 1128 / 2, canMouseY - 120 / 2, 500, 500);
panoramaCtx.globalAlpha = 1.0;
storeData[imgNumber - 1].xPoint = canMouseX - 1128 / 2;
storeData[imgNumber - 1].yPoint = canMouseY - 120 / 2;
console.log(storeData);
}
}
When I add first image everything works fine with mouse events but when I add second image the image data first change change to image data of second image.
When I tried to change the position of second second image and image data of first image changes.
Where am I doing wrong while displaying image?
You are creating a single HTMLImageElement panoramaImg. The imgData property of all your storeData members are thus the same and only HTMLImageElement which points to the last dropped image.
Simply create a new Image() in your drop handler instead of reusing the same.

canvas rectangles get drawn then disappear javascript

I want to have a canvas with a background image, and draw rectangles over the top. The rectangles are called hotSpots in my application. They get drawn to the canvas then quickly disappear. How can I make them stay?
appendSection() first appends a picture with appendPicture() which just appends a canvas to a div, then after that function has run, the canvas and context is made, then for every hotSpot, which there are 3 in this case, it will draw a rect, which it does, then they disappear.
function appendSection(theSection, list) {
list.append('<label class="heading">' + theSection.description + '</label><br/><hr><br/>');
if (theSection.picture) {
appendPicture(list, theSection);
var canvas = document.getElementById('assessmentImage');
var ctx=canvas.getContext("2d");
var img=new Image();
img.onload = function() {
ctx.drawImage(img, 0, 0,canvas.width,canvas.height);
}
img.src = "data:image/jpeg;base64,"+ theSection.picture;
if(theSection.allHotSpots.length > 0) {
for( var x = 0; x < theSection.allHotSpots.length; x++) {
appendHotSpot(list, theSection.allHotSpots[x], theSection.thePicture, ctx);
}
}
}
appendSectionQuestions(theSection, list);
if (theSection.allSubSections) {
for (var x = 0; x < theSection.allSubSections.length; x++) {
var theSectionA = theSection.allSubSections[x];
appendSection(theSectionA, list);
}
}
}
function appendHotSpot(list, HotSpot, picture, ctx) {
var imageWidth = document.getElementById('assessmentImage' + platform).clientWidth;
var imageHeight = document.getElementById('assessmentImage' + platform).clientHeight;
var xScale = imageWidth / picture.xSize;
var yScale = imageHeight / picture.ySize;
HotSpot.topLeft = [Math.round(HotSpot.topLeft[0] * xScale), Math.round(HotSpot.topLeft[1] * yScale)];
HotSpot.bottomRight = [Math.round(HotSpot.bottomRight[0] * xScale), Math.round(HotSpot.bottomRight[1] * yScale)];
var rect = {x1: HotSpot.topLeft[0], y1: HotSpot.topLeft[1], x2: HotSpot.bottomRight[0], y2: HotSpot.bottomRight[1]};
ctx.fillStyle = "#FF0000";
ctx.fillRect(rect.x1, rect.y1, rect.x2, rect.y2);
//addRect("blue", rect);
}
function appendPicture(list, theSection) {
list.append('<div id="wrapper' + platform + '" style="width:100%; text-align:center">\
<canvas class="assessmentImageSmall" style="width:100%;" id="assessmentImage' + platform + '" align="middle" ></canvas>\
<!--<p style="color:#666;" id="imageInstruction">Tap image to enlarge.</p>-->\
</div>');
$("#wrapper").kendoTouch({
tap: function (e) {
switchImage();
}
});
}
It looks like your rects are being drawn and then the image (which loads asynchronously) is eventually loaded and then drawn on top of the rects--making them disappear.
Put the if(theSection.allHotSpots.length > 0 inside the onload so the image doesn't later clobber the rects.

2 images animated using Javascript

From doing research and asking for help I have so far built an animation moving from left to right using the code in the JSFiddle below. This loops every 20 seconds.
http://jsfiddle.net/a9HdW/3/
However now I need a second image that moves from right to left and for this to automatically trigger straight after the first image has completed its animation.
If you could do this that would be amazing.
Thanks In Advance
<canvas id="canvas" width="1600" height="300"></canvas>
<script>
window.requestAnimFrame = (function(){
window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function( callback ){
window.setTimeout(callback, 1000 / 60);
};
})();
var canvas = document.getElementById("canvas"),
cx = canvas.getContext("2d");
function Card(x,y){
this.x = x || -300;
this.y = y || 0;
this.width = 0;
this.height = 0;
this.img=new Image();
this.init=function(){
// this makes myCard available in the img.onload function
// otherwise "this" inside img.onload refers to the img
var self=this;
this.img.onload = function()
{
// getting width and height of the image
self.width = this.width;
self.height = this.height;
self.draw();
loop();
}
this.img.src = "f15ourbase.png";
}
this.draw = function(){
cx.drawImage(this.img, this.x, this.y);
}
}
var myCard = new Card(50,50);
myCard.init();
function loop(){
if((myCard.x + myCard.width) < canvas.width){
requestAnimFrame(loop);
} else {
setTimeout(function() {
// resetting card back to old state
myCard.x = 50;
myCard.y = 50;
// call the loop again
loop();
}, 20000);
}
cx.clearRect(0, 0, canvas.width, canvas.height);
myCard.x = myCard.x + 15;
myCard.draw();
}
This is little bit complicated, however, it boils down to formatting your Card function to understand which direction it is going to. Therefore you will need direction parameter and more complicated draw function which updates your card movement to direction it is supposed to go, like this:
// Updating own position, based on direction
if(this.direction === 1) {
this.x = this.x + this.stepSize; // we move to right
// if I am over canvas at right, I am done animating
if(this.x >= canvas.width) {
this.finishedAnimation = true;
}
} else {
this.x = this.x - this.stepSize; // we move to left
// if I am over canvas at left, I am done animating
if(this.x <= -this.width) {
this.finishedAnimation = true;
}
}
Also, because timing is important - you will need to trigger other card movement only after the first one is completed. Like this:
// We won't draw next card before previous is finished
if(!cardToRight.finishedAnimation) {
cardToRight.draw();
} else {
// Card at right is finished, we move the left card now
cardToLeft.draw();
}
To summarize my points, I made a code which has code comments to explain it's contents, go it through carefully:
// Animation frame gist
window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function( callback ){
window.setTimeout(callback, 1000 / 60);
};
})();
// Variable declarations
var canvas = document.getElementById("canvas"),
cx = canvas.getContext("2d"),
// Handlers for both of the cards
cardToRight,
cardToLeft;
/**
* Card declaration
*
*/
var Card = function(x, y, direction) {
// how many pixels we move
this.stepSize = 5;
// x and y position on canvas
this.x = x;
this.y = y;
// Copy values are used when reset is done
this.xCopy = this.x;
this.yCopy = this.y;
// handle to specify if animation finished
this.finishedAnimation = false;
// 1 means move to right, 0 means move to left
this.direction = direction;
// Image of the card
this.img = undefined;
// Image url for this card
this.imgSrc = "http://placehold.it/350x150"; // for your image: "f15ourbase.png"
// Image width
this.width = 0;
};
/**
* Initialize
*
*/
Card.prototype.init = function(callback) {
// self refers to this card
var self = this;
this.img = new Image();
// onload success callback
this.img.onload = function() {
// Setting own width
self.width = this.width;
// triggering callback on successfull load
return callback();
};
// onload failure callback
this.img.onerror = function() {
// Returning error message for the caller of this method
return callback("Loading image " + this.imgSrc + " failed!");
};
// Triggering image loading
this.img.src = this.imgSrc;
};
/**
* Draw self
*
*/
Card.prototype.draw = function() {
// Updating own position, based on direction
if(this.direction === 1) {
this.x = this.x + this.stepSize; // we move to right
// if I am over canvas at right, I am done animating
if(this.x >= canvas.width) {
this.finishedAnimation = true;
}
} else {
this.x = this.x - this.stepSize; // we move to left
// if I am over canvas at left, I am done animating
if(this.x <= -this.width) {
this.finishedAnimation = true;
}
}
// cx (context) could be also passed, now it is global
cx.drawImage(this.img, this.x, this.y);
};
/**
* Reset self
*
*/
Card.prototype.reset = function() {
// Using our copy values
this.x = this.xCopy;
this.y = this.yCopy;
// handle to specify if animation finished
this.finishedAnimation = false;
};
/**
* Main loop
*
*/
function loop() {
// Clear canvas
cx.clearRect(0, 0, canvas.width, canvas.height);
// We won't draw next card before previous is finished
// Alternatively, you could make getter for finishedAnimation
if(!cardToRight.finishedAnimation) {
cardToRight.draw();
} else {
// Card at right is finished, we move the left card now
cardToLeft.draw();
}
// If cardToLeft not yet animated, we are still pending
if(!cardToLeft.finishedAnimation) {
// Schedule next loop
// "return" makes sure that we are not executing lines below this
return requestAnimFrame(loop);
}
// Animation finished, starting again after 5 seconds
setTimeout(function() {
// Resetting cards
cardToRight.reset();
cardToLeft.reset();
// Start the loop again
loop();
}, 5000); // 5000 milliseconds = 5 seconds
};
/**
* Main program below
*
*/
// Card to right (1 denotes it's direction to right)
cardToRight = new Card(50, 50, 1);
// Card to left (0 denotes it's direction to left)
cardToLeft = new Card(1000, 50, 0);
// Initialize cardToRight & cardToLeft
// Because using only two cards, we can do a bit nesting here
cardToRight.init(function(err) {
// If error with image loading
if(err) {
return alert(err);
}
// Trying to initialize cardToLeft
cardToLeft.init(function(err) {
// If error with image loading
if(err) {
alert(err);
}
// All ok, lets do the main program
loop();
});
});
As a special note: If you wan't your cards appear outside the canvas remember to change values of below accordingly:
// Card to right (1 denotes it's direction to right)
cardToRight = new Card(50, 50, 1); // 50 <- x position of right card
// Card to left (0 denotes it's direction to left)
cardToLeft = new Card(1000, 50, 0); // 1000 <- x position of left card
Finally, here is working JsFiddle example

Canvas and animation

I was trying to create a sample paint application using HTML 5 canvas. Then I added a button to redraw what user had drawn earlier. I am not sure what I am doing wrong or may be completely wrong. When I click redraw button multiple times it generates some magical animation by drawing lines all over. Even though if I log the starting point of drawing the image its same every time.
Demo: http://jsfiddle.net/BW57H/6/
Steps to reproduce:
Draw some circle or rectangle or something by clicking the mouse and dragging it on the rectangular box. Then click reset and redraw , click redraw couple of times after that and see the result.
I am not sure what I have done. I have not read a lot about Canvas. But I am curious to know what is going on here. Thanks.
html
<body>
<canvas id="paint" width="600px" height="300px"></canvas>
<div id="controls">
<button name="reset" id="reset">Reset</button>
<button name="redraw" id="redraw">Re-Draw</button>
</div>
</body>
css
#paint{
border: solid;
}
js
$(document).ready(function(){
var x, y, context, painter;
var xCounter = 0 , yCounter = 0;
var xarray = [];
var yarray = [];
function init(){
while(document.getElementById("paint") === undefined){
//do nothing
}
console.log("Loaded document now registering events for canvas");
var canvas = document.getElementById("paint");
context = canvas.getContext('2d');
painter = new Painter();
canvas.addEventListener('mousedown', capture, false);
canvas.addEventListener('mouseup', capture, false);
canvas.addEventListener('mousemove', capture, false);
document.getElementById("reset").addEventListener("click",function(){ clearCanvas(canvas);}, false);
document.getElementById("redraw").addEventListener("click", function(){
autoDraw();
}, false);
}
function clearCanvas(canvas){
context.save();
// Use the identity matrix while clearing the canvas
context.setTransform(1, 0, 0, 1, 0, 0);
context.clearRect(0, 0, canvas.width, canvas.height);
// Restore the transform
context.restore();
};
function capture(event){
if(event.which !== 1){
return;
}
x = event.layerX;
y = event.layerY;
switch(event.type){
case 'mousedown':
painter.startPaint(event);
break;
case 'mouseup':
painter.endPaint(event);
break;
case 'mousemove':
painter.paint(event);
break;
}
};
var Painter = function(){
var self = this;
self.paintStarted = false;
self.startPaint = function(event){
self.resetRecordingParams();
self.paintStarted = true;
context.beginPath();
context.moveTo(x,y);
self.record();
}
self.endPaint = function(event){
self.paintStarted = false;
self.record();
self.paint(event)
}
self.paint = function(event){
if(self.paintStarted){
context.lineTo(x,y);
context.stroke();
self.record();
}
}
self.record = function(){
xarray[xCounter++] = x;
yarray[yCounter++] = y;
}
self.resetRecordingParams = function(){
xarray = [];
yarray = [];
xCounter = 0;
yCounter= 0;
}
return self;
}
function autoDraw(){
context.beginPath();
console.log('starting at: '+xarray[0]+','+yarray[0]);
context.moveTo(xarray[0],yarray[0]);
for (var i = 0; i < xarray.length; i++) {
setTimeout(drawLineSlowly, 1000+(i*20), i);
};
}
function drawLineSlowly(i)
{
context.lineTo(xarray[i],yarray[i]);
context.stroke();
}
init();
});
You don't have any kind of check to see whether or not you are already drawing, so here is your code with those changes commented, as well as the real-pixel-location fixes (http://jsfiddle.net/upgradellc/htJXy/1/):
$(document).ready(function(){
var x, y, context, painter, canvas;
var xCounter = 0 , yCounter = 0;
var xarray = [];
var yarray = [];
function init(){
while(document.getElementById("paint") === undefined){
//do nothing
}
console.log("Loaded document now registering events for canvas");
canvas = document.getElementById("paint");
context = canvas.getContext('2d');
painter = new Painter();
canvas.addEventListener('mousedown', capture, false);
canvas.addEventListener('mouseup', capture, false);
canvas.addEventListener('mousemove', capture, false);
document.getElementById("reset").addEventListener("click",function(){ clearCanvas(canvas);}, false);
document.getElementById("redraw").addEventListener("click", function(){
autoDraw();
}, false);
}
function clearCanvas(canvas){
context.save();
// Use the identity matrix while clearing the canvas
context.setTransform(1, 0, 0, 1, 0, 0);
context.clearRect(0, 0, canvas.width, canvas.height);
// Restore the transform
context.restore();
};
function capture(event){
if(event.which !== 1){
return;
}
tempPos = getMousePos(canvas, event);
x = tempPos.x;
y = tempPos.y;
switch(event.type){
case 'mousedown':
painter.startPaint(event);
break;
case 'mouseup':
painter.endPaint(event);
break;
case 'mousemove':
painter.paint(event);
break;
}
};
var Painter = function(){
var self = this;
self.paintStarted = false;
//this keeps track of whether or not we are currently auto drawing
self.currentlyAutoDrawing = false;
self.startPaint = function(event){
self.resetRecordingParams();
self.paintStarted = true;
context.beginPath();
context.moveTo(x,y);
self.record();
}
self.endPaint = function(event){
self.paintStarted = false;
self.record();
self.paint(event);
}
self.paint = function(event){
if(self.paintStarted){
context.lineTo(x,y);
context.stroke();
self.record();
}
}
self.record = function(){
xarray[xCounter++] = x;
yarray[yCounter++] = y;
}
self.resetRecordingParams = function(){
xarray = [];
yarray = [];
xCounter = 0;
yCounter= 0;
}
return self;
}
function autoDraw(){
context.beginPath();
//If we are already auto-drawing, then we should just return instead of starting another drawing loop cycle
if(painter.currentlyAutoDrawing){
console.log("painter is already auto drawing");
return;
}
painter.currentlyAutoDrawing = true;
console.log('starting at: '+xarray[0]+','+yarray[0]);
context.moveTo(xarray[0],yarray[0]);
for (var i = 0; i < xarray.length; i++) {
setTimeout(drawLineSlowly, 1000+(i*20), i);
};
}
function drawLineSlowly(i)
{
//when we reach the last element in the array, update painter with the fact that autodrawing is now complete
if(xarray.length == i+1){
painter.currentlyAutoDrawing=false;
}
console.log(xarray.length+" "+i);
context.lineTo(xarray[i],yarray[i]);
context.stroke();
}
function getMousePos(canv, evt) {
var rect = canv.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
init();
});
Obviously you don't stop the previous timeout loop before you start a new...
Use setInterval instead of setTimeout, and clearInterval by next push. So I think the problem is not with the canvas, just with your redraw animation. Btw it is strange because there is some difference between the redraw and the original draw...
var drawInterval = null;
function autoDraw(){
if (drawInterval) {
//here your can reset the previous - still running - redraw
clearInterval(drawInterval);
}
context.beginPath();
console.log('starting at: '+xarray[0]+','+yarray[0]);
context.moveTo(xarray[0],yarray[0]);
var i=0;
setInterval(function (){
++i;
if (i<xarray.length)
drawLineSlowly(i);
else
clearInterval(drawInterval);
},20);
}
note:
There is still bug in the redraw, but at least it does not kill the browser...
Btw the strange "animation" is because you does not check by redraw if you are currently drawing or not, so you start draw and redraw together and they interfere... You have to stop redraw when you start drawing.

Display image with canvas tag trouble

I am new with jquery , i have a small project about display image with canvas. All will good , but i have a trouble when try display all image , i try to use .each(function) or loop but not work
This is my trouble , any one can help ?. Thanks
http://jsfiddle.net/NcKfr/6/
<textarea id="textid">blah blah blah</textarea>
<canvas id="ca1" width="640" height="480"></canvas>
<script>
$(document.body).find('*').each(function() {
var tmp = $("textarea").children().remove();
var text = $("textarea").text();
text = text.replace(/<li>/g, "").replace(/<\/li>/g, "").replace(/<br \/>/g, "").replace(/\/>/g, "").replace(/<img/g, "").replace(/ /g, "");
$("textarea").text(text);
$("textarea").append(tmp);
});
</script>
Script code :
$(function(e) {
var data = $("#textid").val();
rows = data.split('src="');
partNum = [];
var i;
var len = rows.length;
var can = document.getElementsByTagName('canvas')[0];
var ctx = can.getContext('2d');
$(document).ready(function() {
for (i = 1; i < len; i++) {
partNum[i] = rows[i].substr(0,rows[i].indexOf('"'));
$.getImageData({
url: partNum[i],
success: function(image) {
// Set the canvas width and heigh to the same as the image
$(can).attr('width', image.width);
$(can).attr('height', image.height);
$(can).css({
'background-color': 'none',
'border-color': '#fff'
});
// Draw the image on to the canvas
ctx.drawImage(image, 0, 0, image.width, image.height);
},
error: function(xhr, text_status) {
// Handle your error here
}
});
}
});
});
success: function(image) {
script = document.createElement('canvas');
var can = document.body.appendChild(script);
If i change code in two line , i can show all image but i can control it load form 1 to 13. Any body can help me fix it ... thanks
Here is a code which will draw images on one canvas one under another.
var url = "http://farm4.static.flickr.com/",
urls = [
"3002/2758349058_ab6dc9cfdc_z.jpg",
"2445/5852210343_d21767f18d.jpg"],
can = $('#canvas').get(0),
ctx = can.getContext('2d'),
canH = 0,
canW = 0,
h = 0,
images = [],
size = urls.length;
// loop via all images
$.each(urls, function (index, img) {
$.getImageData({
url: url + img,
success: function (image) {
images.push(image);
canH += image.height;
canW = Math.max(canW, image.width);
if (images.length === size) {
can.width = canW;
can.height = canH;
$.each(images, function (i, img) {
ctx.drawImage(img, 0, h);
h += img.height;
});
}
}
});
});
You can also check this: http://jsfiddle.net/HcxG3/6/ (looks like the service behind getImageData is currently down).

Categories