How to limit interactable section of website with JS? - javascript

Take for example an html canvas that is centered in the middle of the page with a width and height smaller than the page itself, so there is a rectangular canvas in the middle (sectioned off by an outline).
How would I make this section of the page, the area contained in this rectangle, the interactable part of the page itself?
I have the following code:
canvas.html
<html>
<head>
<meta charset="utf-8">
<title>Graphs</title>
<link rel="stylesheet" href="index.css">
<script type="module" src="application.js"></script>
</head>
<body>
<canvas id="appCanvas" style="border:1px solid #000000;">
</canvas>
</body>
</html>
index.css
canvas {
padding: 0;
margin: auto;
display: block;
width: 60%;
height: 80%;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
application.js
function resize() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
}
window.onresize = resize;
resize();
application.js also includes a check for mouseup, that draws a circle at the point where the mouse was clicked.
With the given code, I have as mentioned, a box in the middle, however clicking outside of this box still creates a circle. The circle is still made inside the box, it is just projected inside of it. So clicking the top left of the page adds a circle to the top left of the box, and etc.
How would I make it so only clicking in the box makes the circles appear, that is, no projection is occurring (i.e clicking top left of box creates circle at top left of box)?

If you add the onmouseup eventHandler directly on the canvas only clicks inside the canvas will be registered.
The mouseup event is fired at an Element when a button on a pointing device (such as a mouse or trackpad) is released while the pointer is located inside it.
Element: mouseup event
Otherwise you could look at the target of the mouseup event.
document.body.onmouseup = (e) => {
if(e.target.id === 'appCanvas'){
console.log("clicked canvas with no projection");
}
}
canvas {
padding: 0;
margin: auto;
display: block;
width: 60%;
height: 80%;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
<html>
<head>
<meta charset="utf-8">
<title>Graphs</title>
<link rel="stylesheet" href="index.css">
<script type="module" src="application.js"></script>
</head>
<body>
<canvas id="appCanvas" style="border:1px solid #000000;">
</canvas>
</body>
</html>

Related

beginner JavaScript background

I am having is trying to have a grey background, but with text over top of it rather than before or after the grey square.
Here is my code, an HTML document with JS and CSS integrated:
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
/* Change svg background color. */
.area {
background-color: #75738a;
}
</style>
</head>
<body>
<svg width="2000px" height="2000px" class="area">
<script>
write("Power up to the top");
</script>
</svg>
<script>
// start game "press any to continue"
document.addEventListener('keypress', (event) => {
}, false);
</script>
</body>
</html>
Previously, I was drawing a square and expecting to be able to put text on it. I realized instead of setting it to print a square, I needed to set the background image in HTML, and use CSS to center and fullscreen it.
<body>
<img src="gymbackground.jpg" id="bg" alt="">
<body>
HTML^
<style>
#bg {
position: fixed;
top: 0;
left: 0;
/* Preserve aspet ratio */
min-width: 100%;
min-height: 100%;
}
</style>
CSS within HTML^

How can i write text over a canvas animation

So i'm making a online profile for myself, and i was doing research on how to make the landing page as attractive as possible. Came across HTML5 Canvas, did some research and experimentation on making an interactive background, and this is the result (in codepen).
Now, i would like to write my name in the middle of the canvas with the text infront of the animation.
The animation gets called in a recursive loop and the initialization function gets called when the page is resized or refreshed.
Problem is, i can't get the text infront, and for some odd reason, my text shrinks when the page is resized.
Here is my pen
https://codepen.io/hamza-tariq-khan/pen/mzKMNd
<!doctype html5>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Canvas Resize</title>
<style>
canvas{
/* border: 1.5px solid black; */
/* background-color: red; */
display: block;
}
body{
margin: 0;
overflow-x: hidden;
}
.wrapper{
margin : 20px;
}
</style>
</head>
<body>
<canvas></canvas>
<script src="script.js"></script>
<div class="wrapper">
<h1>This is a sample sentence</h1>
</div>
</body>
</html>
and this is an idea of what i want to achieve. (the writing of Mathew williams infront of the moving background)
http://findmatthew.com
If I were you, I would skip rendering text in the canvas and apply some CSS rules to the div to make it show up on top instead. The CSS approach improves performance and also improves accessibility. A blind person using a screen reader will be able to figure out what's in the div, but reading text in the canvas is not supported. Most importantly, it's a lot easier to reason about HTML and CSS than it is to reason about text rendering in a canvas element. How often will you do that? When you come back to change the code in a month, six months, or a year, it will be easier to change the HTML/CSS than it will be to think through the canvas rendering logic all over again!
To do this, use the following CSS for div wrapper:
.wrapper{
position: absolute;
top: 0px;
color: red;
font-size: 60px;
margin : 20px;
}
position: absolute allows the div to overlap the canvas, and properties top, bottom, left and right allow you to control how far the div is offset from the edges of its parent (in this case wrapper is a child of body). I adjusted color and font-size just to make it obvious that it works.
And here is a link to a working example: https://codepen.io/anon/pen/LqoroR
var canvas = document.getElementById("dm_graphs");
var ctx = canvas.getContext("2d");
ctx.fillStyle = "blue";
ctx.fillRect(0, 0, canvas.width, canvas.height);
<style>
body,
canvas,
html {
font: 24px sans-serif;
height: 100hv;
width: 100%;
margin: 0;
padding: 0;
background: #888;
color: #135;
overflow: hidden
}
#fs {
position: relative
}
#txt,
canvas {
position: absolute
}
#txt {
color: yellow;
margin: 50px;
font: 24px subpixel-antialiased Noto Sans Samaritan;
background: transparent
}
</style>
<body>
<div id="fs">
<canvas id="dm_graphs" width="400" height="300"></canvas>
<div id="txt">This is a text over a canvas.</div>
</div>
</body>

three.js dom element makes the whole page gets larger

I'm trying to build a 3D viewer with three.js, that has full height but leaves space for a side panel. The vertical layout works as expected, but as soon as I append the render's dom element, a horizontal scroll bar appears.
Attached is a minimal working example. I would expect to just see the (black) canvas element and the red body. But after v.append(renderer.domElement), the page gets larger (filled with blue, html element) and a horizontal scroll bar appears. It seems the page is larger than its body.
See https://jsfiddle.net/5jnvt4jh.
Has anybody an idea, what may be happening there? I couldn't find any margin or padding with Chrome and Firefox. Thanks :).
MWE
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<style>
html {
background-color: blue;
}
body {
margin: 0px;
height: 100vh;
background-color: red;
}
#viewer {
height: 100%;
width: 80vw;
background-color: green;
}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/86/three.min.js"></script>
</head>
<body>
<div id="viewer"></div>
<script>
var v = document.getElementById('viewer');
var renderer = new THREE.WebGLRenderer();
v.append(renderer.domElement);
renderer.setSize(v.clientWidth, v.clientHeight);
</script>
</body>
</html>
Change style of body to:
body {
margin: 0px;
height: 100vh;
background-color: red;
overflow:hidden;
}
jsfiddle: https://jsfiddle.net/raushankumar0717/5jnvt4jh/2/

How do you capture a click on an HTML element that has a CSS 3D transform away from the screen?

I have a div that rotates around the x-axis, around its center, so that the top half "falls away" from the screen while the bottom half comes toward the screen. When I try to capture the onclick event, I only get it from the div if I click on it below its centre. If I click on it above its center, the containing div receives the onclick event.
I've tried moving the div to the front with z-index and translateZ(), but still the containing div receives the onclick when I click on the top half of the div.
How can I get the div to receive the onclick event, regardless of where on the div it is clicked?
Here's a sample that demonstrates the problem:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script type="text/javascript">
function onMainClick() {
console.log('onMainClick()');
}
function onContainerClick() {
console.log('onContainerClick()');
}
</script>
<title>Click Test</title>
</head>
<body>
<div onclick="onContainerClick()" style="width: 200px; height: 200px; background-color: burlywood">
<div onclick="onMainClick()" style="width:100%; height: 100%; background-color: grey; -webkit-transform: perspective(1000px) rotateX(45deg)"></div>
</div>
</body>
</html>
onMainClick() is not called when clicking the top half of the grey div.
Built the case in a jsfiddle, I don't exactly know what the perspective rotation does, but the solution is to give the other div a z-index of -1...
CSS
#div1 {
width: 200px;
height: 200px;
background-color: burlywood;
z-index: -1;
}
#div2 {
width: 100%;
height: 100%;
background-color: grey;
-webkit-transform: perspective(1000px) rotateX(45deg);
}
Update: correct jsfiddle link...

How to place one element exactly to the same visible position, as another?

I have two elements "src" and "dest"
"src" and "dest" are in different DOM-nodes, that can not have the same parent.
I need to place "src" element in the same visible position, as "dest".
"src" element must also have the same sizes, as "dest".
I have following code for case, when "src" and "dest" having the same parent:
src.css("position", "absolute");
src.css("top", dest.offset().top);
src.css("left", dest.offset().left);
src.width(dest.width());
// Show "src" element, instead of "dest". "src" must be in the same visible position, as "dest"
dest.css("opacity", 0);
src.show();
Unfortunately, it does not works. "src" element has displacement to bottom and left, for that i cannot find the reason.
Maybe, i do something wrong ...
How to do it right for two cases ?
"src" and "dest" having the same grand-parent
"src" and "dest" does't having the same parent. Maybe grand-grand-grand-parent is the common for both.
Update:
I have arranged a simple HMTL document, that does a simple visual swapping of one element with another:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>MacBlog</title>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.4.2.min.js" charset="utf-8"></script>
<style type="text/css" media="screen">
.dest {
background-color: #0cf;
width: 480px;
height: 320px;
}
.src {
background-color: #09c;
width: 1024px;
height: 768px;
}
</style>
<script type="text/javascript" charset="utf-8">
jQuery(function($){
// Common items, to deal with
var src = $(".src");
var dest = $(".dest");
// Setup
src.hide();
// Interaction
dest.click(function(){
src.width(dest.width());
src.height(dest.height());
src.offset(dest.offset());
dest.hide();
src.show();
});
});
</script>
</head>
<body>
<div>
<!--On clicking, this element should visually be swapped by ".src" element -->
<div class="dest"><p>dest</p></div>
<div class="src"><p>src</p></div>
</div>
</body>
</html>
It does not work correctly. After "swapping", "src" element has a strange displacement to top-left direction on ~30 pixels.
I use latest version of Safari 5, if i makes sense.
Update 2:
Unfortunately, this also does not works. I updated my example:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>MacBlog</title>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.4.2.min.js" charset="utf-8"></script>
<style type="text/css" media="screen">
div {
margin: 0;
padding: 0;
}
.holder {
position: relative;
top: 40pt;
left: 40pt;
border: black solid thin;
}
.dest {
background-color: #0cf;
width: 480px;
height: 320px;
}
.src {
background-color: #09c;
width: 1024px;
height: 768px;
}
</style>
<script type="text/javascript" charset="utf-8">
jQuery(function($){
// Common items, to deal with
var src = $(".src");
var dest = $(".dest");
// Setup
src.hide();
// Interaction
dest.click(function(){
src.css("position", "absolute");
src.width(dest.width());
src.height(dest.height());
src.offset(dest.offset());
dest.hide();
src.show();
});
});
</script>
</head>
<body>
<div class="holder">
<!--On clicking, this element should visually be swapped by ".src" element -->
<div class="dest"><p>dest</p></div>
<div class="src"><p>src</p></div>
</div>
</body>
</html>
I tested it here:http://jsfiddle.net/YEzWj/1/
Using your second example make your CSS like this:
div {
position:relative;
margin: 0;
padding: 0;
}
.holder {
position: relative;
top: 40pt;
left: 40pt;
border: black solid thin;
}
.dest {
position:absolute;
background-color: #0cf;
width: 480px;
height: 320px;
}
.src {
background-color: #09c;
width: 1024px;
height: 768px;
}
EDIT: After playing around with it some, it did not work in all circumstances. I decided to change the javascript. Note: My example toggles the display of src and dest within the holder, making holder the same size as dest so the border shows outside the dest and src.
jQuery(function($){
// Common items, to deal with
var src = $(".src");
var dest = $(".dest");
var holder=$(".holder");
holder.width(dest.width());
holder.height(dest.height());
// Setup
src.hide();
// Interaction
dest.click(function(){
src.show();
src.css("position", "absolute");
src.width(dest.width());
src.height(dest.height());
src.offset(dest.offset());
dest.hide();
});
src.click(function(){
dest.show();
src.hide();
});
});
EDIT2: Remove the src.click() event if you wish it to NOT go back to the dest on src click.
You need to make the dest element absolute, otherwise the top and left offsets will not apply.
src.css('position', 'absolute'); // ensure position is set to absolute
src.offset(dest.offset());
Also, elements like p and body will have default stylesheets depending on browser. So try to supply a reset style to make things consistent:
p {
margin: 0;
}
body {
margin: 0;
padding: 0;
}
You can call the offset function to set the offset and handle different parents correctly, like this:
dest.offset(src.offset());

Categories

Resources