So, I am trying to position HTML in the viewer to almost make it look like it is part of the scene. So, when you move the camera, I want the position of it, in terms of the viewer, to stay where it is. Now, I have tried to shift the HTML to emulate this when the camera moves; however, I am not sure if my equation is not right or if I am not there. It seems to shift slightly, but not nearly as much as it should when the camera moves. In other words, if I were to put html on top of a cube in the viewer, and move the camera, I want to html to follow the cube. This is what I have tried:
this.viewer.addEventListener(av.CAMERA_CHANGE_EVENT, function(e){
console.log($(`.draggable`).attr(`originalPos`));
console.log(e.camera);
var width = window.innerWidth, height = window.innerHeight;
var widthHalf = width / 2, heightHalf = height / 2;
let originalPos = $(`.draggable`).attr(`originalPos`).split(` `);
let originalX = originalPos[0];
let originalY = originalPos[1];
$(`.draggable`).css(`position`, `absolute`);
let pixelX = (e.camera.position.x * .0005 + .5) * e.target.container.clientWidth;
let pixelY = (e.camera.position.y * -.009 + .5) * e.target.container.clientHeight;
$(`.draggable`).css(`left`, e.camera.position.x + pixelX);
$(`.draggable`).css(`top`, e.camera.position.y + pixelY);
});
$(`#viewer .adsk-viewing-viewer`).append(`<h1 originalPos = "50px 100px" class = "draggable" style="position: absolute; top: 50px; left: 100px;">Test</h1>`);
But this just not seem to have the correct scaling. It doesn't stay in the position I want it to. I have seen this similar concept in your MarkupsCore tool you have made, and also the area measurement tool seems to have some html that positions based on the camera. How do you do this?
Take a look at this blog article:
https://forge.autodesk.com/blog/3d-markup-icons-and-info-card
It has source code and an example repo, that shows, how to position an HTML DIV element to appear stuck to the 3D object in the Forge Viewer.
Related
I'm using a some code from https://github.com/dimxasnewfrozen/Panning-Zooming-Canvas-Demos/blob/master/demo12/main.js (demo at http://dayobject.me/canvas/demo12/) to zoom in on an image using the Canvas element.
However, when zooming the jump between one zoom level and the next is too large, so I need to add a scale parameter.
How would I got about doing this?
In your main.js, you can change your zoomLevel here,
mouseWheel: function (e) {
e.preventDefault() // Please add this, coz the scroll event bubbles up to document.
var zoomLevel = 2;
...
if (delta > 0)
{
// ZOOMING IN
var zoomedX = canvasPos.deltaX - (canvasZoomX - canvasPos.deltaX);
var zoomedY = canvasPos.deltaY - (canvasZoomY - canvasPos.deltaY);
// scale the image up by 2
initialImageWidth = initialImageWidth * zoomLevel;
}
else
{
// ZOOMING OUT
var zoomedX = (canvasPos.deltaX + canvasZoomX);
var zoomedY = (canvasPos.deltaY + canvasZoomY);
// scale the image down by 2
initialImageWidth = initialImageWidth / zoomLevel;
}
}
Disclaimer: this ruins the zoomedX and zoomedY values. You gotta fix them :)
It seams to me as if the algorithm always takes half of the dimension befor the zoom. At the end of you code you see it in main.js the mouseWheel function:
initialImageWidth = initialImageWidth * 2;
the width is divided by 2 so just change the used value.
You said the step used to zoom in and out is too big.
So I suggest that you generate the new value by using the dimensions of the image you want to zoom. For example you take a percentage of the biggest dimension of the current image.
That's how you can implement a zoom function that zooms according to the dimensions of the image
I'm making a website for my art gallery. Part of what I need to do is display images to the viewers in a way in which they can view them. And I want to do this without reducing the quality of the images, or having to save all of my images in many different sizes to cater to every user.
So, I've made a Javascript function to resize my images to fit completely on the viewer's screen. My code looks like
<img src="[image.png]" onload="setGoodHeight(this);">
where the function setGoodHeight(element) is defined as:
function setGoodHeight (element) {
if(window.innerHeight-50 < element.height) {
var h = element.height;
var w = element.width;
element.height = window.innerHeight - 50;
element.width = w * element.height / h;
}
if (window.innerWidth-100 < element.width) {
var h = element.height;
var w = element.width;
element.width = window.innerWidth - 100;
element.height = h * element.width / w;
}
}
In shorthand, this first checks whether the image is higher than the screen it's trying to be displayed on, and if it is (it usually is) the image is resized to fit comfortably on the screen. Then it checks if, after this, the image is wider than the screen, and if so it shrinks it further. I have verified that this code works.
However, the image is contained within a class called .post I want the post area to wrap to that of the image, at least in width, and so at the end of my javascript function, I added this code:
element.parentNode.width = element.width + 40;
But the post doesn't resize itself. For reference, the code on the actual webpage concerning this can be boiled down to
<div class="post">
<img src="[image.jpg]" onload="setGoodHeight(this);">
</div>
and if you need to look around it a little more it can be found at this link.
How about a pure CSS solution, it will also update magically if the user resizes their browser.
html, body, #fullscreen {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
#fullscreen {
background: url('http://www.nathanrouse.org/wp-content/uploads/2014/01/CrashTestDummy.jpg') center center no-repeat;
background-size: cover;
}
<div id="fullscreen"></div>
Check the doc for background-size. There are other values like "contain" that might suit you better.
I think you're looking for
item.naturalHeight
item.naturalWidth
I was using these in a function to set the max-height & max-width
function imageLoad(item) {
$(item).attr("max-height", item.naturalHeight);
$(item).attr("max-width", item.naturalWidth);
}
I have this idea, to add an "Online Users" thingy to my site.
But I don't know how to do this thingy.
Let me explain. If there are online users, it'll show this on the div.
But if there are alot of online users, which is gonna crowd the div,
I want the images inside to automatically resize, to accomodate the
extra users. Anyone?
PS: I can't post images yet.
This should get you started: http://jsfiddle.net/3KUvt/
The logic involves calculating the total available area in the beginning and calculating a new size (for each user element) whenever a new user is added.
Please note that this is a 2 minute fiddle and will need some fine tuning from your side before you can use this on production. :)
Code: See the demo above to get the complete picture
// can fit 8 of them without shrinking, so pre-calculate available area
var availableArea = 8 * 40 * 40;
function addUser() {
// after adding the new one, how many will there be?
var newCount = $('#holder > .user').length + 1;
// calculate new dimension of each user
var newW = 40; // use same var for w and h since its a square
if(newCount > 8) {
// reduce width (and height) till it fits
while((newCount * newW * newW) > availableArea) {
newW -= 1;
}
}
// resize all existing users
$('#holder > .user').css({
width: newW + 'px',
height: newW + 'px'
});
// add the new user (with the new height)
$('<div class="user"><div>').css({
width: newW + 'px',
height: newW + 'px'
}).appendTo('#holder');
}
I've looked everywhere and so far have not found a non-jQuery js to handle this. I would like to avoid using a library for just this one simple task.
I would like to fix three navigation divs ("#header", "#tabs" and "#footer") to viewport left (or alternatively, to the x position of a div "#helper" with "position: fixed; left: 0; top: 0;") -- but not fix y. They can not be vertically fixed.
I've created a working js that forces the divs to reposition based on scrolling, but it's not smooth in the real page (too many dynamic and graphic elements) - I'd like it to either animate smoothly, or mimic fixed-left and not appear to reposition at all.
Anyone who can give pointers or a quick script, or review and modify the script I have made? I've noticed people tend to ask why an obvious solution is not used instead of answering the question... I will be glad to answer, but would prefer help with the actual problem.
Here is a jsFiddle with the problem: http://jsfiddle.net/BMZvt/6/
Thank you for any help!
Smooth animation example:
var box = document.getElementById('box');
var moveTo = function(obj, target) {
// start position
// you should obtain it from obj.style
var cpos = {
x: 0,
y: 0
}
var iv = setInterval(function(){
cpos.x += (target.x - cpos.x) * 0.3; // 0.3 is speed
cpos.y += (target.y - cpos.y) * 0.3; // 0.3 is speed
obj.style.left = Math.floor(cpos.x) + 'px';
obj.style.top = Math.floor(cpos.y) + 'px';
var dist = Math.abs(cpos.y - target.y); // distance (x+y) from destination
dist += Math.abs(cpos.x - target.x); // < 1 = object reached the destination
if(dist < 1) { // here we are checking is box get to the destination
clearInterval(iv);
}
}, 30); // this is also the speed
}
box.onclick = function(){
moveTo(box, {x: 90, y: 75}); // fire this function to move box to specified point
}
Demonstration: http://jsfiddle.net/Qwqf6/5/
Your script is your job, but this is a quick start how to solve animation problem
You can also do some fancy stuff with speed for example use sin(x) to set the speed
Demonstration #2 http://jsfiddle.net/Qwqf6/6/ (very smooth)
Full script here https://gist.github.com/3419179
I don't think there's a straight way to do this...
But here's a way.
First, You need to be able to detect the direction of the scrolling when window.onscroll event happens. You would do this by comparing the current page offsets with the newly acquired page offsets whenever the scroll event happens. (http://stackoverflow.com/questions/1222915/can-one-use-window-onscroll-method-to-include-detection-of-scroll-direction)
Now suppose you know the direction of the scroll, you want to change the styling for the divs depending on the direction of the scroll.
Let FixAtX be the value of the x coordinate that you want to fix your divs at.
Let OriginalY be the y coordinate of the divs.
Also whenever scrolling happens, despite of the direction, you want to remember the pageoffset X and Y. Let's call them OldX and OldY
If scrolling vertically:
Set position value for divs' style to be absolute.
Set top value for divs' style to be OriginalY
Set left value for divs' style to be OldX + FixAtX
If scrolling horizontally:
Set position value for divs' style to be fixed.
set top value for divs' style to be OriginalY - OldY (<- this may be different depending on how the browser computes pageOffset value,)
Set Left value for divs' style to be FixAtX
I think this should work...
Since you are just using browser's rendering for positioning, it should be very smooth!
hope I understood the question correctly.
This is for people who view this post - I wound up going with the solution I initially put together in the jsFiddle that used a simple javascript to mimic fixed x.
The javascript in the first answer was hefty and wound up buggy, and the second answer sounded good but did not work in practice. So, I'm recommending the javascript from the jsFiddle (below) as the best answer to fixed x and fluid y without a javascript library. It's not perfect and has a minimal delay but is the best answer I've found.
function fixLeft() {
function getScrollX() {
var x = 0, y = 0;
if( typeof( window.pageYOffset ) == 'number' ) {
x = window.pageXOffset;
} else if( document.body && ( document.body.scrollLeft) ) {
x = document.body.scrollLeft;
} else if( document.documentElement && ( document.documentElement.scrollLeft) ) {
x = document.documentElement.scrollLeft;
}
return [x];
}
var x = getScrollX();
var x = x[0];
// have to get and add horizontal scroll position px
document.getElementById('header').style.left = x + "px";
document.getElementById('tabs').style.left = x + "px";
document.getElementById('footer').style.left = x + "px";
}
window.onscroll = fixLeft;
I'm trying to create a rollercoaster ride for a project and need the rollercoaster to follow a path.
You can see my illustration on rollercoaster
I need the red box to follow the rollercoaster road in the background? The red box illustreres the image I'm going to use. Is this possible? I'm trying using this code...
<script type="text/javascript">
$(window).on('scroll', function(e) {
var scrollTop = $(window).scrollTop();
//var windowHeight = $(window).height();
var windowHeight = $('.road2').height();
//var S = scrollTop + Math.floor(windowHeight / 2);
var S = $(this).scrollTop(); // scrolled distance
var t = 0 + (S/windowHeight);
//var T = 0 + (S/36); // value for Top
//var L = 300 + Math.abs(Math.sin(S/400)*460); // value for Left
//
//$(".rollerImage").css({top: T+'%', left: L+'px'}); //set CSS
var canvas_X=400;
var canvas_Y=400;
// Increment Parameterization
t += 0.05;
// Width of Car
var car_X=150;
// Hieght of Car
var car_Y=50;
// Point A
var a_X=0;
var a_Y=0;
// Point B
var b_X=canvas_X-car_X; //Place point B at the end
var b_Y=0;
// Center of Semi Circle
var c_X=(b_X-a_X)/2;
var c_Y=(a_Y-a_Y)/2;
// Calculate X and Y point on trajectory
var x = a_X + t * (b_X- a_X);
var y = Math.sqrt(Math.pow((b_X - a_X),2)/4 + Math.pow((x-c_X),2));
$(".rollerImage").css({top: x+'px', left: y+'px'}); //set CSS
});
</script>
Hope someone can help with this type of path animation. Maybe it is possible to define the path in a array of coordinates?
I've tried using joel scrollpath, but can't "bind" an image to the path :(
//Graahf
I've tried to get it working with the jQuery Scrollpath using your html and css files plus the code from the demo site.
Check if this is OK for you: http://jsfiddle.net/Skr4R/6/embedded/result/
You can also check the sources of the fiddle: http://jsfiddle.net/Skr4R/6/
Important for this, is that the entire wrapper moves and rotates, that is why in my solution the train-image is outside of the wrapper, like this:
<div class="rollerCoasters">
<img src="" style="background:red; height:100px; width:50px; position:absolute; top:380px; left:50%; z-index:200; margin-left:-25px">
</div>
<div class="wrapper">
<div class="road1"><img src="base64-encoded-img" width="1434" height="539"/></div>
</div>
Hope this gets you started. It might not be the best solution, if you want the train to move, and not it's surroundings.
i am trying to achieve the same process and this has helped me along, the way forward about roating the train/object with the track could you not rotate the background(track to make the train look like it is following the track)