Stop Custom Image from rotating - autodesk-forge

We are using forge viewer to display Revit files. We want to display a custom image as background. We tried different options. However, the image is rotating and we don't want the custom image to rotate. Would it be possible to add the custom image using code to the Environment and avoid rotating? We also tried using three.js mesh. It displays the image but the image is rotating. What can we do to avoid the custom image from rotating?
Thank you for your help.
The following is our sample code using Mesh. It displays the image but it rotates.
const imgTexture = THREE.ImageUtils.loadTexture('images/bsd-speclink-logo.jpg')
var transparentMaterial = new THREE.MeshBasicMaterial({
map: imgTexture,
color: 0xffffff,
opacity: 0.1,
transparent: true
})
viewer.impl.matman().addMaterial('transparent',transparentMaterial,true)
var geometry = new THREE.PlaneGeometry(50, 40, 40, 40);
var mesh = new THREE.Mesh(geometry, transparentMaterial)
mesh.position.set(60, -60, 0);
viewer.impl.scene.add(mesh)
viewer.impl.invalidate(true)

See this blog post here to set the canvas transparent so you can slip in a background underneath.
Or try the skybox workaround here to emulate background in the canvas.

Related

Autodesk forge grey colour showing through colour material

I am trying to simply change the colour of a model in autodesk forge. I am using the following code.
Creation of the material
var material = new THREE.MeshPhongMaterial
({
color: new THREE.Color("rgb(255, 0, 0)"),
transparent: false
});
Adding it to the list of materials
materials.addMaterial(
'NewMaterial',
material,
true)
Line of code that actually sets the material
fragList.setMaterial(fragId, material);
This works almost perfectly. The colour of the model changes to red as it should but as you move the view around, what looks like the underlying grey of the model seems to be showing through the red like its clipping through in certain areas.
I have been through https://threejs.org/docs/#api/materials/MeshPhongMaterial and messed with a bunch of properties of the material and while they changed the look of the material especially the lighting properties however nothing would stop the grey clipping through. Any suggestions on what could be causing this or where to look would be appreciated
Not sure if there is a down side to using this method but I used the setThemingColour that was demonstrated in the easter code sample.
https://forge.autodesk.com/blog/happy-easter-setthemingcolor-model-material
var red = new THREE.Vector4(1, 0, 0, 0.5);
viewer.setThemingColor(dbId, red);
Changed the colour, doesnt show through other models like overlays and doesnt have the clipping issue I had.
use this extension from Autodesk forge instead of working on three.js directly.
https://forge.autodesk.com/cloud_and_mobile/2015/12/change-color-of-elements-with-view-and-data-api.html
It is very simple, you just have to write few lines:
viewer.loadExtension('Autodesk.ADN.Viewing.Extension.Color');
viewer.setColorMaterial([objectIds],colorcodes);

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.

Click through transparent canvas element to select element behind it

I am using KineticJS. I have a canvas with draggable, resizable images on it (code was just copied from: http://www.html5canvastutorials.com/labs/html5-canvas-drag-and-drop-resize-and-invert-images/). The draggable, resizable images are on one layer, and I have a rectangle on another layer. The rectangle layer is on top. The rectangle is transparent (no fill).
When I drag the image under the rectangle and again try to click on the image, of course the image does not move - because it's not on top. The rectangle is on top. However I'd like to click "through" the transparent rectangle and keep acting on the image underneath. In other words, when you click and drag I want it to be as if the rectangle is not there, but I want the rectangle to show on top.
Here is a demo:
http://jsfiddle.net/T8m64/106/
Drag the image under the rectangle and you'll see that you can no longer grab it since it's underneath. [I am fully aware this is not "unobtrusive javascript", i.e. the javascript is embedded in the html. Sorry. I just copied it from the first link above.]
Anyway, as I said, the demo is copied from that first link above, with the following code added at the end:
//Overlying rectangle. I'm doing it as a path not a rect, because that's ultimately what I care about
var rect = new Kinetic.Path({
x: 0,
y: 0,
data: 'm 2.0012417,2.0057235 125.7664883,0 0,105.8016465 -125.7664883,0 z',
fill: 'none',
stroke: 'black',
scale: 1
});
// add the shape to the layer
var rectLayer = new Kinetic.Layer();
rectLayer.add(rect);
stage.add(rectLayer);
rectLayer.moveToTop();
Thanks
You can tell a layer to stop listening for events.
This will allow layers underneath to respond to those events.
rectLayer.setListening(false);

How to play gif inside canvas in HTML5

I want to play animated GIF file inside a HTML Canvas. I have used the code below but it is not working.
What is wrong with the code?
var drawingCanvas = document.getElementById('myDrawingCanvas');
if(drawingCanvas.getContext)
{
var context = drawingCanvas.getContext('2d');
var imgObj = new Image();
imgObj.onload = function ()
{
context.drawImage(imgObj, 0, 0, 1024, 600);
}
imgObj.src='HTML Images/Spell Bee/images/mainscreen.gif';
}
You cannot as canvas doesn't provide any methods to deal with animated gifs. You should split gif into single frames then create a spritesheet and animate it copying current frame.
You can actually decode the GIF with JavaScript and write the frames to canvas. Check http://slbkbs.org/jsgif/
I found an article that answers your question. Basically, when you add an animated gif to a canvas element it displays the exact state the image is at when it's included. So, as rezoner says, you need to create a spritesheet and animate it using javascript.

Drag div element with canvas to another

I'm having my first experience in developing html5 applications. My issue is to make room plan. In the top of the page I have elements to drag to the bottom map area (they are copied). In the map area I can move elements, but not copy.
I've built drag'n'drop with help of image elements. But now I want to use canvas for updating numbers on images. I want to use canvas text functions for updating images.
The problem is when I copy canvas element from the top, html inserts well, but it is not drawn in some reasons.
Please, watch code here http://jsfiddle.net/InsideZ/MuGnv/2/. Code was written for Google Chrome.
EDIT:
I made a few small tweaks here: http://jsfiddle.net/MuGnv/5/
Note the changes made to the drawImg function:
function drawImg(src, targetClass) {
$(targetClass).each(function() {
var ctx = $(this).get(0).getContext('2d');
var img = new Image();
img.src = src;
img.onload = function() {
ctx.drawImage(img, 0, 0);
};
});
}
Anytime a drop event is handled, the images are drawn again. This was the missing component as the image was only being drawn once.