How draw lines between and fill on 4 points on an ASP.NET page? - html

Using GPS, I will know the latitude/longitude for 4 corners of a lot of land (I suppose it could be 5 or 6 so a polygon -- although will usually be a rectangle or parallelogram). Using DIV tags (with runat=server), I can mark the dots on an ASP.NET page pulling the data points from a database.
But, is there a way I can essentially turn these into shapes? I'm trying to map out a, for example, subdivision of plats on a web page. Ultimately, I'd like data to appear on mouseover, have unsold plats a different color, click on a plat and it navigates somewhere, etc).
But right now, I'm just trying to see if I can plot the shapes on a page.
Thanks very much for any guidance.

If you can count on your users having a modern browser, html5 <canvas> is probably what you want. You can just put a canvas on your page with
<canvas id="myCanvas" width="200" height="100"></canvas>
Then draw to it in javascript like so:
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.fillStyle = '#f00';
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo(0, 100);
ctx.lineTo(50, 100);
ctx.lineTo(50, 0);
ctx.closePath();
ctx.fill();
Adjust or add corners as needed.

Related

Building an web based image annotation tool - saving annotations to localStorage

I am building a web application for annotating images. The work flow is as follows:
Select a project - using : action = list all sub-projects
Click on a sub-project : action = fetch all the images within-sub project
Display the images as a horizontal scrollable thumbnail gallery
Onclick image thumbnail from the gallery, display the larger image for annotation.
I am using canvas to display larger image. I have used another canvas as a layer to the first one, and I am able to draw rectangles using mouse over regions of interest. I am saving it locally. However, when I move on to the next image, the rectangle also gets carried to the next image.
My question is, instead of using just one layer, do I have to dynamically create as many canvas layers as I have in the annotation dataset. I am not sure because in each sub project I have around 8000-9000 images. Though I wont be annotating on all of them, still creating as many canvases as layers doesn't really sound good for me.
The following is the code:
HTML Canvas
<div class="body"> <!-- Canvas to display images begins -->
<canvas id="iriscanvas" width=700px height=700px style="position:absolute;margin:50px 0 0 0;z-index:1"></canvas>
<canvas id="regncanvas" onclick="draw(this, event)" width=700px height=700px style="position:absolute;margin:50px 0 0 0;z-index:2"></canvas>
</div> <!-- Canvas to display images ends -->
Step 4 given above: OnClick display thumbnail
function clickedImage(clicked_id) {
var clickedImg = document.getElementById(clicked_id).src;
var clickedImg = clickedImg.replace(/^.*[\\\/]/, '');
localStorage.setItem("clickedImg", clickedImg);
var canvas = document.getElementById("iriscanvas");
var ctx = canvas.getContext("2d");
var thumbNails = document.getElementById("loaded_img_panel");
var pic = new Image();
pic.onload = function() {
ctx.drawImage(pic, 0,0)
}
thumbNails.addEventListener('click', function(event) {
pic.src = event.target.src;
});
}
Draw rectangles on second layer of canvas
window.onload=function(){
c=document.getElementById("regncanvas");
if (c) initCanvas(c);
};
function initCanvas(canvas){
// Load last canvas
loadLastCanvas(canvas);
}
function draw(canvas, event){
// Draw at random place
ctx=c.getContext("2d");
ctx.fillStyle="#ff0000";
ctx.beginPath();
ctx.fillRect (250*Math.random()+1, 220*Math.random()+1, 40, 30);
ctx.closePath();
ctx.fill();
// Save canvas
saveCanvas(canvas);
}
function saveCanvas(c){
localStorage['lastImgURI']=c.toDataURL("image/png");
}
function loadLastCanvas(c){
if (!localStorage['lastImgURI']) return;
img = new Image();
img.onload = function() {
ctx=c.getContext("2d");
ctx.drawImage(img, 0, 0, img.width, img.height);
};
img.src= localStorage['lastImgURI'];
}
Can someone guide me please?
The following is a screen grab of my application:
I have developed OCLAVI which is an image annotation tool with loads of features. It's still in beta but just after 3 weeks of release, it is gaining attraction quickly.
I have few advises for you.
HTML Canvas follow draw and forget strategy and every time redrawing the image is not a good idea. Be it 10 images or 10k, you should have one canvas for drawing the image and one canvas for drawing the shapes. Image canvas need be touched only when the image changes. Different shapes can share the same canvas.
You should integrate a data storage. Local storage is clearly not a good option to store this amount of data (especially if you have a team member who also would be annotating on the same image dataset.)
Isolate the code to a separate-separate file according to the shape. It will be very handy when you will think of adding support for Circle, Polygon, Cuboidal, Point interactions. Trust me following OOPs concepts will relive you from a lot of pain.
In terms of complexity
zooming with coordinates is easy
move with coordinates is of medium level difficulty
but you need to think with pen and paper to implement move on a zoomed image canvas (P.S. take care of the canvas flickering when the image moves
). How much the image can move in each direction also need to be calculated.
Take care of the image to canvas dimension ratio because at the end you need to have the coordinates scaled down to image level.
If your canvas size vs image size ratio is 1:1 then your job is simplified.
But this won't happen always because some images might be very small or very large to directly fit in window screen and you need to scale up and down accordingly.
The complexity increases if you like to use percentage width and height for canvas and your other team member annotating the image has a different screen size. So he drawing something will look something else on your screen.

HTML5 / Canvas "Glass" Circle

I need to render a simple chart and I want the points to be glassy looking circles/orbs in the chart area. I can find tons of examples of drawing these with Photoshop, but I don't want to use stock images; I'd prefer to draw them in my HTML5 canvas. I am no artist, though!
There are many HTML5 canvas questions, but I don't see anything that leads me to this solution.
A point in the right direction would be most appreciated.
All you have to do is create one or more radial gradients to fit the properties of the glassy object that you want. It's easy to do!
Just one gradient:
// Create some gradient
var gradient = ctx.createRadialGradient(105, 105, 20, 120, 120, 50);
gradient.addColorStop(0, 'rgba(250,250,255,0)');
gradient.addColorStop(0.75, 'rgba(230,250,255,1.0)');
gradient.addColorStop(1, 'rgba(0,0,255,0)');
// draw the gradient (note that we dont bother drawing a circle, this is more efficient and less work!)
// but make sure it covers the entire gradient
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, 300, 300);​
Can make this:
Live example:
http://jsfiddle.net/GTbjk/
Maybe you want to reign in that fuzzy edge:
gradient.addColorStop(0.8, 'rgba(0,0,255,0)');
gradient.addColorStop(1, 'rgba(0,0,255,0)');
http://jsfiddle.net/GTbjk/1/
I'm not going to make one to your specification, since you didn't provide one and thats not what we're here for anyway. Making these will almost exclusively be the work of well-placed radial gradients, so go experiment!
As j08691 points out this is a really inefficent way of making these unless you want them to be dynamic or scalable, you are better off just making images and use ctx.drawImage

Is it possible to mask / crop a html element group dynamically?

Is there a way use javascript, css, canvas or svg to create an animated mask (can be just binary).
The closest I've come is using this:
var data = canvas.toDataURL();
$('#masked').css("-webkit-mask-image","url("+data+")");
But this only works in chrome and safari and is a bit buggy.
Is there a way of using css to draw a really simple triangular mask?
If its going to be dynamic you can do it with canvas, draw the path you want and fill it, by default canvas is transparent, so any of the parts not filled will show the element underneath. However if its going to be a static mask I suggest just using a png.
Live Demo
var canvas = document.getElementById("canvas"),
ctx = canvas.getContext("2d");
canvas.width = canvas.height = 200;
// make a path for a triangle
ctx.beginPath();
ctx.moveTo(0,0);
ctx.lineTo(200,0);
ctx.lineTo(200,200);
ctx.lineTo(100,50);
ctx.lineTo(0,200);
ctx.lineTo(0,0);
ctx.fill();

How to draw a circle sector on an html5 canvas?

I'm trying to make a sort of pie-chart shape on a canvas element, however I can't seem to find any function that does this by itself. I only seem to be able to draw full circles and segments. Is there an easy way to do this?
(See also: Wikipedia on circle terminology)
The following should work:
context.moveTo(cx,cy);
context.arc(cx,cy,radius,startangle,endangle);
context.lineTo(cx,cy);
context.stroke(); // or context.fill()
with cx, cy being the center of the arc.

Custom Line stroke in HTML5 canvas

When drawing lines with the HTML5 canvas element, is it possible to define the stroke style of the lines? Basically in Photoshop and other similar programs, you can define a stroke style for lines that looks like it is "hand drawn". Is is possible to do anything like that in HTML5 canvas or am I shooting for the moon here?
Thanks
-Jesse
It is possible but not by default. See ShadowCloud's post for what you can do by default (very little).
Depending on what you want, it shouldn't be too hard.
If by "hand drawn" you mean you want jitter, you'd have to break up every drawn line/curve into smaller parts and add some noise to each of the points.
If you want a brush you'd have to break up every drawn line/curve into smaller parts and call drawImage every few pixels to emulate a photoshop brush.
Almost all of them rely on breaking up your lines and curves into smaller bits, so you should figure that out foremost.
If you decide to implement these and are having trouble breaking up bezier curves and want help, let me know and I'll give you my code for that.
There is no standard API in HTML5 Canvas to manage such thing.
You can just set the color or the width of the stroke, for example:
context.strokeStyle = '#f00'; // red color
context.lineWidth = 4; // 4px wide
// Draw some rectangles.
context.fillRect (0, 0, 100, 100);
context.strokeRect(0, 0, 100, 100);
You can try to get more control using a library (Processing.js or Fabric.js)