How can I dynamically resize a div? - html

I found some answers about dynamically doing stuff to divs, but none of them did what I want.
I am working with Raphael js vector library and need a div for the canvas where the objects are going to be drawn. For example:
<html>
<head>
<style>
#canvas
{
height: 2000px;
position: absolute;
width: 1500px;
}
</style>
</head>
<body>
<div id="canvas"></div>
<!-- some code here -->
</body>
</html>
In my JS file I did the following:
var paper = Raphael("canvas"),
r = paper.rect(100, 100, 100, 100),
c = paper.circle(500, 500, 80);
Now on my application, the user will populate the canvas by creating objects like r and c I showed above. But the problem is that once an object gets created outside of canvas' dimensions, it will not be show on the paper/canvas.
I am trying to dynamically enlarge div's size to i.e. height: 3000px, width: 2000px. I found some answers about absolute position but that did not help. Also found about div overflow, but this applies to div's parent element. Any help will be appreciated.

What you need to do is resize both the containing div and the paper. In this example I will show your circle is cropped bottom right.
When you click the canvas, it will resize to show your circle is drawn correctly.
See http://jsfiddle.net/kRzx5/7/
var paper = Raphael("canvas"),
r = paper.rect(100, 100, 100, 100),
c = paper.circle(500, 500, 80);
// size i want to resize to
var w = 1000;
var h = 1000;
var canvas = $('#canvas');
canvas.on('click', function(){
// resize container
$(this).css({width: w, height: h});
// resize paper
paper.setSize(w, h);
});
In this example I am using an arbitrary size to use, you could keep checking the positions and sizes of each object that gets added, and find the item which has largest value on x and y when checking its bounding box, then resize to this. So paper will always fit the items that get added.

Related

CSS - Position elements on the same place despite of device's screen size

I am developing an Ionic App and it needs to have some buttons (one above another, not inline) on the bottom-left place of the device's screen
I have the following CSS:
.button {
left = "1em";
z-index = "13";
overflow = "scroll";
position = "absolute";
width = "3em";
height = "2.5em";
textAlign = "center";
}
and then I calculate its bottom like this:
let bottom: number = 0;
this.floors.forEach(floor => {
let floorButton: HTMLElement = document.createElement("button");
floorButton.setAttribute("class", "button");
floorButton.appendChild(document.createTextNode(floor.level));
floorButton.style.bottom = bottom + "em";
bottom = bottom + 5;
});
Now my problem is simple: in a device with a bigger screen than another device, it is positioning in an upper position.
I can workarround this by calculating the height of the device's screen and dividing it x times until I get to the position I want. But this looks dirty to me (I don't know if it's the right wait tho, maybe it is).
So my question is, is there a simpler way that doing this as the one I put above instead of having to calculate the screen's height size in pixels? Can it be done directly by CSS? I've checked #media but it looks like it won't help at all. Or maybe I'm just doing it right and I'm overthinking it too much?
Thanks!
You can just use CSS for this:
.button {
display: block;
margin-top: 5px;
}
In this way doesn't matter what is the width of screen, always your buttons will be in separate line.

HTML5 canvas: how do I query or modify the underlying bitmap dimensions as opposed to the DOM element dimensions?

I'm using an HTML5 canvas element:
<style>
#myCanvas {
width: 100%;
height: 100%;
object-fit: contain;
}
</style>
<canvas id="myCanvas" ontouchstart="..." />
I understand that there is an underlying bitmap, and then there is a DOM element that this bitmap is boxed in, and the 2 objects have different dimensions, so e.g. the bitmap is scaled/squished to fit into the DOM element. It would be easier for me to understand if the bitmap dimensions always equalled the DOM element dimensions, but that's not how it works.
How do I query the respective dimensions?
How do I set the respective dimensions?
How do I see the 2 sets of dimensions in the Chrome developer tool?
How do I keep the 2 sets of dimensions in sync?
This is important because mouse-clicks and finger touches are delivered in DOM coords but we'd usually need to interpret them in canvas coords.
(And a related question: have I done it correctly, to set the DOM element to expand to the maximum dimensions allowed by the parent?).
To get the dimensions of the canvas's underlying bitmap:
var w = canvas.width;
var h = canvas.height;
To get the dimensions of the DOM element:
var w = canvas.clientWidth;
var h = canvas.clientHeight;
To set the canvas's underlying bitmap:
canvas.width = 900;
canvas.height = 400;
To set the DOM element's dimensions, this is down to CSS styles and whatever else is on the screen and it's a more complex question.
In Chrome, "Developer Tools", Chrome displays the DOM element dimensions and I couldn't find any way to get the canvas underlying bitmap dimensions other than typing in "canvas.width" and "canvas.height" into the commandline.
As for trying to arrange such that height==clientHeight and width=clientWidth , I would guess that it's possible but it's probably also difficult and probably undesirable.
So to map a touch action or mouseclick from DOM element coords to canvas bitmap coords, a simple scaling operation seems sufficient:
function elementCoordsToCanvasCoords(X,Y)
{
X = X * canvas.clientWidth / canvas.width;
Y = Y * canvas.clientHeight / canvas.height;
return [X,Y];
}
function onTouchStart(event)
{
fingerStart(event.changedTouches[0].clientX, event.changedTouches[0].clientY);
}
function fingerStart(X, Y)
{
[X,Y] = elementCoordsToCanvasCoords(X,Y);
...
}

Moving background with my cursor

My website's landing page (http://www.chrisamaddeo.com/) has a full screen background. I want to make it move like an example of this website's header (http://www.kaiserair.com/) I have this code, HTML, which goes in the head of my website:
<!DOCTYPE html>
<html>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
<script>
$(document).ready(function() {
var movementStrength = 25;
var height = movementStrength / $(window).height();
var width = movementStrength / $(window).width();
$("#top-image").mousemove(function(e){
var pageX = e.pageX - ($(window).width() / 2);
var pageY = e.pageY - ($(window).height() / 2);
var newvalueX = width * pageX * -1 - 50;
var newvalueY = height * pageY * -1 - 25;
$('#top-image').css("background-position", newvalueX+"px "+newvalueY+"px");
});
I have this code, css and it doesn't work:
#top-image {
background:url('https://d3ui957tjb5bqd.cloudfront.net/images/screenshots/products/0/8/8905/red-rocks-park-o.jpg' -50px -25px;
position:fixed ;
top:0;
width:100%;
z-index:0;
}
My website is hosted with weebly and their html is a little different
Actually, i've just tried copying your code:
http://codepen.io/chrisboon27/pen/rEDIC
It does work, in that it moves the image.
I did have to add some some closing braces to your jQuery but maybe you just missed those when you pasted the code into this question.
Also, I looked at your site and noticed you are currently using background-size:cover. This takes your bg image and makes it fit within the div - you dont want that as you want some bg extending beyond the div - so i'n the css in the example I linked to you can see I used calc to make the bg-image size to 100% width + 50px. I used 50px as your code currently moves the background image position by up to 25px left or right, therefore you need it to be 50px total wider than the div.
EDIT:
If you use calc you should include a -webkit prefixed version too (unless you are using prefix-free or prefixr to add prefixes. Here is browser support: http://caniuse.com/calc
If you need to support more browsers you will need to set background-size via javascript
I'm finding that quite hard to follow without recreating it and seeing where those numbers come from. However I recently made something very similar with jQuery for someone else except it moves an img within a div. It probably wouldn't take much to switch it to move a background image though (though finding out the bg-image dimensions would be tricky - you might be better hard coding them in that instance).
html:
<div class="container"><img src="foo.jpg" class="draggable"/>
</div>
jQuery:
//for each item
$(".container").each(function(){
//get the container width
var conWidth = $(this).width();
//and its height
var imgHeight = $(this).find("img").height();
//get the nested img width
var conHeight = $(this).height();
//and its height
var imgWidth = $(this).find("img").width();
//figure out how much of the image is not visible horizontally
var excessWidth = imgWidth - conWidth;
//and how much is not visible vertically
var excessHeight = imgHeight - conHeight;
//how far is this container from the left of the page
var containerPositionLeft = this.offsetLeft;
//and from the top
var containerPositionTop = this.offsetTop;
//when moving mouse over container
$(this).mousemove(function(e){
//figure out how many pixels the mouse is from the left edge of the page
var mouseoffLeftPage = e.pageX;
//and how many from the top edge of the page
var mouseoffTopPage = e.pageY;
//figure out how many pixels the mouse is from the left edge of the page
var mouseoffLeftPx = mouseoffLeftPage - containerPositionLeft;
//and how many from the top edge of the page
var mouseoffTopPx = mouseoffTopPage - containerPositionTop;
//figure out the distance the mouse is from the left edge as a percentage (kind of - all the way to the right equals 1 not 100)
var mouseoffLeftPercent = mouseoffLeftPx/conWidth;
//do the same for height
var mouseoffTopPercent = mouseoffTopPx/conHeight;
//times the 'percentage' value by the amount of image hidden - so if your conatiner is 200px wide, your image 300px wide nd your mouse is half way across this value would be 0.5*100 which would give you 50 - which is exactly half the amount of image that is missing.
//note this gets set as a minus value as we will be using a minus number to shift the image around.
var setnewWidth = -(mouseoffLeftPercent * excessWidth);
//do the same for the height
var setnewHeight = -(mouseoffTopPercent * excessHeight);
//add the values as css (using transform(translate) as it's more performant and does subpixel rendering so looks smoother [or does it? it does in animations but seems as my js is not technically animating it it might not make a difference in that respect] - could set the top,left version as fallback for unsupporting browsers but ie9 supports transforms anyway so i dont care.)
$(this).find("img").css({"transform" : "translate("+ setnewWidth+"px ,"+setnewHeight+"px)" });
//$(this).find("img").css({"left" : setnewWidth+"px", "top" : setnewHeight+"px" });
});
});
Not a direct answer to what isn't working in your code, but shows an example (with comments on what is happening) of how it can be done - note that my version doesn't rely on you knowing any of the widths or heights of objects and can run on multiple items on one page - also it doesn't have to be placed at the very top of the page. It does assume the image is larger than its container though - if it isn't larger the image just moves around within it.
You could reduce the number of variables by doing more calculations in a row, I just wanted it to be as easy to read the logic as possible.
DEMO:
http://codepen.io/chrisboon27/pen/BhkJq
Simpler than that, you can just make sure the CSS position is set to "fixed" so wherever you are on the page it's always 0px from the top.

HTML5 Canvas (SIMPLE PAINT APPLICATION)

I'm working on a paint application and I'm trying to centre the canvas onto the middle of the screen . Any attempts I made the detection was off(still at the top left of the screen) but it was visually appearing in the centre of the screen.
Basically it wont draw onto the canvas when I moved it to the centre of the screen.
Any help would be much appreciated , Thanks....
I HAVE MY CODE BELOW ...
It's not clear from your question how you're centring it, but you need to account for any offset of elements which contain your canvas when you attempt to map the mouse position to a position on the canvas. You can do this by including the offsetLeft and offsetTop values (see docs) of the containing element when you do your calculations.
The following will work if you're offsetting the position of the div which wraps the canvas (which I've given an id to make it easier to reference):
function move(e) {
// Get the div containing the canvas. Would be more efficient to set this once on document load
var container = document.getElementById('container');
if((e.button == 0) && (mouseIsDown)) {
g.beginPath();
document.onselectstart = function(){ return false; }
//g.fillStyle = "red";
// Account for the offset of the parent when drawing to the canvas
g.arc((e.x - container.offsetLeft) - brush, (e.y - container.offsetTop) - brush, brush, 0, Math.PI * 2);
g.fill();
g.closePath();
}
}
And a simplistic demo using your fiddle here.

How can I keep my canvas fast when creating a large map?

I'm trying to create a game with HTML5 and a canvas. At the moment I am using the KineticJS library.
The things I have working so far are zooming in and out, dragging from a layer within the stage, and dragging from some objects. This all works nice and fast.
However, the game also needs a landscape, where people can build houses, grainfields etc. Also there need to be some trees and other details. This all makes the canvas very full.
So to test, I made a canvas layer of 10000 x 10000 pixels and made it in 100 x 100 tiles of 100 x 100 px. Just this took so much time it didn't even load.
So I tried it with less tiles (25 x 25) and this does load, but when I try to zoom, drag the stage or drag an object, it is very, very slow and it all needs to contain many more objects.
So the main question is: Can anyone consult me of which method I can use best for the above story? Is a canvas the correct option, or are there other (and better) options?
A 10,000 x 10,000px map is waaay to large.
Conceptually, this is fine. The trick is not to hold-in-memory/draw the whole thing! ie, even if your map is that large you'll only ever draw/update the tiles/objects for the 500 x 500px, or whatever your viewport is, around your character.
See this post, and Simon's answer to achieve this.
And here is the example jsFiddle (full credit to Simon Sarris) associated with the answer.
I found a perfect solution!
I'm going to combine canvas with some regular HTML like div.
I have made this, it makes a field from 15000x15000 px within this div i make 225 new divs which will contain the canvas objects. Every canvas object will have a size from 100x100 px.
The total loading time is about 4 seconds, and I will build the zooming, dragging with just some javascript and divs.
<!DOCTYPE HTML>
<html>
<head>
<style>
body,html {
margin: 0px;
padding: 0px;
}
#container{
width: 15000px;
height: 15000px;
}
.canvas{
float: left;
margin: 0px;
padding: 0px;
height: 1000px;
width: 1000px;
}
</style>
<script src="/js/jquery.js"></script>
<script src="/js/kinetic.js"></script>
</head>
<body>
<div id="zoomer" style="position: absolute;"></div>
<div id="container">
<?php for ($x = 1;$x<=15;$x++){?>
<?php for ($y = 1;$y<=15;$y++){?>
<div class="canvas" id="blok<?php echo $x;?>-<?php echo $y;?>"></div>
<?php } ?>
<?php } ?>
</div>
<script>
var bk = {};
$.each($(".canvas"),function(){
var id = this.id;
bk[id] = new Kinetic.Stage({
container: this.id,
width: 1000,
height: 1000
});
var ly = new Kinetic.Layer();
for(x = 0;x<10;x++){
for(y = 0;y<10;y++){
var r = Math.random();
var g = Math.random();
var b = Math.random();
var tile = new Kinetic.Rect({
width: 100,
height: 100,
x: x * 100,
y: y * 100,
fill: "rgb("+ parseInt(255*r) +","+ parseInt(255*g) +","+ parseInt(255*b) +")"
});
ly.add(tile);
}
}
ly.draw();
bk[id].add(ly);
});
</script>
</body>
</html>
Anyway, thanks for the effort!