Why Does Text Markup Size Varies Based on Zoom? - autodesk-forge

When loading text markups from a database, the text markups show up in a different size based on the current zoom of the viewer. How do I make text markups show at a static size regardless of zoom?
function saveFreeformMarkup(markup){
let markupObject = {
x: markup.position.x,
y: markup.position.y,
width: markup.size.x,
height:markup.size.y,
type: TEXT_MARKUP_TYPE,
text: $(`#freeText`).val(),
urn_id: urn[`id`],
active: ACTIVE
};
$.ajax({
... send markupObject to database ...
});
}
function loadSingleMarkup(markup, markupTool){
let MarkupsCore = Autodesk.Viewing.Extensions.Markups.Core;
let text = new MarkupsCore.MarkupText(markup.id + ID_INCREMENT, markupTool, markup.text);
markupTool.addMarkup(text);
text.setSize({ x: markup.x, y: markup.y}, markup.width, markup.height);
text.setText(markup.text);
text.updateStyle(true);
}

This is because there's an handler attached to the camera change event that adjusts the viewbox of the SVG per the updated bounds of the current view when navigation (scaling/panning) occurs.
To overcome this you can piggyback the onCameraChange handler of the MarkupCore extension (be sure to do this prior to the event binding to the upper chain that is before entering the edit mode) and apply scaling to the SVG based on the current camera pivot values and the ones recorded when you added the markups:
MarkupsCore.originalOnCameraChange = MarkupsCore.onCameraChange;
MarkupsCore.onCameraChange = function(event){
let scaleString = calculateScale(originalPivot, viewer.autocam.pivot);
this.svg.setAttribute('transform', scaleString);
this.originalOnCameraChange(event)
}
See here for details on SVG transform.
Will leave it up to you to implement the calculations or even a better approach to transform the markups in response to navigation.

I was able to fix the issue by changing the loadSingleMarkup() function to the following
const FONT_SIZE_SCALE = 90;
function loadSingleMarkup(markup, markupTool){
let MarkupsCore = Autodesk.Viewing.Extensions.Markups.Core;
let text = new MarkupsCore.MarkupText(markup.id + ID_INCREMENT, markupTool, markup.text);
markupTool.addMarkup(text);
text.setSize({ x: markup.x, y: markup.y}, markup.width, markup.height);
text.setText(markup.text);
text.style[`font-size`] = 12 / FONT_SIZE_SCALE;
text.updateStyle(true);
}
(adding text.style[`font-size`] = 12 / FONT_SIZE_SCALE;)

Related

is there possible for set rotation and scale to raster static image source in open layer 6

I am using open layers 6 lib for map rendering and events.
my application needed same like this example http://viglino.github.io/ol-ext/examples/layer/map.geoimage.html i.e. Example have ol.source.GeoImage..
I have tried
I am displaying raster images on map using this sample code is
const url = imagurl;
const extent = [0, 0, imageData.width, imageData.height];
const projection = new Projection({
code: 'xkcd-image',
units: 'pixels',
extent,
});
const imageLayer = new ImageLayer({
source: new Static({
url,
projection,
imageExtent: extent,
}),
});
and i am using affine transformation lib and returns scaling, rotation and transformation..
its giving the values
scaling : 327.805670381418,327.805670381418
rotation : -0.1310210334156003
transformation : 7179251.8557908312,6022627.228704552
i need to add this code into ol-6 static image source
source: new ol.source.GeoImage(
{ image,
imageCenter: transformation,
imageScale: scaling,
imageRotate: rotation,
//projection: pixelProjectio
})
suggest or help on this.. thanks in advance.. and save my days..

html2canvas on esri Map - layers moves

I am trying to create a function in the Angular system which will produce an image of the map using html2canvas
The following is the current function:
window.emapComponent.service.getMap('mapApi').then((map) => {
html2canvas(document.getElementById("mapApi"), { useCORS: true }).then(function (canvas) {
canvas.screenshotDataURI = canvas.toDataURL("image/jpg", 0.5);
canvas.toBlob(function (blob) {
saveAs(blob, oRequest.fileName)
});
});
})
What happens is that in the system itself, as soon as I drag the map with the mouse, the photo comes out weird (file attached)-
I noticed in the elements of html that although I see the objects of the layers adjusted to the map, in practice the div itself is dragged from place to place and this is what I get in the picture
I would be happy to help with this

Forge MArkups Font Size and Thickness of Freehand

I am trying to draw a Markups in forge Viewer but it's working when loading extension
var extensionOptions = {
hideIssuesButton: false,
hideFieldIssuesButton: true,
};
// Use the `viewer` reference to call `loadExtension` with the extension name and the extension options:
viewer["3d"].loadExtension('Autodesk.BIM360.Extension.PushPin', extensionOptions).then(function (extension)
{
PushPinExtensionHandle = extension;
});
but draw Thickness and Font Size is very small.How to increases the size?
Please find the attachment for reference.
here are some properties which u can adjust to set the size and width of your Text
var textgeometry = new Three.TextGeometry(text,
Object.assign({}, {
font: fonts,
bevelEnabled: false,
curveSegments: 2,
bevelThickness: 0,
color: 0xFFA500,
bevelSize: 0.21,
height: 3,
size: 1
}));
here is the link for reference how u can add Text Geometry
TextGeometry
It looks to me the post is about how to set font size and freehand thickness of Markup in Forge Viewer. I am not sure why the code snippet is about loading Pushpin Extension.
anyway, let me try to answer the question of font size and freehand thickness.
Markup Core extension provides the parameter to set font style when you create text. The parameter is a json, in which font-size is one key. So to set font size, the code is like below:
markupExt.enterEditMode();
var text1= new Autodesk.Viewing.Extensions.Markups.Core.CreateText(markupExt,2333,
{x:10,y:10}, {x:100,y:100},'My Test String Small', {"font-size":5})
text1.execute();
var text2= new Autodesk.Viewing.Extensions.Markups.Core.CreateText(markupExt,2333,
{x:30,y:30}, {x:130,y:130},'My Test String Big', {"font-size":20})
text2.execute();
As to thickness, the other post tells now to set stroke width.
Autodesk Forge Viewer Markup Style Object

Set transparent for specific element

I want set transparent for specific element, i follow this code:
var instanceTree = this.viewer.model.getInstanceTree();
var fragList = this.viewer.model.getFragmentList();
this.listElement.forEach(element => {
instanceTree.enumNodeFragments(element, (fragId) => {
console.log(element.material)
var material = fragList.getMaterial(fragId)
if (material) {
material.opacity = value;
material.transparent = true;
material.needsUpdate = true;
}
});
});
this.viewer.impl.invalidate(true, true, true);
but it overide for all elements have that material. How can i set for selected element?
Appreciate any comments.
UPDATE 1:
i found go around way is clone main material than register it with different name:
var newMaterial = material.clone();
const materials = this.viewer.impl.matman();
materials.addMaterial('mymaterial',newMaterial,true);
fragList.setMaterial(fragId,newMaterial);
newMaterial.opacity = value;
newMaterial.transparent = true;
newMaterial.needsUpdate = true;
but effect is not what i want, it has different color and when set transparent i can only see a couple object behind it
You can create your own, custom THREE.js material and assign it to the fragment using fragList.setMaterial(fragId, material).
For more information on using custom materials or shaders, see https://forge.autodesk.com/blog/custom-shader-materials-forge-viewer.
EDIT:
Regarding the visual anomalies (for example, when you only see some of the objects behind something semi-transparent), this is a known problem, unfortunately with no clear solution. When the Forge Model Derivative service creates an SVF file to be viewed in Forge Viewer, the individual scene elements are stored in a data structure optimized for fast traversal, depending on whether they are semi-transparent or fully opaque. This data structure is fixed, and so unfortunately, when you take an object that was originally fully opaque, and you make it semi-transparent, it will most likely be rendered in a wrong order...

dragging and dropping onto a jquery slider - posting position to server

I'm trying to implement dragging an item onto a jquery slider. For example, if the item is dropped onto 86% of the slider I would like to POST this position to the server so the item can be place 86% along the result set on the server.
How do you detect dropping onto a jQuery slider and the percentage POSTed to the server?
Since I'm not so good at explaining things, I made a jsFiddle for you. Although this might not be exactly what your looking for, it should be a good starting point!
Here's the code :
$(function () {
//the draggable object
$("#dragobject").draggable();
//Prepare the slider
var range = 100,
sliderDiv = $("#slider");
// Activate the UI slider
sliderDiv.slider({
min: 0,
max: range,
create : function(){
$(this).find(".ui-slider-handle").hide();
}
});
// Number of tick marks on slider
var position = sliderDiv.position(),
sliderWidth = sliderDiv.width(),
minX = position.left,
maxX = minX + sliderWidth,
tickSize = sliderWidth / range;
//Set slider as droppable
sliderDiv.droppable({
//on drop
drop: function (e, ui) {
var finalMidPosition = $(ui.draggable).position().left + Math.round($("#dragobject").width() / 2);
//If within the slider's width, follow it along
if (finalMidPosition >= minX && finalMidPosition <= maxX) {
var val = Math.round((finalMidPosition - minX) / tickSize);
sliderDiv.slider("value", val);
alert(val + "%");
//do ajax update here to set the position
/*$.ajax({
type: "POST",
url: url,
data: val,
success: function () {
//congrats
},
dataType: dataType
});*/
}
}
});
});
And here's the jsFiddle link : jsFiddle example
Hope it helps,
Marc.
SOURCES :
Jquery slider that slides while mouse move,
jQuery UI slider
Since you are using jQuery, lets assume you are using jQuery UI for your drag and drop. First read this: http://api.jqueryui.com/droppable/#event-drop
Then realize that you get the offset position of the dropped element relative to the droppable container as part of the event. This would be where you could compute that into percentage if you needed.
For example, dropped at position left -> 90px of a container that you know to be 100px wide means 90% is your magic number.
Or if you are using native drag and drop, check out this simple edit: http://jsbin.com/ezuke/3283/edit . If you pop a console log on the event in the drop event, you will see that it also exposes the offset of where you dropped it and you could again consume that in your calculation of %.