Javascript canvas draw from array - javascript

I am currently creating a family tree and have run into some problems when creating the children nodes coming from the father node. At the moment I am drawing topPerson.draw(context); which = the father node and then calling a for loop to cycle through an array of children they have which exists in the Partnership.js file, the array is this.mChildren = new Array();
What I am trying to do is cycle through the array and draw each child underneath the parent node in the same style as the parent (bordered with rectangle, image centered and name underneath).
The Person.js which is used to set the origin of canvas to center, draw a rectangle, write text including name of the node and then add node image:
Person.prototype.draw = function (context) {
//draw rectangle
var c = document.getElementById("canvas");
var context = c.getContext("2d");
context.scale(1, 1);
context.rect(canvas.width * 0.5, canvas.height * 0.5,160,210);
context.fillStyle = '#FFFFFF';
context.fill();
context.stroke();
context.fillStyle = '#000000';
context.font = "30px Arial";
context.fillText(this.getName(), canvas.width * 0.5 + 15, canvas.height * 0.5 + 190);
//get image and draw
context.drawImage(this.getImage(), canvas.width * 0.5 + 5, canvas.height * 0.5 + 5);
I have tried to create an array that looks like this:
for (i = 0; < mChildren.length; i++){
img = new Image();
img.src = mChildren[i];
img.onLoad = (function(img, i){
return function () {
context.drawImage(img, i*img.width, i*img.height);
}
})(img, i)
}

Related

Rotate canvas image to anticlockwise in the same canvas

Say we have a canvas:
<canvas id="one" width="100" height="200"></canvas>
var canvas = document.getElementById("one");
var context = canvas.getContext("2d");
var cw = canvas.width;
var ch = canvas.height;
// Sample graphic
context.beginPath();
context.rect(10, 10, 20, 50);
context.fillStyle = 'yellow';
context.fill();
context.lineWidth = 7;
context.strokeStyle = 'black';
context.stroke();
// create button
var button = document.getElementById("rotate");
button.onclick = function () {
// rotate the canvas 90 degrees each time the button is pressed
rotate();
}
var myImageData, rotating = false;
var rotate = function () {
if (!rotating) {
rotating = true;
// store current data to an image
myImageData = new Image();
myImageData.src = canvas.toDataURL();
myImageData.onload = function () {
// reset the canvas with new dimensions
canvas.width = ch;
canvas.height = cw;
cw = canvas.width;
ch = canvas.height;
context.save();
// translate and rotate
context.translate(cw, ch / cw);
context.rotate(Math.PI / 2);
// draw the previows image, now rotated
context.drawImage(myImageData, 0, 0);
context.restore();
// clear the temporary image
myImageData = null;
rotating = false;
}
}
}
And on a button click the canvas gets rotated -90 degrees anticlockwise (around the centre) and the dimensions of the canvas get also updated, so in a sense, it looks like this afterwards:
I want to rotate a canvas element to the anticlockwise rotation. I have used this code but it's not working as I want.
JavaScript has a built-in rotate() function for canvas context:
context.rotate( angle * Math.PI / 180);
The problem is that the rotation will only affect drawings made AFTER the rotation is done, which means you will need to:
Clear the canvas first: context.clearRect(0, 0, canvas.width, canvas.height);
Rotate the context context.rotate( 270 * Math.PI / 180);
Redraw the graphics
Thus, I recommend wrapping the graphics we want to draw in a function to make it easier to call after every rotation:
function drawGraphics() {
context.beginPath();
context.rect(10, 10, 20, 50);
context.fillStyle = 'yellow';
context.fill();
context.lineWidth = 7;
context.strokeStyle = 'black';
context.stroke();
}

Blur behind transparent box in JavaScript canvas

How can I achieve a blur behind a transparent box (fillStyle = 'rgba(255, 255, 255, 0.2)') in JavaScript canvas? Here's what I've got so far:
var canvas = document.getElementById('draw');
var c = canvas.getContext('2d');
function main() {
c.fillStyle = '#222';
c.fillRect(0, 0, canvas.width, canvas.height);
c.fillStyle = '#000';
c.fillRect(32, 32, 64, 64);
c.fillStyle = 'rgba(255, 255, 255, 0.2)';
c.filter = 'blur(5px)';
c.fillRect(16, 16, 128, 24);
}
But what happens, is instead of blurring the background behind the rectangle, is the rectangle itself is blurred, kind of obviously.
In the final script, I will probably use paths instead of rects.
Context2D filters will be applied only on your new drawings, so to also blur the background, you would actually have to redraw the part of the background you want to be blurred.
Fortunately, canvas can drawImage itself.
var blurredRect = {
x: 80,
y: 80,
height: 200,
width: 200,
spread: 10
};
var ctx = canvas.getContext('2d');
var img = new Image();
img.onload = draw;
img.src = 'https://upload.wikimedia.org/wikipedia/commons/5/55/John_William_Waterhouse_A_Mermaid.jpg';
function draw() {
canvas.width = img.width / 2;
canvas.height = img.height / 2;
// first pass draw everything
ctx.drawImage(img, 0,0, canvas.width, canvas.height);
// next drawings will be blurred
ctx.filter = 'blur('+ blurredRect.spread +'px)';
// draw the canvas over itself, cropping to our required rect
ctx.drawImage(canvas,
blurredRect.x, blurredRect.y, blurredRect.width, blurredRect.height,
blurredRect.x, blurredRect.y, blurredRect.width, blurredRect.height
);
// draw the coloring (white-ish) layer, without blur
ctx.filter = 'none'; // remove filter
ctx.fillStyle = 'rgba(255,255,255,0.2)';
ctx.fillRect(blurredRect.x, blurredRect.y, blurredRect.width, blurredRect.height);
}
<canvas id="canvas"></canvas>
But, canvas blur filter is a bit different than CSS one in that it will make the spreading stay inside the drawn area. This means that in our case, we have a 5px border around our rectangle that is less blurred than the center.
To workaround, we can take the whole thing in a different order and play with globalCompositeOperation property*:
var blurredRect = {
x: 80,
y: 80,
height: 200,
width: 200,
spread: 10
};
var ctx = canvas.getContext('2d');
var img = new Image();
img.onload = draw;
img.src = 'https://upload.wikimedia.org/wikipedia/commons/5/55/John_William_Waterhouse_A_Mermaid.jpg';
function draw() {
var spread = blurredRect.spread,
ratio = 0.5,
// make our blurred rect spreads
x = blurredRect.x - spread,
y = blurredRect.y - spread,
w = blurredRect.width + (spread * 2),
h = blurredRect.height + (spread * 2);
canvas.width = img.width * ratio;
canvas.height = img.height * ratio;
// this time we will first draw the blurred rect
ctx.filter = 'blur('+ spread +'px)';
// this time we draw from the img directly
ctx.drawImage(img,
x / ratio, y / ratio, w / ratio, h / ratio,
x, y, w, h
);
// now we will want to crop the resulting blurred image to the required one, so we get a clear-cut
ctx.filter = 'none'; // remove filter
// with this mode, previous drawings will be kept where new drawings are made
ctx.globalCompositeOperation = 'destination-in';
ctx.fillStyle = '#000'; // make it opaque
ctx.rect(blurredRect.x, blurredRect.y, blurredRect.width, blurredRect.height);
ctx.fill(); // clear-cut done
// reuse our rect to make the white-ish overlay
ctx.fillStyle = 'rgba(255,255,255,0.2)';
// reset gCO to its default
ctx.globalCompositeOperation = 'source-over';
ctx.fill();
// now we will draw behind the our blurred rect
ctx.globalCompositeOperation = 'destination-over';
ctx.drawImage(img, 0,0, canvas.width, canvas.height);
// reset to defaults
ctx.globalCompositeOperation = 'source-over';
}
<canvas id="canvas"></canvas>
But this approach requires that we keep access to the whole background as a drawable thing, in the example above that was just an image, but in real life, this might mean you'd have to do this operation on a second offscreen canvas.
var blurredRect = {
x: 80,
y: 80,
height: 200,
width: 200,
spread: 2
};
var ctx = canvas.getContext('2d');
// create an off-screen canvas
var bCanvas = canvas.cloneNode();
var bCtx = bCanvas.getContext('2d');
var img = new Image();
img.onload = draw;
img.src = 'https://upload.wikimedia.org/wikipedia/commons/5/55/John_William_Waterhouse_A_Mermaid.jpg';
function draw() {
var spread = blurredRect.spread;
canvas.width = bCanvas.width = img.width / 2;
canvas.height = bCanvas.height = img.height / 2;
// now we have a composed background
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
ctx.font = '40px Impact';
ctx.fillStyle = 'white';
ctx.fillText('..SO BLUR ME..', 120, 282);
// make our clear-cut on the offscreen canvas
bCtx.filter = 'blur(' + spread +'px)';
bCtx.drawImage(canvas,
blurredRect.x - spread, blurredRect.y - spread, blurredRect.width + spread * 2, blurredRect.height + spread * 2,
blurredRect.x - spread, blurredRect.y - spread, blurredRect.width + spread * 2, blurredRect.height + spread * 2
);
// clear-cut
bCtx.filter = 'none';
bCtx.globalCompositeOperation = 'destination-in';
bCtx.beginPath();
bCtx.rect(blurredRect.x, blurredRect.y, blurredRect.width, blurredRect.height);
bCtx.fillStyle = '#000';
bCtx.fill();
// white-ish layer
bCtx.globalCompositeOperation = 'source-over';
bCtx.fillStyle = 'rgba(255,255,255,0.2)';
bCtx.fillRect(blurredRect.x, blurredRect.y, blurredRect.width, blurredRect.height);
// now just redraw on the visible canvas
ctx.drawImage(bCanvas, 0,0);
}
<canvas id="canvas"></canvas>
*One may say that instead of an offscreen canvas and gCO we could have used ctx.clip(), but since you said it might a more complex Path than a rect, I will not advise to do so. Indeed, while it would require less code, and maybe use less memory, clipping is just bad with antialiasing, and since you are doing blurring, that will just look plain ugly.

rotate one of the 2 canvas objects placed in canvas

I'm developing web app using canvas and I made three. canvas, canvas_panorama and canvas_image.
First one is something like main canvas, conteiner for the others. canvas_panorama is a background for canvas_image.
After canvas is right clicked, I'm computing angle to rotate canvas_image:
function getAngle( e, pw /*canvas*/ ){
var offset = pw.offset();
var center_x = (offset.left) + ($(pw).width() / 2);
var center_y = (offset.top) + ($(pw).height() / 2);
var mouse_x = e.pageX;
var mouse_y = e.pageY;
var radians = Math.atan2(mouse_x - center_x, mouse_y - center_y);
angle = radians;
}
After I have an angle I'm trying to rotate canvas_image like this:
function redraw(){
var p1 = ctx.transformedPoint(0,0);
var p2 = ctx.transformedPoint(canvas.width,canvas.height);
ctx.clearRect( p1.x, p1.y, p2.x-p1.x, p2.y-p1.y );
canvas_image_ctx.drawImage(image_img, 0, 0, 150, 150);
canvas_panorama_ctx.drawImage(panorama_img, 0, 0, 600, 300);
canvas_panorama_ctx.drawImage(canvas_image, 20, 20);
// rotate panorama_img around its center
// x = x + 0.5 * width
// y = y + 0.5 * height
canvas_panorama_ctx.translate(95, 95);
canvas_panorama_ctx.rotate(angle);
// translate to back
canvas_panorama_ctx.translate(-95, -95);
ctx.drawImage(canvas_panorama, 0, 0);
}
But this rotates both canvas_image and canvas_panorama. It should only rotate canvas_image
JSFiddle to show you my problem
I think you are confusing yourself with this idea of multiple canvases.
Once in the drawImage() method, every of your canvases are just images, and could be just one or even just plain shapes.
Transformation methods do apply to the canvas' context's matrix, and will have effect only if you do some drawing operations when they are set.
Note : To reset your context matrix, you can either use save(); and restore() methods which will also save all other properties of your context, so if you only need to reset the transform, then it's preferred to simply reset the transformation matrix to its default : ctx.setTransform(1,0,0,1,0,0).
Here is a simplified example to make things clearer :
var ctx = canvas.getContext('2d');
// a single shape, with the border of the context matrix
var drawRect = function(){
ctx.beginPath();
ctx.rect(10, 10, 50, 20);
ctx.fill();
ctx.stroke();
ctx.beginPath();
ctx.rect(0, 0, canvas.width, canvas.height);
ctx.stroke();
};
// set the color of our shapes
var gradient = ctx.createLinearGradient(0,0,70,0);
gradient.addColorStop(0,"green");
gradient.addColorStop(1,"yellow");
ctx.fillStyle = gradient;
// here comes the actual drawings
//we don't have modified the transform matrix yet
ctx.strokeStyle = "green";
drawRect();
// here we translate of 100px then we do rotate the context of 45deg
ctx.translate(100, 0)
ctx.rotate(Math.PI/4)
ctx.strokeStyle = "red";
drawRect();
// reset the matrix
ctx.setTransform(1,0,0,1,0,0);
// here we move of 150px to the right and 25px to the bottom
ctx.translate(150, 25)
ctx.strokeStyle = "blue";
drawRect();
// reset the matrix
ctx.setTransform(1,0,0,1,0,0);
<canvas id="canvas" width="500" height="200"></canvas>
In your code, you are setting the transformations on the canvas that does represent your image, and you do draw every of your canvases at each call.
What you want instead, is to set the transformation on the main canvas only, and draw the non-transformed image :
var main_ctx = canvas.getContext('2d');
var img_canvas = canvas.cloneNode();
var bg_canvas = canvas.cloneNode();
var angle = 0;
// draw on the main canvas, and only on the main canvas
var drawToMain = function(){
// first clear the canvas
main_ctx.clearRect(0,0,canvas.width, canvas.height);
// draw the background image
main_ctx.drawImage(bg_canvas, 0,0);
// do the transforms
main_ctx.translate(img_canvas.width/2, img_canvas.height/2);
main_ctx.rotate(angle);
main_ctx.translate(-img_canvas.width/2, -img_canvas.height/2);
// draw the img with the transforms applied
main_ctx.drawImage(img_canvas, 0,0);
// reset the transforms
main_ctx.setTransform(1,0,0,1,0,0);
};
// I changed the event to a simple onclick
canvas.onclick = function(e){
e.preventDefault();
angle+=Math.PI/8;
drawToMain();
}
// a dirty image loader
var init = function(){
var img = (this.src.indexOf('lena')>0);
var this_canvas = img ? img_canvas : bg_canvas;
this_canvas.width = this.width;
this_canvas.height = this.height;
this_canvas.getContext('2d').drawImage(this, 0,0);
if(!--toLoad){
drawToMain();
}
};
var toLoad = 2;
var img = new Image();
img.onload = init;
img.src = "http://pgmagick.readthedocs.org/en/latest/_images/lena_scale.jpg";
var bg = new Image();
bg.onload = init;
bg.src = 'http://www.fnordware.com/superpng/pnggradHDrgba.png';
<canvas id="canvas" width="500" height="300"></canvas>

How do I get the image data on specific objects?

In a canvas I created a 2d context. In that context... with a function... I'm able to create some 'circle objects'. Now, what I want, is to get the ImageData of a single circle object instead of the image data of the whole context.
In the code below, you can see my wish commented out.
var c = document.getElementById('canvas');
var ctx = c.getContext('2d');
var circle = function (X,Y) {
var that = this;
that.X = X;
that.Y = Y;
that.clicked = function(e) {
//
//
//!!!!!!!!!!!!!!
// Code below works fine, on context level
imgData = ctx.getImageData(e.pageX, e.pageY, 1, 1);
//
// Code below is at the level of the circle, that's what I want, but isn't working
imgData = that.getImageData(e.pageX, e.pageY, 1, 1);
//!!!!!!!!!!!!!!
//
//
alert(imgData.data[3]);
}
that.draw = function () {
ctx.save();
ctx.translate(that.X, that.Y);
ctx.fillStyle = '#33cc33';
ctx.beginPath();
ctx.arc(0, 0, 50, 0, 2 * Math.PI);
ctx.fill();
ctx.stroke();
ctx.restore();
}
}
var circles = new Array();
circles.push(new circle(50,50));
document.addEventListener('click',function() {
circles.forEach(function(circ,index){
circ.clicked();
});
})
So, how do I get the image data on specific objects?
edit:
I understand that I need to draw the circle first, I do that later in my code, but what if I've got a background rect in the context, when I click next to the circle, it will get the imageData of the background rect, when I want to return the 0 value of the alpha rgba.
To this you need to log all your drawings as a "shadow canvas". The most common way is to create shape objects and store them in for example an array:
Draw the shape on canvas
Log its type, position, dimension, colors and orientation and store as an object and push that object to the array
When you need to get an isolated shape or object as an image:
Get mouse position (if you want to click on the object to select it)
Iterate the array of objects to see which object is "hit"
Create a temporary canvas of the dimension of that shape
Draw in the shape into the temporary canvas
Extract the data as an image (ctx.getImageData(x, y, w, h) or canvas.toDataURL())
When you need to resize your canvas you simply iterate all the objects and redraw them. You can even serialize your data for storage using this method.
An example of an object can be:
function Rectangle(x, y, w, h, fill, stroke) {
this.x = x;
this.y = y;
this.width = w;
this.height = h;
this.fill = fill;
this.stroke = stroke;
}
You can extend this object to render it self to canvas as well as giving you a bitmap of itself isolated from the other shapes. Add this to the above code:
Rectangle.prototype.render = function(ctx) {
if (this.fill) { /// fill only if fill is defined
ctx.fillStyle = this.fill;
ctx.fillRect(this.x, this.y, this.width, this.height);
}
if (this.stroke) { /// stroke only if stroke is defined
ctx.strokeStyle = this.stroke;
ctx.strokeRect(this.x, this.y, this.width, this.height);
}
}
Rectangle.prototype.toBitmap = function() {
var tcanvas = document.createElement('canvas'), /// create temp canvas
tctx = tcanvas.getContext('2d'); /// temp context
tcanvas.width = this.width; /// set width = shape width
tcanvas.height = this.height;
tctx.translate(-this.x, -this.y); /// make sure shape is drawn at origin
this.render(tcxt); /// render itself to temp context
return tcanvas.toDataURL(); /// return image (or use getImageData)
}
You simply draw your shapes, create the object based on the positions etc:
var rect = new Rectangle(x, y, w, h, fillColor, strokeColor);
myShapeArray.push(rect);
When you need to render the shapes:
for(var i = 0, shape; shape = myShapeArray[i++];)
shape.render(ctx);
And when you need to get its bitmap (you retrieved its index in advance with the mouse click):
var image = myShapeArray[index].toBitmap();
And of course: you can make similar objects for circles, lines etc.
Hope this helps!
Remember that Canvas is a bitmap graphics tool. Anything you draw into a single context becomes part and parcel of the same object. You can't get separate image data for each "object" you used to draw on that canvas... it's painted ... flattened ... into those pixel positions for that bitmap as soon as you hit draw().
The only way you could do something like what you are looking for would be to create separate canvas contexts that you overlay on top of each other. This would be better handled by utilizing a library such as KineticJS (http://www.html5canvastutorials.com/kineticjs/html5-canvas-events-tutorials-introduction-with-kineticjs/). The only other option would be to use an object oriented drawing tool such as SVG, (through Raphael.js, for example: http://raphaeljs.com) which does preserve separate objects in the the graphics space.
For reference about getImageData, see http://www.html5canvastutorials.com/advanced/html5-canvas-get-image-data-tutorial/
You can use trigonometry instead of trying to locate your colors with getImageData.
For example, if you have a circle defined like this:
var centerX=150;
var centerY=150;
var radius=20;
var circleColor="red";
Then you can test if any x,y is inside that circle like this:
// returns true if x,y is inside the red circle
isXYinCircle(140,140,centerX,centerY,radius);
function isXYinCircle(x,y,cx,cy,r){
var dx=x-cx;
var dy=y-cy;
return(dx*dx+dy*dy<=r*r);
}
If the x,y is inside that red circle then you know the color at x,y is "red"
If you have multiple overlapping circles you can test each circle in increasing z-index order. The last circle that reports x,y inside will be the color at x,y.
It is because that is not a CanvasGraphicsContext. Try:
that.draw();
imgData = ctx.getImageData(e.pageX, e.pageY, 1, 1);
At first, I create my 2 canvas elements. 1 to display, 1 to calculate the pixeldata.
var c = document.getElementById('canvas');
var c2 = document.getElementById('canvas2');
var ctx = c.getContext('2d');
var ctx2 = c2.getContext('2d');
var width = window.innerWidth,
height = window.innerHeight;
c.width = ctx.width = c2.width = ctx2.width = width;
c.height = ctx.height = c2.height = ctx2.height = height;
Than I make my function to create an image
function Afbeelding(src, X, Y, W, H) {
var that = this;
that.X = X;
that.Y = Y;
that.W = W;
that.H = H;
that.onClick = function () { };
that.image = new Image(that.W, that.H);
that.image.src = src;
that.draw = function (context) {
context = (typeof context != 'undefined') ? context : ctx;
context.save();
context.translate(that.X, that.Y);
context.drawImage(that.image, 0, 0, that.W, that.H);
context.restore();
}
When a document.click event is fired, the next function (inside the Afbeelding function) will be called:
that.clicked = function (e) {
if ((e.pageX > that.X - (that.W / 2) && e.pageX < that.X + (that.W / 2)) && (e.pageY > that.Y - (that.H / 2) && e.pageY < that.Y + (that.H / 2))) {
if (that.isNotTransparent(e)) {
that.onClick();
}
}
}
This function (also inside the Afbeelding function) is used to check the pixel for transparancy.
that.isNotTransparent = function (e) {
var result = false;
ctx2.clearRect(0, 0, width, height);
that.draw(ctx2);
var imgData = ctx2.getImageData(e.pageX, e.pageY, 1, 1);
ctx2.clearRect(0, 0, width, height);
if (imgData.data[3] > 0) {
result = true;
}
return result;
}
}
And all below is to lauch the things up above.
var items = new Array();
var afb = new Afbeelding();
afb.draw();
afb.onClick = function () {
alert('clicked');
}
items.push(afb);
document.addEventListener('mousedown', function (e) {
items.forEach(function (item, index) {
item.clicked(e);
});
});

blend two images on a javascript canvas

How do you blend two arrays of pixel data to create one image? with the option of using different blending modes?
Pixastic is a special framework for advanced use of canvas, here are blending examples: http://www.pixastic.com/lib/docs/actions/blend/
If you would like do this alone, you can extract pixel data from 2 images, blend it with a mathematical equation, and put into a canvas. Here is information how to get and put pixel data from/to canvas:
http://ajaxian.com/archives/canvas-image-data-optimization-tip
Update:
Simple example with alpha blending of 2 images in proportion 50-50.
(Images borrowed from http://www.pixastic.com/sample/Butterfly.jpg and http://www.pixastic.com/sample/Flower.jpg )
<img src="Butterfly.jpg" id="img1">
<img src="Flower.jpg" id="img2">
<p>Blended image<br><canvas id="canvas"></canvas></p>
<script>
window.onload = function () {
var img1 = document.getElementById('img1');
var img2 = document.getElementById('img2');
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var width = img1.width;
var height = img1.height;
canvas.width = width;
canvas.height = height;
var pixels = 4 * width * height;
context.drawImage(img1, 0, 0);
var image1 = context.getImageData(0, 0, width, height);
var imageData1 = image1.data;
context.drawImage(img2, 0, 0);
var image2 = context.getImageData(0, 0, width, height);
var imageData2 = image2.data;
while (pixels--) {
imageData1[pixels] = imageData1[pixels] * 0.5 + imageData2[pixels] * 0.5;
}
image1.data = imageData1;
context.putImageData(image1, 0, 0);
};
</script>
I have created a separate, lightweight, open-source library for perform Photoshop-style blend modes from one HTML Canvas context to another: context-blender. Here's the sample usage:
// Might be an 'offscreen' canvas
var over = someCanvas.getContext('2d');
var under = anotherCanvas.getContext('2d');
over.blendOnto( under, 'screen', {destX:30,destY:15} );
See the README for more information.
I am tasked with recreating this java applet using JavaScript (must be tablet friendly, and work in all modern browsers > IE8).
I am creating images using: var image1 = new Image(); and then setting source: img.src = "some path";
So, from pepkin88 I see that the following function will blend two images by combining their pixel array data, overriding previous data from the first image with the new blended data, and finally putting the new data on the canvas resulting in a blended image:
window.onload = function () {
var img1 = document.getElementById('img1');
var img2 = document.getElementById('img2');
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var width = img1.width;
var height = img1.height;
canvas.width = width;
canvas.height = height;
var pixels = 4 * width * height;
context.drawImage(img1, 0, 0);
var image1 = context.getImageData(0, 0, width, height);
var imageData1 = image1.data;
context.drawImage(img2, 0, 0);
var image2 = context.getImageData(0, 0, width, height);
var imageData2 = image2.data;
while (pixels--) {
imageData1[pixels] = imageData1[pixels] * 0.5 + imageData2[pixels] * 0.5;
}
image1.data = imageData1;
context.putImageData(image1, 0, 0); };
HOWEVER, if you viewed the java applet that I'm responsible for recreating, you see that blending happens in real-time continuously as you drag the image around with the pointer the images are constantly blending based on their overlapped regions..
SO, I'm looking to modify the code to account for this, and I continually have the x, y, positions of images drawn (based on top left corner), and the w, h of all images stays static:
the following snippets don't include everything I'm doing, just what I sense is important for you to know
//Rectangle Class from Java converted to JS
function Rectangle(x, y, width, height, src) {
this.x = x;
this.y = y;
this.w = width;
this.h = height;
this.img = new Image();
this.img.src = src;
}
//Stores instance in rect array
rect[0] = new Rectangle(1, (height - 111)/2, 150, 105, "images/mMain.png");
//Draw method that's called
Rectangle.prototype.draw = function(ctx) {
//this.checkBound();
ctx.drawImage(this.img, this.x, this.y, this.w, this.h);
prepareMix(this.img, this.x, this.y, this.w, this.h);
}
So, I'm working on a prepareMix function that receives image info and uses it to get and store image data:
function prepareMix(src, x, y, w, h) {
pixels = 4 * w * h;
var image = mtx.getImageData(x, y, w, h);
var imgData = image.data;
}
Made a list of what to do:
Sense the overlapping
Get and Store the overlapping image data
Mix the overlapping region data arrays
Replace the overlapping image data with the blended data
Put the new data on the canvas
1. Sense the Overlapping:
Plan: Store image positions and compare positions data to know whether or not overlapping is occurring.
IF overlapping is TRUE, which two images is it true for? Distinguish these images that're overlapping from other images so that methods can be called on them.
js, css, html, and images in zip here BOX

Categories