Drawing rectangles in web application that show screen position from windows - javascript

I have an input string like this:
{ (3200, 1080), (1280, 0) ; (1280, 1024), (0, 0) }
which is basically an input I get from my c# program which takes the coordinates of my screens.
The numbers in brackets are coordinates of the lower right and upper left point and define a rectangle. For example:
(1280, 1024), (0, 0)
means that the first screen has dimensions 1280 x 1024 and starts in the upper left point (0,0). Next to it is the second screen which upper left point is at coordinate (1280, 0) and its lower right coordinate is at point (3200, 1080) - and they form a rectangle.
What I have to do is draw these screen in an web application - nothing fancy just two different colored rectangles would do. Now, I did a little research and saw that html5 canvas might be the way to go, but I want to hear what you think and maybe give me a push in the right direction. If you could give some jsfiddle example that would be appreciated!

You could just use DIVs with position: absolute, as detailed on this jsFiddle (jQuery used for the sake of simplicity, but the same can easily be accomplished without jQuery).
edit (I just added the code if for some reason your jsfiddle gets deleted!):
HTML:
<div id="screens">
<div id="screen0" class="screen"></div>
<div id="screen1" class="screen"></div>
</div>
CSS:
#screens { position: relative }
.screen {position: absolute }
#screen0 { background: blue; }
#screen1 { background: green; }
JS:
var originalScreens = [
{
position: [0,0],
dimensions: [1280,1024]
},
{
position: [1280,0],
dimensions: [1090,1080]
}
];
var scale = 0.1;
for(var i=0; i<originalScreens.length; i++) {
$('#screen' + i).css('left', (originalScreens[i].position[0] * scale) + 'px');
$('#screen' + i).css('top', (originalScreens[i].position[1] * scale) + 'px');
$('#screen' + i).css('width', (originalScreens[i].dimensions[0] * scale) + 'px');
$('#screen' + i).css('height', (originalScreens[i].dimensions[1] * scale) + 'px');
}

Related

How to find out if an object is touching another object in JS

(excuse my bad english, I am 13 years old)
alright, even though i just joined stackoverflow today, I have been coding for a while. I'm trying to make a simple game (and may make it something bigger later) and I want the hammer (the player sprite) not be able to go through the box toward the middle of the screen, but I don't know how. here is what I have:
var sq = document.getElementById("box");
var posX = 0;
var posY = 0;
var rot = "rotate(0deg)";
var id = null;
function move(object, pixels, xa){
if(xa == true) {
posX+=pixels;
object.style.left = posX + 'px';
}else{
posY+=pixels;
object.style.top = posY + 'px';
}
}
OBJect.style.left = "200px";
OBJect.style.top = "200px";
document.addEventListener('keydown', logKey);
function logKey(e) {
if (`${e.code}` == "ArrowRight") {
rot = "rotate(90deg)";
sq.style.transform = rot;
move(sq, 5, true);
if(posX > 470){
posX = 5;
}
}
if (`${e.code}` == "ArrowLeft") {
rot = "rotate(270deg)";
sq.style.transform = rot;
move(sq, -5, true);
if(posX < 0){
posX = 465;
}
}
if (`${e.code}` == "ArrowDown") {
rot = "rotate(180deg)";
sq.style.transform = rot;
move(sq, 5, false);
if(posY > 465){
posY = 5;
}
}
if (`${e.code}` == "ArrowUp") {
rot = "rotate(0deg)";
sq.style.transform = rot;
move(sq, -5, false);
if(posY < 0){
posY = 470;
}
}
}
setInterval(function(){
xaxis.innerHTML = "x: " + posX;
yaxis.innerHTML = "y: " + posY;
rotate.innerHTML = rot;
},1);
#myContainer {
width: 500px;
height: 500px;
position: relative;
background: black;
outline: red solid 10px;
}
#box {
width: 30px;
height: 30px;
position: absolute;
background-color: gray;
}
#OBJect {
width: 30px;
height: 30px;
position: absolute;
background-color: gray;
}
<!DOCTYPE html>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>
<style>
/*style would go here/*
</style>
<body>
<div id="myContainer">
<img src="https://cdn.glitch.com/7f9c2ae2-9b45-42a1-a387-380de7f5d3bd%2Fhammer.png?v=1615308683807" alt="hammer" id="box">
<div id="OBJect"></div>
</div>
<br><br>
<div id="xaxis"></div>
<div id="yaxis"></div>
<div id="rotate"></div>
<script>
//script would go here
</script>
</body>
</html>
yeah, yeah, I know. I could definetly improve, but I only know basic things,and some of these from either Stackoverflow or w3schools, and yes, I know there is a lot of solved answers with this problem, but I get confused by them because they are too complicated for me. I just request easy, simple code to understand (if it isn't, please label things so I know).
sorry if this is too much, I just need help :/
so to do this you need to know the 4 corners of each element then you need to check if the other object is within the players bounds
they're both rectangles and to be touching 1 of these statements have to be true
the top left corner of the square is to the right of the top left corner of the player and the top left corner of the square is to the left of the top right corner of the player while the top left corner of the square is less than the y of the top side and higher than the y of the bottom side
the top right corner of the square is to the left of the top right corner of the player and the top right corner of the square is to the right of the top left corner of the player while the top right corner of the square is less than the y of the top side and higher than the y of the bottom side
same as 1 & 2 but with the bottom left and right corners
if one of the corners has the same x and y as a corner on the other object or if the position of one object is the same as the other
a second way to do this is using Pythagoras theorem to get the distance between two points
a^2 + b^2 = c^2
how that would look in code
let c = Math.sqrt(Math.pow(Math.abs(x1 - x2), 2) + Math.pow(Math.abs(x2, y2), 2))
this is a little tricky but the distance between two points is a triangle in a sense so the distance on x and y form the two legs then to get the actual distance we need the hypotenuse which is what Pythagoras theorem gets us. So to get a and b we need to get the absolute value of the first minus second x and y to get the distance on x and y then we square them with Math.pow() and add them but that gives us c^2 and we just want c so we get the square root with Math.sqrt() which gives us the distance then the one other thing we have to do is get the center of the objects to use as a and b. Since you're working with javascript on a webpage the X and Y values are for the top left corner so you need to add half the width and height to x and y appropriately to get the center of the object, then you can use the distance formula. the only problem with this approach is that it works best for circles because every point around the edge is equally distant from the center which isn't true for a square.
So personally I would use the first method, you can get the other corners by using width and height to add to the position of the top left corner to get the other positions. it's more code but more precise than distance because you're checking the bounds of each object rather than checking distance from center
I also joined today and I am 12. since the hammer is an img, you can use css:
I think your question was that you want to move the hammer, if yes:
var left = 0; /*left and top can be edited in your code but*/
var top = 0;/*you have to reset them using the code below*/
var hammer = document.querySelector('#hammer');
hammer.style.left = left + 'px';
hammer.style.top = top + 'px';
#hammer {
position: absolute;
left: 0px;
right: 0px;
}/*set left and right via js*/
<!--just add an id like #hammer to the hammer-->

Create div overlay for image based on xml attributes

I want to create a div overlay, set at 5% opacity, which creates a diagonal bounding box around each of the lines of text in this image. I have the coordinates of each of the four points I need to draw the bounding box, which are encoded as attributes in an XML element which contains the text of individual line as its data. It seems to me that since I have the x,y coordinates for the four corners, I should be able to create the overlay -- but I cannot figure out what the proper syntax would be to mark out the div. Someone suggested to me using the transform functions for CSS (which was the right call as I originally framed this question) but that sounds like I'd be basically writing eight separate pieces of css, one for each line -- which could get messy since there are potentially 118 pictures like this that I would be writing custom pieces of CSS for.
Am I wrong in thinking this can be done programmatically, and if not can someone point me at some methods for doing so?
Yes, it is possible this way, with simple html markup:
<div class="image_box" data-cords="20,50,210,50,50,250,240,250">I am the text inside the div, I can be in several lines. It is important for text stay vertical and it is important the text to follow boundary box.</div>
Than do some script magic:
$.fn.skewText = function () {
return this.each(function (i) {
var thisText = $(this);
var coords = thisText.data('cords').split(',');
/* Calculate degree */
var deg = Math.tan((coords[5] - coords[1]) / (coords[4] - coords[0])) * 57.2957795;
/* Skew pixels for calculations */
var skewVal = coords[4] - coords[0];
/* Calculate position */
var cssWidth = (coords[2] - coords[0] - skewVal) + 'px';
var cssHeight = (coords[5] - coords[1]) + 'px';
var cssTop = coords[1] + 'px';
var cssLeft = (coords[0] * 1 + skewVal) + 'px'; /* Add a half of skew */
/* Wrapp and apply styles */
thisText.wrapInner('<div class="skew_padding" />').wrapInner('<div class="skew_text" />');
var skewText = thisText.find('.skew_text');
skewText.css({
'transform': 'skew(' + deg + 'deg)',
'top': cssTop,
'left': cssLeft,
'width': cssWidth,
'height': cssHeight,
'background': 'none rgba(0,0,0,.5)'
});
/* Now skew back each letter inside */
var skewPadding = skewText.find('.skew_padding');
var letters = skewPadding.text().split(' ');
var newText = '<span>' + letters.join('</span> <span>') + '</span>';
skewPadding.html(newText);
skewPadding.find('span').css({
'display': 'inline-block',
'transform': 'skew(' + (-deg) + 'deg)'
});
});
};
$('[data-cords]').skewText();
That is possible with this css:
.image_box {
position: relative;
width: 300px;
height: 300px;
background: yellow;
}
.skew_text {
position: absolute;
}
.skew_padding {
padding: 10px;
}

Smoothing movement effect that follows mouse position

I want to create a very simple effect moving a background image when the mouse moves. For that Im recording the mouse position and using it to modify a css property:
$('#landing-content').mousemove(function(e){
var amountMovedX = (e.pageX * -1 / 6);
var amountMovedY = (e.pageY * -1 / 6);
$(this).css('background-position', amountMovedX + 'px ' + amountMovedY + 'px');
});
http://jsfiddle.net/X7UwG/580/
I want to make the background movements less aggressive, at first i though well, lets just increase the divider factor in the equation in order to make larger mouse positions lower:
http://jsfiddle.net/X7UwG/581/
The main problem with this approach is that the background is indeed moving slower BUT also very choppy (move the mouse slowly). Since we are now dividing by 100 instead of 6, the non decimal part of the result change after several pixels of movement (open console and see the result). Since background position only takes non decimal values as correct, the movement is not fluid.
I guess I have two ways of solving this, smoothing the transitions between the movements or have a different equation that transforms mouse position into background diferential position, but i cant figure out how to fix it.
The second part of the problem is to prevent the background movement to surpass the background size:
Would something like this work for you?
I simply reduced the divisor by half and increased the size of the background image to account for the movement and applied margin:0 on the body to hide the whitespace that was present in the fiddle
http://jsfiddle.net/X7UwG/582/
$('#landing-content').mousemove(function(e){
var amountMovedX = (e.pageX * -1 / 50);
var amountMovedY = (e.pageY * -1 / 50);
$(this).css('background-position', amountMovedX + 'px ' + amountMovedY + 'px');
console.log(amountMovedX);
});
body {
margin:0px;
}
#landing-content {
overflow: hidden;
background-image: url(http://i.imgur.com/F2FPRMd.jpg);
width: 100%;
background-size: 115%;
background-repeat: no-repeat;
max-height: 500px;
border-bottom: solid;
border-bottom-color: #628027;
border-bottom-width: 5px;
padding:0px;
}

Adjust position of absolute div based on its width

So I've been trying to integrate flot into some of our standard reporting stuff. I looked at some of the flot examples and cobbled together some code that generates a flot plot based on some data that we generate a report on.
From one of the flot examples, I found that you could make a tooltip appear over the graph through some javascript. It works great. My one issue, that I cannot seem to resolve, is with the tooltip. Occasionally, when the tooltip gets to be on the far right of the graph, such that it would render off the side of the page, it renders off the side of the page.
This is problematic because in order to clearly read the tooltip at that point you must scroll the page to the right, while keeping the mouse on the relevant data piece. To solve this I am trying to render the tooltip to the left of the cursor when the cursor would be past the left half of the plot area. However, I have so far only been successful at determining when the cursor is past the left half of the screen, and my attempts to reposition the div have been fruitless.
Relevant Code:
function showTooltip(x, y, msg) {
flot_tooltip = $("<div id = 'flot_tooltip'>" + msg + '</div>').css({
position: 'absolute',
display: 'none',
top: y + 5,
left: x + 5,
border: '1px solid #000',
background: '#eee',
padding: '2px',
opacity: '0.75'
}).appendTo('body').fadeIn(150)
adjustForX(flot_tooltip)
}
function adjustForX(flot_tooltip){
if ($(flot_tooltip).offset().left > window.innerWidth/2) {
//alert($(flot_tooltip).width())
//next need to adjust the left position of the element
}
}
Full Fiddle
Sorry for the long-winded explanation,
any guidance would be much appreciated.
I had the same problem on one of my pages and solved it with this code:
function showTooltip(x, y, contents) {
var params = {
position: 'absolute',
display: 'none',
border: '2px solid #333333',
'border-radius': '3px',
padding: '3px',
size: '10',
'background-color': 'lightyellow',
opacity: 0.90
};
if (x < 0.8 * $(window).width()) {
params.left = x + 20;
}
else {
params.right = $(window).width() - x + 20;
}
if (y < 0.8 * $(window).height()) {
params.top = y + 5;
}
else {
params.bottom = $(window).height() - y + 10;
}
$('<div id="tooltip">' + contents + '</div>').css(params).appendTo('body').fadeIn(200);
}
Here I compare the xand yposition values to the window size and position the tooltip to the left of the mouse position if the mouse position is near the right border and above the mouse position if it is near the bottom.

Javascript Image Pan / Zoom

By combining some CSS and Jquery UI / draggable I have created the ability to pan an image and with a little extra JS you can now zoom the image.
The problem I am having is that, if you zoom in the image's top left corner is fixed, as you would expect. What I would like is for the image to stay central (based on the current pan) so that the middle of the image stays in the middle of the container whilst getting larger.
I have written some code for this but doesn't work, I expect my maths is wrong. Could anyone help?
I want it to work like this does. When you scroll into an image it keeps the image centered based on the current pan rather than zooming out from the corner.
HTML:
<div id="creator_container" style="position: relative; width: 300px; height: 400px; overflow: hidden;">
<img src="/images/test.gif" class="user_image" width="300" style="cursor: move; position: absolute; left: 0; top: 0;">
</div>
Javascript:
$("#_popup_creator .user_image").bind('mousewheel', function(event, delta) {
zoomPercentage += delta;
$(this).css('width',zoomPercentage+'%');
$(this).css('height',zoomPercentage+'%');
var widthOffset = (($(this).width() - $(this).parent().width()) / 2);
$(this).css('left', $(this).position().left - widthOffset);
});
Long story short, you need to make a transform matrix to scale by the same amount as the image and then transform the image's position using that matrix. If that explanation is complete greek to you, look up "image transforms" and "matrix math".
The beginning of this page is a pretty good resource to start with even though it's a different programming language:
http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/geom/Matrix.html
Anyway, I've implemented those methods in some projects of my own. Here's the zoom in function from something I wrote that functions the way you want:
function zoomIn(event) {
var prevS = scale;
scale += .1;
$(map).css({width: (baseSizeHor * scale) + "px", height: (baseSizeVer * scale) + "px"});
//scale from middle of screen
var point = new Vector.create([posX - $(viewer).width() / 2, posY - $(viewer).height() / 2, 1]);
var mat = Matrix.I(3);
mat = scaleMatrix(mat, scale / prevS, scale / prevS);
point = transformPoint(mat, point);
//http://stackoverflow.com/questions/1248081/get-the-browser-viewport-dimensions-with-javascript
posX = point.e(1) + $(viewer).width() / 2;
posY = point.e(2) + $(viewer).height() / 2;
$(map).css({left: posX, top: posY});
return false;//prevent drag image out of browser
}
Note the commands "new Vector.create()" and "Matrix.I(3)". Those come from the JavaScript vector/matrix math library http://sylvester.jcoglan.com/
Then note "transformPoint()". That's one of the functions from that ActionScript link (plus hints on http://wxs.ca/js3d/) that I implemented using sylvester.js
For the full set of functions I wrote:
function translateMatrix(mat, dx, dy) {
var m = Matrix.create([
[1,0,dx],
[0,1,dy],
[0,0,1]
]);
return m.multiply(mat);
}
function rotateMatrix(mat, rad) {
var c = Math.cos(rad);
var s = Math.sin(rad);
var m = Matrix.create([
[c,-s,0],
[s,c,0],
[0,0,1]
]);
return m.multiply(mat);
}
function scaleMatrix(mat, sx, sy) {
var m = Matrix.create([
[sx,0,0],
[0,sy,0],
[0,0,1]
]);
return m.multiply(mat);
}
function transformPoint(mat, vec) {
return mat.multiply(vec);
}

Categories