Multiple images/layers on Canvas - javascript

I have a canvas that I add a background image to from my source in the Html, I then insert images from my local computer and add text to the image, I am able to move/rotate image and text no problem.
I wish to have the ability to move the uploaded image and text to back and to front of the background image, I cannot find a solution, I think it involves Multiple Canvas layers or something of the sort. Please can someone suggest a way to do this?
<div class="well" style="height:350px;">
<a name="1"><center>Sonstiges</center></a>
<div class="cleaner_h3"></div>
<img style="cursor:pointer;width:90px;height:120px;" class="img-polaroid" src="img/phones/designs/son01r.png">
<img style="cursor:pointer;width:90px;height:120px;" class="img-polaroid" src="img/phones/designs/son02r.png">
<img style="cursor:pointer;width:90px;height:120px;" class="img-polaroid" src="img/phones/designs/son09.png">
<img style="cursor:pointer;width:90px;height:120px;" class="img-polaroid" src="img/phones/designs/son04p.png">
<img style="cursor:pointer;width:90px;height:120px;" class="img-polaroid" src="img/phones/designs/son05p.png">
</div>
Jquery portion where I add the background image
$(".img-polaroid").click(function(e){
var el = e.target;
var design = $(this).attr("src"); //src is the particular image you click on
$('#tcanvas').css({
'backgroundImage': 'url(' + design +')',
'backgroundRepeat': 'no-repeat',
'backgroundPosition': 'top center',
'background-size': '100% 100%'
});
});
Canvas element
<div id="phoneDiv" class="page" style="width: 800px; height: 800px; position: relative;left:5%; background-color: rgb(255, 255, 255);">
<canvas id="tcanvas" width=800 height="800" class="hover" style="-webkit-user-select: none;"></canvas>
</div>

Problem:
You have an existing image on the canvas and you want to draw another image behind the existing image.
You can use context.globalCompositeOperation="destination-over" to cause subsequent drawing to be drawn "under" the existing content.
What happens is that any existing non-transparent pixels on the canvas will remain and the new image is drawn only into the transparent pixels.
So draw this wall-frame with transparent pixels inside the frame:
context.drawImage(backgroundImage,0,0);
Then set compositing to "destination-over"
(any new drawing will display only where the existing wall-frame is transparent).
context.globalCompositeOperation="destination-over";
Then draw a second image:
The city will be "drawn behind" the existing image (thanks to compositing):
context.drawImage(cityImage,0,0);

Related

How to make different aspect ration images into same width and height without getting cropped?

I have multiple div with class called card. I need my all div to be same height and same width. I want to add images to those div. I have different images with different aspect ratios. Also I want whole image filled inside the div. (I want to prevent from cropped images). Therefore, If I can convert all images into same aspect ratio first, then it should be okay. Then I can set .card-img {width=100%}. Height should be same for all images because .card has same width and all images have same aspect ratio. How can I make this work as I mentioned?
<div class="card">
<img class="card-img" src="img-1.jpg" alt="" />
</div>
<div class="card">
<img class="card-img" src="img-2.jpg" alt="" />
</div>
<div class="card">
<img class="card-img" src="img-3.jpg" alt="" />
</div>
.card{
width: 270px
height: 400px;
}
Assume img-1.jpg, img-2.jpg, img-3.jpg has different aspect ratios.
You can't force an image to have a different aspect ratio from its natural one without either cropping or distorting it. You say you don't want to crop so that is not a possibility and you would be unlikely to want to distort it (stretch it in one direction or the other).
What you can do is make sure that the whole image is always visible is use contain instead of cover.
Obviously this means there will be space either at the top and bottom or at the sides of your cards in some cases but this is an inevitable consequence of the no-cropping requirement.
I have faced the same problem many a times. Unfortunately the only options we have available when height and width are fixed are:
Use object-fit: cover on the img element. This results in some cropping.
Use object-fit: contain on the img element. This ensures there is no cropping but adds whitespace around the image.
If you are okay with differing height and width, then you have the option to use a masonry layout as described here:
https://masonry.desandro.com/layout.html
Easy, just set max width and max height to 100% and let the browser sort it out.
.card {
width: 270px;
height: 400px;
border: 1px solid #333;
}
.card img {
max-width: 100%;
max-height: 100%;
}
<div class="card">
<img class="card-img" src="https://picsum.photos/370/400" alt="" />
</div>
<div class="card">
<img class="card-img" src="https://picsum.photos/400/100" alt="" />
</div>
<div class="card">
<img class="card-img" src="https://picsum.photos/400" alt="" />
</div>
This is in case you want the image element. If you want the image as a background, use the contain property.
UPDATE
If you want the images to fill the cells, use
.card img {
width: 100%;
height: 100%;
}
But this will stretch the image. These are the two options you have without cropping.

Transparent image always on top of Canvas. Draw behind transparent image

Here is my jsfiddle:
Im looking for 2 things:
i always want the transparent image: "https://s23.postimg.org/c3u19aeqz/bmap_Front.gif" to be on top of the drawing/canvas. Lets call it layer foreground (lfg). This image should never be overpainted.
When i save my drawing as image. I only want to save the "drawings" that were drawn underneath the image. This means saving everything except the transparent image.
I tried "playing" with:
ctx.globalCompositeOperation = "source-over";
ctx.globalCompositeOperation = "destination-over";
and
<div id="LayerTown" class="containerChild" style="position: relative;">
<canvas id="canvas" style="position: absolute; left: 0; top: 0; z-index: 0;">
Update your browser
</canvas>
<img src='https://s23.postimg.org/c3u19aeqz/bmap_Front.gif' style="position: absolute; left: 0; top: 0; z-index: 1;">
</div>
So far nothing has helped me. Since im very new to html/css/js please consider alterating my fiddle if you want to help me, because i have a hard time understanding what i should do, if its just a command line.
Doing what you said in the OP, adding a image element on top of the canvas is the way to go. By adding the CSS rule "pointer-events:none" you will be able to right click the canvas through the image and saving only what's on the canvas.
<div id="LayerTown" class="containerChild" style="position: relative;">
<canvas id="canvas" style="position: absolute;">
Update your browser
</canvas>
<img src='https://s23.postimg.org/c3u19aeqz/bmap_Front.gif' style="position: absolute; pointer-events: none;">
</div>
You will also have to remove the addImg2Canvas() function from the script as we no longer want to draw the image on the canvas.

How to align text and buttons next to canvas (WebGL + JavaScript + CSS)

I have a webpage with a canvas for implementing graphics rendering, and would like to align some text and buttons to the left of it. My HTML code is as follows:
<body onload="webGLStart();">
<canvas id="canvas" style="border: none;" width="800" height="450" align="center"></canvas>
<div class="controls">
<h2>Controls</h2>
<button class="btn" onclick="initBuffers(1)">Man</button>
<br><br>Use the mouse to rotate the view.
</div>
</body>
So what I want to align to the left is everything in the 'controls' class. Currently it is being displayed below the canvas on a new line. I want it to be aligned to the left starting on the same line as the canvas, with the canvas remaining centered.
I am using a stylesheet and would like to know how to implement this using css.
My site can be seen here. It is the Controls section I want to move up towards the top of the page.
Any help would be much appreciated, thank you.
I would suggest you wrap it all in a wrapper div which is centered and has position relative. Then you can position the controls absolute like this:
<div class="wrapper" style="margin: 0 auto; width: 800px; position: relative;">
<canvas id="canvas" style="border: none;" width="800" height="450" align="center"></canvas>
<div class="controls" style="position: absolute; top:0; left:0;">
<h2>Controls</h2>
<button class="btn" onclick="initBuffers(1)">Man</button>
<br><br>Use the mouse to rotate the view.
</div>
</div>
Here is a makeshift answer. I would use bootstrap for positioning though.
You can use bootstrap.
JSFiddle
is that what you are looking for? use col-sm-{x/12} to size and resize your positions.

HTML/Javascript Overlaying Images on Region Mouseovers

So I have an image on a page and an imagemap corresponding to that image, then I also have two corresponding images, each the same size as the first (mostly transparent) that I want to overlay onto that image when a certain region of the imagemap is moused over. How would I go about doing that, is this something I can accomplish with CSS or will I need javascript for it?
I think you do need Javascript as not all browsers support css hover psuedo-class on elements other than <a>. You should be able to do it with minimal Javascript. See the <map> tag: http://www.w3schools.com/tags/tag_map.asp
For example, if you want mousing over the 100 by 100 pixel square in the top left of your image (image1.png) to enable the overlay image (image2.png):
<script type="text/javascript">
function area1_mouseover() {
document.getElementById('image2').style.visibility = 'visible';
}
function area1_mouseout() {
document.getElementById('image2').style.visibility = 'hidden';
}
</script>
<img src="image2.png" id="image2" style="position: absolute; visibility: hidden; z-index: 2;" usemap="#my_map" />
<img src="image1.png" id="image1" usemap="#my_map" />
<map name="my_map">
<area shape="rect" coords="0,0,100,100" onmouseover="area1_mouseover();" onmouseout="area1_mouseout();" />
</map>
Edit: applying the map to all the images should solve that problem since they are all the same size.

How to overlay data on an image

I am a rookie web developer and I am looking to put data points over an image that can be interacted with when hovered over, similar to most common map applications.
From my current understanding, using the Canvas in Javascript seems to be the best way to go, does anyone have any recommendations on how to do this and maybe point me in the right direction?
Does not require canvas although canvas can be used.
Shortest coding would be make a div with a background image being the image you want to place points on.
If it is not an image then you would need to make two divides on the overlay divide (the first one in the HTML code) use position:absolute to place it on top with the same width and height -- then the image content divide that follows will be layered under your absolute positioned divide.
<div style="background:url(image.jpg); width:100px; height:100px">
... material here is on top of the image ...
</div>
or
<div style="position:absolute; width:100px; height:100px">
... material here is on top of the image ...
</div>
<div style="width:100px; height:100px">
... place object here which picks up your map or whatever ...
</div>
The ... material here is on top of the image ... can be a canvas but SVG would be less coding as it has links supported
<div style="background:url(image.jpg); width:100px; height:100px">
<object data="yourOverlay.svg" width="100" height="100" >
</object>
</div>
Here is a sample SVG file posted at http://tutorials.jenkov.com/svg/a-element.html
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<a xlink:href="/svg/index.html">
<text x="10" y="20">/svg/index.html</text>
</a>
<a xlink:href="/svg/index.html" xlink:show="new">
<text x="10" y="40">/svg/index.html
(xlink:show="new")</text>
</a>
<a xlink:href="/svg/index.html" xlink:show="replace">
<text x="10" y="60">/svg/index.html
(xlink:show="replace")</text>
</a>
<a xlink:href="/svg/index.html" target="_blank">
<text x="10" y="80">m/svg/index.html
(target="_blank")</text>
</a>
<a xlink:href="/svg/index.html" target="_top">
<text x="10" y="100">/svg/index.html
(target="_top")</text>
</a>
</svg>
Depending on your application you may want to consider straight HTML for "... material here is on top of the image ..." so it will work in older browsers.
And FYI you could code the background into the SVG and just have a object tag in the html page and use googles "SVGWEB" http://code.google.com/p/svgweb/ to support nearly every browser.
Good resource here: http://dev.opera.com/articles/view/html5-canvas-painting/
But for what you're doing, you don't really need a canvas, imo. If you have an image, and you know where stuff is that you want to overlay (pixel offset), you can provide the pixel offsets from each data point in JSON or XML to your client script, and then just have it use absolute positioning to place them where they need to be on the image.
Another possible solution is to just use an SVG image which i believe supports links ect directly

Categories