I am trying to create a new div layer using JavaScript that can be absolutely positioned on the page after page load.
My code is as follows:
<html><head>
<script type="text/javascript">
function showLayer() {
var myLayer = document.createElement('div');
myLayer.id = 'bookingLayer';
myLayer.style.position = 'absolute';
myLayer.style.x = 10;
myLayer.style.y = 10;
myLayer.style.width = 300;
myLayer.style.height = 300;
myLayer.style.padding = '10px';
myLayer.style.background = '#00ff00';
myLayer.style.display = 'block';
myLayer.style.zIndex = 99;
myLayer.innerHTML = 'This is the layer created by the JavaScript.';
document.body.appendChild(myLayer);
}
</script>
</head><body bgcolor=red>This is the normal HTML content.
<script type="text/javascript">
showLayer();
</script>
</body></html>
The page can be seen here.
The problem I am having is that the div is sitting after the original body content rather than over it on a new layer. How can I remedy this?
Try with this instead:
var myLayer = document.createElement('div');
myLayer.id = 'bookingLayer';
myLayer.style.position = 'absolute';
myLayer.style.left = '10px';
myLayer.style.top = '10px';
myLayer.style.width = '300px';
myLayer.style.height = '300px';
myLayer.style.padding = '10px';
myLayer.style.background = '#00ff00';
myLayer.innerHTML = 'This is the layer created by the JavaScript.';
document.body.appendChild(myLayer);
The reason it was not working is that you used x and y css properties (which don't exist) instead of left and top. Also, for left, top, width, height you had to specify a unit (e.g. px for pixels).
Try these,
Set the position using top and left rather than x and y.
An absolute positioned element needs to be contained inside something that also has a position style. The usual trick is to create a container with position: relative.
You should be setting styles such as width, height, top, left etc with + 'px'.
You don't need to set display: block for the div as it is already a block element.
Related
In my vis.js network, I want to make a popup appear at the position of a node when I click on the node.
I used the getPositions method but the popup appears in the wrong place (too much on the left and top corner), as if the coordinates were incorrect.
network.on("click", function (params) {
// Get the node ID
var nodeId = params.nodes[0];
if (nodeId) {
// Get the node title to show in the popup
var popup = this.body.nodes[nodeId].options.title;
// Get the node coordinates
var nodePosition = network.getPositions(nodeId);
var nodeX = nodePosition[nodeId].x;
var nodeY = nodePosition[nodeId].y;
// Show the tooltip in a div
document.getElementById('popup').innerHTML = popup;
document.getElementById('popup').style.display = "block";
// Place the div
document.getElementById('popup').style.position = "absolute";
document.getElementById('popup').style.top = nodeY+'px';
document.getElementById('popup').style.left = nodeX+'px';
}
});
// Empty and hide the div when click elsewhere
network.on("deselectNode", function (params) {
document.getElementById('popup').innerHTML = null;
document.getElementById('popup').style.display = "none";
});
I got some help on the vis support section of github.
Turns out the trick was to use canvasToDOM().
Here's how it applied to my code:
network.on("click", function(params) {
// Get the node ID
var nodeId = params.nodes[0];
if (nodeId) {
// Get the node title to show in the popup
var popup = this.body.nodes[nodeId].options.title;
// Get the node coordinates
var { x: nodeX, y: nodeY } = network.canvasToDOM(
network.getPositions([nodeId])[nodeId]
);
// Show the tooltip in a div
document.getElementById("popup").style.display = "block";
// Place the div
document.getElementById("popup").style.position = "absolute";
document.getElementById("popup").style.top = nodeY + "px";
document.getElementById("popup").style.left = nodeX + "px";
}
});
It works when the network stays put, but in my case I want to fit the network and zoom on the clicked node, so the popup doesn't follow, but since this is a separate issue I will post another question.
You are using network.getPositions(params.nodes[0]), but since the nodes can change a lot when zooming in and out and moving the network on the canvas somehow the positions do not match the real position of the node. I do not know if this is a bug in visjs or there is some other reason for it. The docs say they return the position of the node in the canvas space. But thats clearly not the case in your example.
Looking at the docs [ https://visjs.github.io/vis-network/docs/network/#Events ] the click event argument contains:
{
nodes: [Array of selected nodeIds],
edges: [Array of selected edgeIds],
event: [Object] original click event,
pointer: {
DOM: {x:pointer_x, y:pointer_y}, // << Try using this values
canvas: {x:canvas_x, y:canvas_y}
}
}
Try to use the params.pointer.DOM or params.pointer.canvas positions X and Y to position your popup. This should be the location of the cursor. This will be the same position as the node, since you clicked on it.
So try something like:
document.getElementById('popup').style.top = params.pointer.DOM.y +'px';
document.getElementById('popup').style.left = params.pointer.DOM.x +'px';
-- Untested
use the click event and paint a div over the canvas.
network.on("click", function(params) {
// Get the node ID
var nodeId = params.nodes[0];
if (nodeId) {
// Get the node title to show in the popup
var popup = this.body.nodes[nodeId].options.title;
//use JQUERY to see where the canvas is on the page.
var canvasPosition = $('.vis-network').position();
//the params give x & y relative to the edge of the canvas, not to the
//whole document.
var clickX = params.pointer.DOM.x + canvasPosition.top;
var clickY = params.pointer.DOM.y + canvasPosition.left;
// Show the tooltip in a div
document.getElementById("popup").style.display = "block";
// Place the div
document.getElementById("popup").style.position = "absolute";
document.getElementById("popup").style.top = clickY + "px";
document.getElementById("popup").style.left = clickX + "px";
}
});
fixed position for tooltip/popup example
I have an empty div with a scrollbar:
<div id="figure1" style="width:1000px; height:300px; overflow:scroll;"></div>
And using javascript I am adding images into the div:
function add_img(imgID, src, x, y, height, width){
var img = document.createElement("img");
img.setAttribute('id', imgID);
img.setAttribute('src', src);
img.style.left = x;
img.style.top = y;
img.style.width = width;
img.style.height = height;
img.style.position = 'absolute';
document.getElementById('figure1').appendChild(img);
}
When I add a new image outside of the 1000x300px box, I want that image to only be visible when you use the scrollbar.
Instead, the images which lie outside of the box overflow beyond the edges of figure1. The scrollbar doesn't do anything.
How can I stop the images from overflowing?
Thanks!
I see two issue - first you need to add + "px" to your dimensions (at least if you use integer type parameters like I did).
The other thing would be not to use position = "absolute". For example position = "relative" seems to do the trick. (If you like, have a further read on the layout options in CSS, good luck)
https://jsfiddle.net/xpsu9usw/
How would I make a JavaScript function that, when it is run, creates a new <div> element at the cursors position with the class 11 and id 12; then deletes it after 2 seconds?
I don't want to use any external scripts. I just want it to be raw JavaScript.
Firstly, you're going to have to use mouse events. Mouse events contains properties such as clientX, clientY, pageX, pageY, offsetX, offsetY, screenX, screenY. Look up the difference. These are read-only properties and display coordinates based on what kind of property they are.
So basically you can pretty much create an element, make the position absolute, and set the top and left properties using the mouse events properties such as pageX and pageY.
Adding a function
document.body.setAttribute('onclick', 'myFunction(event)');
Then creating the element
function myFunction(ev){
var div = document.createElement('div');
div.id = '12';
div.className = '11';
div.style.position = 'absolute';
div.style.height = '100px';
div.style.width = '100px';
div.style.backgroundColor = 'cornflowerblue';
div.style.top = ev.pageY;
div.style.left = ev.pageX;
var body = document.getElementsByTagName('body');
body[0].appendChild(div);
//you can easily destroy in 2 seconds using set timeout
setTimeout(function(){
body[0].removeChild(div);
}, 2000)
}
Try it. This code will create a div element in the position where you click your mouse.
I am trying to create a button in javascript and make that button positioned below a canvas, the same width as the canvas, however, I don't seem to be able to set the top and width as a variable (the code is ignored). Here is my code: (problem lines commented)
var myButton = document.createElement('button');
myButton.style.position = 'absolute';
myButton.style.left = '0px';
myButton.style.top = canvasHeight; //
myButton.style.width = canvasWidth; //
myButton.style.height = '100px';
myButton.innerHTML = 'Restart!';
document.body.appendChild(myButton);
Note that the canvas is resizable, so I can't just type in a px value.
Here's my comment in an answer:
Make sure you have the correct format in canvasHeight and canvasWidth, e.g. "100px" rather than just "100".
I have seen some similar questions here but not actually what I need to know!
I am using Flash CS6 and outputting a CreateJS framework animation instead of regular .swf files. When you publish from within the API (Flash) it generates an html5 doc and an external .js file with the actual javascript that defines the animation.
Here's what I need: I want my animation to either be able to go full screen and maintain it's aspect ratio -OR- be set at say 1024x768 and be centered in the browser window but if viewed on a mobile device, dynamically resize to fit the device screen size or viewport size and centered.
A perfect example of what I need is here: http://gopherwoodstudios.com/sandtrap/ but I don't see which code is doing the dynamic resizing in this example.
Any help would be greatly appreciated. In addition, I am supplying the html5/js output of the Flash API since it seems to be very, very different than the example code given in other canvas-related posts.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>CreateJS export from index</title>
<script src="http://code.createjs.com/easeljs-0.5.0.min.js"></script>
<script src="http://code.createjs.com/tweenjs-0.3.0.min.js"></script>
<script src="http://code.createjs.com/movieclip-0.5.0.min.js"></script>
<script src="http://code.createjs.com/preloadjs-0.2.0.min.js"></script>
<script src="index.js"></script>
<script>
var canvas, stage, exportRoot;
function init() {
canvas = document.getElementById("canvas");
images = images||{};
var manifest = [
{src:"images/Mesh.png", id:"Mesh"},
{src:"images/Path_0.png", id:"Path_0"}
];
var loader = new createjs.PreloadJS(false);
loader.onFileLoad = handleFileLoad;
loader.onComplete = handleComplete;
loader.loadManifest(manifest);
}
function handleFileLoad(o) {
if (o.type == "image") { images[o.id] = o.result; }
}
function handleComplete() {
exportRoot = new lib.index();
stage = new createjs.Stage(canvas);
stage.addChild(exportRoot);
stage.update();
createjs.Ticker.setFPS(24);
createjs.Ticker.addListener(stage);
}
</script>
<style type="text/css">
body {text-align:center;}
#container { display:block;}
</style>
</head>
<body onload="init();" style="background-color:#D4D4D4">
<div id="container">
<canvas id="canvas" width="1024" height="768" style="background-color:#ffffff; margin: 20px auto 0px auto;"></canvas>
</div>
</body>
</html>
Thanks again!
don't know if you worked this one out in the end, but I recently had the same issue - I just needed to resize the whole createJs object to the viewport.
I added a listener to viewport resizing (I used jQuery), then resized the canvas stage to match the viewport, then using the height of the original flash stage height, or width depending on what you want (mine was 500), you can scale up the createJs movie object (exportRoot).
(function($){
$(window).resize(function(){
windowResize();
});
})(jQuery);
function windowResize(){
stage.canvas.width = window.innerWidth;
stage.canvas.height = window.innerHeight;
var test = (window.innerHeight/500)*1;
exportRoot.scaleX = exportRoot.scaleY = test;
}
Hope that helps someone!
function resizeGame()
{
widthToHeight = 600 / 350;
newWidth = window.innerWidth;
newHeight = window.innerHeight;
newWidthToHeight = newWidth / newHeight;
if (newWidthToHeight > widthToHeight)
{
newWidth = newHeight * widthToHeight;
gameArea.style.height = newHeight + 'px';
gameArea.style.width = newWidth + 'px';
} else
{
newHeight = newWidth / widthToHeight;
gameArea.style.height = newHeight + 'px';
gameArea.style.width = newWidth + 'px';
}
scale = newWidthToHeight / widthToHeight;
stage.width = newWidth;
stage.height = newHeight;
gameArea.style.marginTop = ((window.innerHeight - newHeight) / 2) + 'px';
gameArea.style.marginLeft = ((window.innerWidth - newWidth) / 2) + 'px';
}
widthToHeight is your game canvas scaling ratio. gameArea is your div id
make it sure your html tag must contain
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"/>
The inline width and the height of the canvas define "resolution" - setting a CSS style of width defines "scale". Think of it like canvas size and image size in photoshop.
Because width and height of elements isn't defined when you export, I'm struggling to come up with a good way to scale up. But, you can always scale down. Use CSS to set the max-width and max-height to be 1024x768 (or whatever your original is) and then set the regular width and height to be whatever you need (proportionately).
Then just use CSS to center - margin:auto and all that.
I find it useful to allow my canvas to be fluid based on width, and then adjust the height based on the aspect ratio on resize. There are a couple things to keep in mind.
You must assign a width & height attribute to the canvas element whether you're creating with javascript or with html
You have to adjust the object's style.height property, not the canvas height property directly.
If you follow this sort of example you can even use media queries to give even more flexibility. jsFiddle, if you please.
var el = document.getElementById('mycanvas');
var aspectRatio = el.height / el.width;
resizeCanv = function resize (){
var style = getComputedStyle(el);
var w = parseInt(style.width);
el.style.height = (w * this._aspectRatio) + 'px';
};
// TODO: add some logic to only apply to IE
window.addEventListener('resize', resizeCanv);
EDIT: I haven't tested this with any interactivity within the canvas, only layout and animations.