How can i write text over a canvas animation - javascript

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>

Related

How to limit interactable section of website with JS?

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>

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/

Layer Text Between Background Color Background Image

I have a block of text and it want it to be above the block's background color and below the block's background image. I know I could just create multiple blocks and z-index them. I'm wanting to keep the code as clean as possible and not have a bunch of unnecessary stuff.
I'm guessing that the answer is "no", but maybe you guys know something I do (maybe a nifty new background property or JavaScript function).
HTML Code:
<section role="main" id="content">
<h1 class="pageheading">Home Page</h1>
</section>
CSS Code:
#content {
background-color:#69583b;
background-image:url(tattoo-256x256.png);
background-position:center bottom;
background-repeat:no-repeat;
}
Obviously, as it stands, the text "Home Page" sits on top of the image.
The logical thought would simply be to use <img> and position:absolute it, but, again, that's not my intention. I know multiple, other, ways it can be done. I'm just trying to find out if I can do it, this way.
You could do it with a CSS pseudo class. (I've added in opacity just as part of the demo):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<style>
#content {
background-color:#69583b;
background-position:center bottom;
background-repeat:no-repeat;
position: relative;
}
#content::after {
content: "";
position: absolute;
z-index: 2;
width: 100%;
top: 0; bottom: 0; left: 0; right: 0;
background: url(http://placehold.it/256x256);
opacity: 0.8;
}
</style>
</head>
<body>
<section role="main" id="content">
<h1 class="pageheading">Home Page</h1>
</section>
</body>
</html>

Positioning overlapping canvas

I've got a page that is supposed to display a line graph. There is a title at the top, the graph in the middle, then a table below them. It is laid out roughly like this:
<div>
<h1>Title</h1>
</div>
<div>
<canvas1></canvas>
<canvas2></canvas>
</div>
<div>
<table></table>
</div>
Right now each of the 'div' blocks are staying separate from each other, which is good. However, the two canvas's, despite having different z-index values, are next to each other instead of stacking on top. I've read that their position values should both be set to absolute, but whenever I do this, the table immediately moves on top of the canvas.
What position and display values do I need to set to the div's and the elements inside them to get the canvasses on top of each other (both are the same dimensions) without anything else stacking on top of their div?
Edit: Here's a fiddle
HTML:
Wrap the 2 canvases inside a wrapper div.
<div id="wrapper">
<canvas id="canvasBottom" width=300 height=200></canvas>
<canvas id="canvasTop" width=300 height=200></canvas>
</div>
CSS:
Position the 2 canvases at the same top & left relative to the wrapper div.
#wrapper{
position:relative;
width:300px;
height:200px;
}
#canvasTop,#canvasBottom{
position:absolute; top:0px; left:0px;
width:300px;
height:200px;
}
If you set the "position" attribute of your two canvas to "absolute", then the two canvas would stick to the parent element, say, your div.
The reason why the table moves on top of your canvas is that the table, in a sense, "neglected" your canvas and was located as if there is no canvas.
What you should do is keep the absolute position value of the canvas and set the "top" value of table to the height of your canvas, then the table would be just beneath the canvas.
let me give you an example:
<!DOCTYPE html>
<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>Animal World</title>
<style>
canvas {
width: 50%;
height: 100px;
position: absolute;
}
#dog {
z-index: 1;
}
#cat {
z-index: 0;
background-color: blue;
}
table{
background-color: rgb(196, 255, 216);
position: relative;
top: 100px;
border-collapse: collapse;
}
caption{
font-weight: bolder;
font-size: 2em;
background-color: rgb(196, 255, 216);
border: 1px groove lightblue;
}
td,th{
border: 1px groove lightblue;
}
</style>
</head>
<body>
<div>
<h1>Animal</h1>
</div>
<div id = "canvas">
<canvas id = "dog"></canvas>
<canvas id = "cat"></canvas>
</div>
<script>
var dog = document.getElementById('dog');
var cat = document.getElementById('cat');
var dog_ctx = dog.getContext('2d');
var cat_ctx = dog.getContext('2d');
dog_ctx.fillStyle = "red";
dog_ctx.fillRect(20, 20, 20, 20);
</script>
<div class = "table">
<table>
<caption>Animal</caption>
<tr>
<th>Dog</th>
<th>Panda</th>
<th>Cat</th>
</tr>
<tr>
<td>middle</td>
<td>large</td>
<td>small</td>
</tr>
</table>
</div>
</body>
</html>
Definitely use flex-box to float stacked canvases to perfection. Note: you'll need to use "display: flex" for the entire layout including HTML and BODY elements, plus any parent containers/ divs.
#canvasWrapper {
align-items: center;
display: flex;
height: 100%;
justify-content: center;
}
canvas {
position: absolute;
}

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