I am using RaphaelJS to draw 4 boxes inside a canvas.
var paper = new Raphael(document.getElementById('canvas_container'), 512, 256);
var rectangle = paper.rect(50, 50, 50, 50),
rectangle2 = paper.rect(400, 50, 50, 50);
rectangle3 = paper.rect(50, 200, 50, 50);
rectangle4 = paper.rect(400, 200, 50, 50);
rectangle2.attr("fill", "red");
rectangle3.attr("fill", "green");
rectangle4.attr("fill", "blue");
jsfiddle: http://jsfiddle.net/SFRWj/1/
--
My problem: I want to loop and cut/divide my svg canvas in 4: top left, top right, bottom left, bottom right
Purpose: I want to have 4 separate elements I can then try to convert to png or base64 or just do something with them.
any ideas?
UPDATE 1:
with two for loops and
paper.setViewBox(i*viewStep,j*viewStep,128,128,false);
I got something like this: http://jsfiddle.net/SFRWj/3/
Here is an example with svg.js but you can probably achieve the same with Raphael:
var src = 'http://distilleryimage11.s3.amazonaws.com/89ac2e90d9b111e297bf22000a1f9263_7.jpg'
/* create canvases */
var draw1 = SVG('canvas1').viewbox(0,0,75,75)
var draw2 = SVG('canvas2').viewbox(75,0,75,75)
var draw3 = SVG('canvas3').viewbox(0,75,75,75)
var draw4 = SVG('canvas4').viewbox(75,75,75,75)
/* draw image */
var image = draw1.image(src).size(150,150)
/* clone image to other canvases */
draw2.add(image.clone())
draw3.add(image.clone())
draw4.add(image.clone())
http://jsfiddle.net/wout/rgzG6/
This example basically created four svg canvases, clones the content from the first to the other canvases and sets a viewbox for everyone of them. If you have multiple elements you could consider putting everything in a group before cloning them.
Related
This question already has an answer here:
Is there a way to disable color mixing/overlapping in html canvas
(1 answer)
Closed 7 months ago.
I'm trying to find a way to draw multiple elements onto an HTML canvas, then adjust all of their opacities at once. For example, this codepen example draws two overlapping rectangles with globalAlpha set to 0.5, so they're semi-transparent.
Here's what I see:
Here's what I want to see:
In other words, I want to draw some set of elements, then adjust their alpha/opacity all at once. In the example above, I want the overlapping section of blue & red to appear as just blue, since the blue rectangle was drawn 2nd.
I want this solution to apply to images, shapes, any canvas drawings really.
Does anyone know how to accomplish this using HTML canvas?
you must decompose the process
1- create de canvas with all draw ( alpha 100%)
2 set aside the flattened drawings
3 clear the canvas
4 fetch the picture and add it to the canvas
5 set alpha to 50%
6 add the tmp flattened drawings with alpha
const cnv = document.createElement("canvas");
cnv.width = 300;
cnv.height = 300;
const ctx = cnv.getContext("2d");
document.body.appendChild(cnv);
// Draw red rectangle
ctx.fillStyle = "#f00";
ctx.fillRect(20, 20, cnv.width - 140, cnv.height - 60);
// Draw blue rectangle
ctx.fillStyle = "#00f";
ctx.fillRect(100, 40, cnv.width - 140, cnv.height - 60);
//aside the draw in flatten layer
let tmp = new Image();
tmp.src = cnv.toDataURL();
// clear the canvas
ctx.clearRect(0, 0, cnv.width, cnv.height);
// apply bg
ctx.fillStyle = "#000";
ctx.fillRect(0, 0, cnv.width, cnv.height);
const image = new Image(); // Using optional size for image
image.src = "https://img.photographyblog.com/reviews/kodak_pixpro_fz201/photos/kodak_pixpro_fz201_01.jpg";
image.onload = () => {
// Draw background image
ctx.drawImage(image, 0, 0);
ctx.drawImage(image, 0, 0, cnv.width, cnv.width);
// Set alpha to 0.5
ctx.globalAlpha = 0.5;
//overlay with the tmp flatten img with 50%
ctx.drawImage(tmp, 0, 0, cnv.width, cnv.width);
}
I have a simple rectangle that forms the clipping area for all shapes added to the canvas, which is working great:
var area = new paper.Rectangle(
100, 100, 300, 120
);
var path = new paper.Path.Rectangle(area);
group.addChild(path);
group.clipped = true;
What I'm trying to achieve is instead of hiding the paths that fall outside of this area, they are shown with a slight opacity, something like:
Thanks in advance for any help and suggestions.
This is not a simple way as clipped, you might do it by using method intersect.
Please try this code.
// SET INITIAL
var area = new paper.Path.Rectangle(100, 100, 300, 220);
area.fillColor = 'yellow'
area.opacity = 0.2
var circle1 = new paper.Path.Circle({
center:[150, 150],
radius: 100,
fillColor: 'red'
})
// OPACITY CLIPPING
var circle2 = circle1.intersect(area)
circle1.opacity = 0.2
If a lot of my drawings are going to be within a particular area of my larger canvas (in this case, in the center), is there a way to just say that you're working within that particular 'sub-canvas' instead of having to add/subtract the margins every time you want to draw? It just makes my code look a lot more complicated every time I'm specifying coordinates.
You can change the coordinates' origin using translate().
First, save the original origin using save(). Then, find the origin that suits the centre of your screen's drawing area and call translate(x, y). Do your drawing, and then use restore() to get your previous origin back.
jsFiddle.
Kinetic.js, a popular library for Canvas allows you to create a Group layer. You can specify the x, y coordinates, height and width of this Group. You can also add shapes and draw other things within this group.
Here's and example:
var stage = new Kinetic.Stage({
container: 'container',
width: 578,
height: 200
});
var shapesLayer = new Kinetic.Layer();
/*
* create a group which will be used to combine
* multiple simple shapes. Transforming the group will
* transform all of the simple shapes together as
* one unit
*/
var group = new Kinetic.Group({
x: 220,
y: 40,
rotationDeg: 20
});
var colors = ['red', 'orange', 'yellow'];
for(var n = 0; n < 3; n++) {
// anonymous function to induce scope
(function() {
var i = n;
var box = new Kinetic.Rect({
x: i * 30,
y: i * 18,
width: 100,
height: 50,
name: colors[i],
fill: colors[i],
stroke: 'black',
strokeWidth: 4
});
group.add(box);
})();
}
shapesLayer.add(group);
stage.add(shapesLayer);
Here's a tutorial on how to add Groups
You can use drawimage to draw an offscreen canvas to a certain part of another canvas.
Create a new canvas object and draw all your stuff to that. In the end draw that canvas to your onscreen canvas with drawimage at some coordinates.
I have an upcoming project that I would like to use the HTML5 canvas element to accomplish what would have had to be done in the past with either images and absolutely paced div's or Flash. Here is a basic example of the concept
Here are my concerns:
I am ok with using div's with corner radius to create the circles as they will be styled, and I'm not sure if I can do that with a mix of svg and the canvas element.
My main concern is the stroke that joins the outer circles to the inner, I would like to do this with canvas but am not sure A) How to get multiple canvas elements on one page in one containing element (a wrapper div) and B) how to figure out the starting points, I would assume the ending point would just be the center of the wrapper div (IE if its 600x600 = x=300, y=300)
Can anyone shed some light on this and offer any suggestions? Is there an advantage to using any of the jQuery canvas plugiins over vanilla JS?
thank you!
The canvas API consists of some functions which seem to do the job just fine:
.moveTo/.lineTo for a line path
.arc for a circle path
.stroke to stroke a path (line)
.fill to fill a path (circle)
Here's a very trivial proof of concept: http://jsfiddle.net/eGjak/275/.
I've used (x, y) for both the lines and the circles, which means the lines go from and to the midpoint of two circles. r is the radius of a circle.
var ctx = $('#cv').get(0).getContext('2d');
var circles = [ // smaller circles
{ x: 50, y: 50, r: 25 },
{ x: 250, y: 50, r: 25 },
{ x: 250, y: 250, r: 25 },
{ x: 50, y: 250, r: 25 },
];
var mainCircle = { x: 150, y: 150, r: 50 }; // big circle
function drawCircle(data) {
ctx.beginPath();
ctx.arc(data.x, data.y, data.r, 0, Math.PI * 2); // 0 - 2pi is a full circle
ctx.fill();
}
function drawLine(from, to) {
ctx.beginPath();
ctx.moveTo(from.x, from.y);
ctx.lineTo(to.x, to.y);
ctx.stroke();
}
drawCircle(mainCircle); // draw big circle
$.each(circles, function() { // draw small circles and lines to them
drawCircle(this);
drawLine(mainCircle, this);
});
You could just do all of these circles in CSS. Get some divs, style them as you like in CSS, and then apply border-radius: 100; to the object, and done. I hope this helped.
i am creating a image slider with html5 and jquery what i want to do is add 3 images on top of each other in one canvas and then get pixeldata of first image and remove some of it's pixels to show 2nd image through first i'm using jCanvas
Plug-in To Do This In Jquery What I've Got So Far Is
$(document).ready(function(){
function invert() {
$("canvas").setPixels({
x: 150, y: 150,
width: 100, height: 75,
// loop through each pixel
each: function(px) {
px.r = 255 - px.r;
px.g = 255 - px.g;
px.b = 255 - px.b;
px.a = 255 - px.a;
}
});
}
$("canvas")
.addLayer({
method: "drawImage",
source: "images/01.jpg",
x: 100, y: 100,
width: 480, height: 440
}).addLayer({
method: "drawImage",
source: "images/02.jpg",
x: 100, y: 100,
width: 380, height: 340
}).addLayer({
method: "drawImage",
source: "images/01.jpg",
x: 100, y: 100,
width: 280, height: 240,
load: invert
})
// Draw each layer on the canvas
.drawLayers();
});
Now What it Does Is making A hole In all the Images Means Erase all the Pixels Of That Portion Of all Images and Show the Background of canvas Is It Possible to Get Only Pixels Of Particular image or layer and Invert It is there any jquery plug-in available? any other way to do that? Any Help On this Will Be Very Useful To Me....Thanx In Advance....
Keep in mind that drawing on a canvas is like painting on paper, it doesn't remember what you drew before only what you have in the canvas right now so if you draw one image and then draw over it with another, the old picture is lost forever.
What you should do is keep all three images in three different buffers (simply load the three different images into three different image objects).
Then draw the top most image in the context.
When you wish to dissolve the first image into the second, instead of deleting pixels from the top image (which will only show the the background), simply use the same coordinates you would use to remove pixels from the first image to get the pixel data from the second image (the coordinates for deleting pixel from the top image can be used as indexes to the image data for the second image) and copy those values to the canvas, again using the same coordinates, for example:
If you algorithm leads you to first remove pixel x = 100, y = 175, use those coordinates to get the data from the buffer of the second image and copy that to the same coordinates in the canvas' image data.
Here's some code:
var width = 300;
var height = 300;
var img1 = new Image();
img1.src = "image1.png";
var img2 = new Image();
img2.src = "image2.png";
function go()
{
// Wait for the images to load
if ( !img1.complete || !img2.complete )
{
setTimeout( go, 100 );
return;
}
// Create a temporary canvas to draw the other images in the background
var tc = document.createElement( "canvas" );
tc.width = width;
tc.height = height;
var c2 = tc.getContext( "2d" );
// Draw the first image in the real canvas (change the ID to your canvas ID)
var c = document.getElementById( "myCanvas" ).getContext( "2d" );
c.drawImage( img1, 0, 0 );
var data1 = c.getImageData( 0, 0, width, height ); // Get the data for the first image
// Draw the second image in the temporary canvas (which is hidden) and get its data
c2.drawImage( img2, 0, 0 );
var data2 = c2.getImageData( 0, 0, width, height );
// Copy the data from the hidden image to the visible one
// This is where your magic comes into play, the following
// is just a very very simple example
var pix1 = data1.data;
var pix2 = data2.data;
for ( var x = 0; x < width; x++ )
{
for ( var y = 0; y < height; y++ )
{
var pos = ( ( y * width ) + x ) * 4;
pix1[ pos ] = pix2[ pos++ ];
pix1[ pos ] = pix2[ pos++ ];
pix1[ pos ] = pix2[ pos++ ];
pix1[ pos ] = pix2[ pos ];
}
}
// Redraw the visible canvas with the new data
c.putImageData( data1, 0, 0 );
}
window.onload = go;
The canvas element does not provide the ability to use layers like that. You may need to check add-ons like canvas collage or CanvasStack