p5.js element on canvas positions - javascript

I'm coding a p5.js game and i have to draw a button, an input and a p html elements over my canvas. I wanna have all this elements centered relative to the canvas.
I tried this solution without success:
var gameCanvas = createCanvas(600, 600);
gameCanvas.parent("game-container");
input = createInput();
input.position(280, 300);
input.parent("game-container");
I have a div with game-cointainer id and this work until i center the div by css. When I center the div the canvas get centered but the input position remain relative to the div and not to the canvas.
So this is a responsive html page powered with MDL framework. If i center the canvas with "mdl-layout-spacer" div before and after my "game-container" div, the canvas stay to the center but input remain to left (300 px from the left of my game-container div).
If i center the game-container div with mdl col offset both inout and canvas are centered but i lose the responsive center. Anyone that is good with p5.js know how i can solve this problem?

This is because you are loading the input object before you load the CSS page. Either put the script tag after the css tag, or put
input = createInput();
input.position(280, 300);
input.parent("game-container");
into your setup() function.

Your problem is that the p5 button is position absolute
Solution:
Create a div called container. Apply some flexbox so the children are centred
#container {
min-height: 100vh; /*vertical center*/
min-height: -webkit-fill-available; /*mobile viewport bug fix*/
display: flex;
align-items: center;
justify-content: center;
position: relative;
}
Now add a div sketch to your container. The sketch will be centred vertically and horizontally. It's important to add this div because its size will be equal to your canvas size. You can then add the button to this canvas. The sketch div needs position: relative to override the absolute position of the button
#sketch {
position: relative;
}
Now you can create your canvas and button. Then add both of them to the sketch
function setup() {
let canvas = createCanvas(100, 100);
canvas.parent("sketch");
background(0);
button = createButton('click me');
button.mousePressed(changeBG);
button.position(0, 0);
button.parent("sketch");
}
function changeBG() {
let val = random(255);
background(val);
}
The result is a vertically and horizontally centred sketch with a button relative to the sketch top left. Please try the example below. I coloured the divs for you. Container:red, Sketch:green, Canvas: grey values. You won't see much green because its covered with the Canvas
function changeBG() {
let val = random(255);
background(val);
}
function setup() {
let canvas = createCanvas(100, 100);
canvas.parent("sketch");
background(0);
let button = createButton('click me');
button.position(0, 0);
button.mousePressed(changeBG);
button.parent("sketch");
}
body {
margin: 0;
}
#container {
min-height: 100vh; /* mobile viewport bug fix */
min-height: -webkit-fill-available;
display: flex;
align-items: center;
justify-content: center;
position: relative;
background-color: red;
}
#sketch {
position: relative;
background-color: green;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.min.js" integrity="sha512-N4kV7GkNv7QR7RX9YF/olywyIgIwNvfEe2nZtfyj73HdjCUkAfOBDbcuJ/cTaN04JKRnw1YG1wnUyNKMsNgg3g==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
</head>
<body>
<div id="container">
<div id="sketch">
</div>
</div>
</body>
</html>
I hope I was able to help you guys. Have a nice day

Related

why html5 canvas is not full screen when vertical scrollbar appears

I'm using a full screen canvas as background of the first section of my page. But as soon as I add the second section and vertical scrollbar appears, the height of canvas reduces a little bit and a gap appears. here's my code:
P.S: Sorry, my code contained bugs, I fixed them. now you can see the red gap.
var canvas = document.getElementById('canvas')
var c = canvas.getContext('2d')
scaleCanvas()
window.addEventListener("resize", scaleCanvas)
function scaleCanvas() {
canvas.width = window.innerWidth
canvas.height = window.innerHeight
c.fillStyle = 'black'
c.fillRect(0, 0, canvas.width, canvas.height)
}
* {
box-sizing: border-box;
max-width: 100%;
}
body {
margin: 0;
padding: 0;
}
#first-section {
position: relative;
min-height: 100vh;
background-color: red; /* to see the gap */
}
#content {
position: relative;
z-index: 2;
}
#second-section {
min-height: 100vh;
background-color: blue;
}
#canvas {
display: block;
padding: 0;
margin: 0;
border: none;
position: absolute;
top: 0;
left: 0;
z-index: 1;
}
<div id="first-section">
<canvas id="canvas"></canvas>
<div id="content">content</div>
</div>
<div id="second-section"></div>
Assuming you mean full screen, and not full page. The two are very different.
If you mean full page then the link to the Screen API will also give you details on obtaining the page size.
Size full screen canvas.
The problem is that you have content that extends outside the page width and height (innerWidth, innerHeight)
The elements with ids first-section, content, and second-section must be inside the display area or else you will get a scroll bar. The scroll bar will change the innerWidth, innerHeight values subtracting the scrollbar width or height depending on which is visible.
To prevent scroll bars the best option is to keep all content inside innerWidth, and innerHeight
Full screen with scroll bars.
If you want have the scroll bars and you are using full screen you can use the Screen API to get the width and height of the display in pixels. You can set the canvas size to match the screen without the scroll bars effecting its size.
Note Do read the provided link to Screen as what defines the screen may not be as expected. EG more than one monitor, or device orientation will effect how you use the API.
Basic example
Thus when in full-screen mode you can set the canvas size and ignore scroll bars with
function sizeFullScreenCanvas() {
canvas.width = screen.width;
canvas.height= screen.height;
}

Get a Circles Width Defined by a Percent in Pixels and apply them to the Height Value

After 4 hours of trial and errors, I cannot find a way to get the width of the circle that is defined by a percent and convert it to pixels and make the circles height the same size as the width in pixels. Below is what I have right now. (I have tried many variations of this but cannot figure it out) Right now it only works on my screen. I try it on other devices and the height is just not right. This button is created onload.
Example: Circle Width = 12% , the Pixel Value of 12% on a screen is "70px". So somehow make Circle Height = 70px.
<!DOCTYPE html>
<head>
<title>Circle Test</title>
<meta charset='UTF-8'>
<script type="text/javascript" src="/js/fs"></script>
</head>
<body>
</body>
</html>
// Creates a button
var mainButton = document.createElement("button");
mainButton.style.width = "10%";
// Get the Screens Avaliable Width and Get 10% of it and convert it to pixels
var wad = screen.availWidth * .1 + "px";
// Thinking this would return the pixel amount the circle button is, but it only works on the regular screen and not when resized. It also does not work for mobile.
console.log(wad);
mainButton.style.height = wad;
You set the width of your button to 10% of its containing block's width, and the height to 10% of the width of one of
The available area of the rendering surface of the output device, in CSS pixels.
The area of the output device, in CSS pixels.
The area of the viewport, in CSS pixels.
It's very likely that these are measurements of two different things, or that resizing the window will affect one but not the other. Fortunately, CSS has a unit for "percentage of the window's width": vw. Set your button's height and width in vw units, and you don't need any JavaScript:
button {
width: 10vw;
height: 10vw;
border-radius: 50%;
}
<button>Go</button>
If you really meant that the button is 10% as wide as its container, even if its container isn't as wide as the whole window, you can use the padding-bottom technique detailed in this answer. Unlike height, percentages in padding refer to the width of the containing block:
.wrapper {
width: 40%; /* here I use 40% instead of 10% for aesthetics */
padding-bottom: 40%; /* should match width */
position: relative;
}
.wrapper > button {
display: block;
position: absolute;
width: 100%;
top: 0;
bottom: 0;
border-radius: 50%;
}
/* the rest is just to make figuring out
the exact width of the button difficult */
body {
display: flex;
align-items: stretch;
height: 90vh;
}
body > div {
flex: 1 1 0;
background: rebeccapurple;
margin: 0 4px;
}
<div>
<div class="wrapper"><button>Go</button></div>
</div>
<div></div>
<div></div>
And finally, just for completeness, if you really must get the computed width from JavaScript, you can use window.getComputedStyle:
let button = document.querySelector('button');
let width = window
.getComputedStyle(button)
.getPropertyValue('width');
console.log(button.style.height = /* DO NOT DO THIS */ width);
button {
width: 40%;
border-radius: 50%;
}
/* the rest is just to make figuring out
the exact width of the button difficult */
body {
display: flex;
align-items: stretch;
height: 90vh;
}
body > div {
flex: 1 1 0;
background: rebeccapurple;
margin: 0 4px;
}
<div>
<button>Go</button>
</div>
<div></div>
<div></div>
If you try putting that into a resize handler, though, performance will suffer.

How to horizontally centre a stars rating image within a Bootstrap column?

I have a stars rating image which is controlled using Javascript and CSS to display a rating out of five (in quarter steps, twenty is the dimensions of the star in pixels):
$.fn.stars = function() {
return $(this).each(function() {
var val = Math.round(parseFloat($(this).html())*4)/4;
var size = Math.max(0, (Math.min(5, val)))*20;
var $span = $("<span />").width(size);
$(this).html($span);
});
}
$(function() {
$("#avg-rating").html('<span class="stars">{{ avg_rating }}</span>');
});
span.stars, span.stars span {
display: block;
background: url(stars.png) 0 -20px repeat-x;
width: 100px;
height: 20px;
}
span.stars span {
background-position: 0 0;
}
The image is displayed in a Bootstrap column:
<div class="container-fluid">
<div class="text-center">
<div class="row">
<div class="col-xs-6"><div id="avg-rating"></div></div>
<div class="col-xs-6">blah blah</div>
</div>
</div>
</div>
The image is currently left justified in its column. I have tried several things in CSS to align the image horizontally in its column, such as adjusting the display attribute or background position. But I am unable to move the image without upsetting the functionality of the image manipulation.
Update
Using inline-block instead of block messes up the placement of the stars (image should show four lighted stars out of five):
span.stars, span.stars span {
display: inline-block;
...
Your problem seems to stem from here:
span.stars, span.stars span {
display: block;
background: url(stars.png) 0 -20px repeat-x;
width: 100px;
height: 20px;
}
You've set the star container to 'display: block' which makes it take up the whole line. You want it to be an inline-block with a width smaller than the full-width available so that it can be centred.
Here is an example of how it would work:
https://jsfiddle.net/f6L8gr1b/2/
If your elements with class "col-xs-6" are supposed to be next to each other horizontally, you can use inline-block.
.col-xs-6 {
display: inline-block;
}
The div elements default to block which places them on a new line.

Clipping a site display with an overlay div in a given viewport

I am querying how it is possible to have a site, for arguments sake StackOverflow, where an overlay div can hide all of the content apart from what is inside the div. I suppose like a camera, you can only see whats in the viewfinder, not outside of it. I want for the moment for the viewfinder to be fixed.
I found: Fiddle
which is close, but not quite. I have tried to google and ask friend devs but no luck in the resource department. Anyone got any ideas to get me started?
<html>
<div class="content">
<h1>All the page content divs</h1>
</div>
<div id="viewport-window"></div>
</html>
You can do this by applying a clip-path style to the main element you want the overlay to be over (for instance body if you want the whole page). You could possibly also use clip for more browser support, but do keep in mind it is being deprecated.
Demo
Has a static clip-path, but when moving mouse around it will change to a 200x200 viewport that follows the mouse
jQuery(document).mousemove(function(e){
var width = jQuery(document).width();
var height = jQuery(document.body).height();
var viewW = 200;
var viewH = 200;
var top = e.pageY - (viewH/2);
var right = (width-e.pageX) - (viewW/2);
var bottom = (height-e.pageY) - (viewH/2);
var left = e.pageX - (viewW/2);
var style = "inset("+top+"px "+right+"px "+bottom+"px "+left+"px)";
jQuery(document.body).css({
"-webkit-clip-path":style,
"-moz-clip-path":style,
"clip-path":style
});
});
body {
-webkit-clip-path:inset(20px 200px 200px 40px);
-moz-clip-path:inset(20px 200px 200px 40px);
clip-path:inset(20px 200px 200px 40px);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<img src="https://placekitten.com/g/500/500" />
Actually, you can do this without an "overlay" element.
Just use a giant box-shadow and a high z-index.
In this example I've used a :hover and the 'overlay` is slightly transparent.
.wrapper {
width: 80%;
margin: auto;
text-align: center;
}
.box {
width: 100px;
height: 100px;
margin: 1em;
display: inline-block;
vertical-align: top;
background: plum;
position: relative;
}
.box:hover {
box-shadow: 0 0 0 10000px rgba(0, 0, 0, 0.75);
z-index: 9999;
}
<div class="wrapper">
<div class="box">Lorem ipsum.</div>
<div class="box">Lorem ipsum.</div>
<div class="box">Lorem ipsum.</div>
</div>
Of course, this effect is purely visual the other elements are still accessible.
You can also do that in 2 steps for example:
First, create a div to overlay entire page and hide everything.
Second, create a clone of your div(to be shown) with absolute position which has the same coordinates of the original location, and increase its z-index.
So, the logic is to hide everyting and show what you want over it. You could also visualize it with css or jquery animations.

How to fill the browser window with a canvas element without creating scroll bars?

I have a problem to get my window size, I try this code:
Javascript
var game;
function game() {
this.canvas = document.getElementById('canvas');
this.canvasWidth = window.innerWidth;
this.canvasHeight = window.innerHeight;
this.initCanvas = function() {
this.canvas.style.width = this.canvasWidth + "px";
this.canvas.style.height = this.canvasHeight + "px";
}
this.run = function() {
this.initCanvas();
}
}
game = new game();
game.run();
I also have
CSS
html, body {
padding: 0;
margin: 0;
}
I only have a canvas in my body.
Problem is, that I have a vertical and horizontal scroll bar. This means the size of canvas is too large. How to make it of the window size without the scroll bars appearing?
It looks like you're just trying to make your canvas have a width and height of 100%. You can do this with just css:
HTML
<body>
<canvas id="canvas"></canvas>
</body>
CSS
body, html {
height: 100%;
width: 100%;
margin: 0px;
}
canvas {
background: #ffcccc;
height: 100%;
width: 100%;
display: block;
}
​
Demo
Or if you want to use your code but get rid of the scroll bars on the window, you need to specify block on the canvas tag.
CSS
canvas {
display: block;
}
Demo
When you use CSS to style your <canvas> element it will get scaled instead of sized. Be sure to set the .width and .height properties on the canvas element instead (ie canvas.width not canvas.style.width).
jsfiddle example
In the example the first canvas element is scaled correctly, the second (using CSS) is not scaled properly. This has to do with a default canvas element size (300x150) that CSS scales.
To prevent getting scrollbars when setting the <canvas> to the full window width/height set the body to overflow:hidden; as used in the jsfiddle above.

Categories