Dropped frame even on the simpliest examples - javascript

I'm creating a canvas game and using Chrome profiler to find rendering and performance issues. But it shows lots of red block "Dropped Frame".
let canvas = document.querySelector('canvas')
let c = canvas.getContext('2d')
let dpr = window.devicePixelRatio || 1
let {width, height} = canvas.getBoundingClientRect()
canvas.width = width * dpr
canvas.height = height * dpr
c.scale(dpr, dpr)
let x = 100
let y = 100
document.body.addEventListener('mousemove', (event) => {
x = event.clientX
y = event.clientY
})
function render() {
c.fillStyle = '#9be2fe'
c.fillRect(0, 0, width, height)
c.fillStyle = '#e23521'
c.beginPath()
c.arc(x, y, 40, 0, 2 * Math.PI)
c.fill()
}
function main() {
requestAnimationFrame(main)
render()
}
main()
* {
margin: 0;
padding: 0;
}
body {
height: 100vh;
}
canvas {
width: 100%;
height: 100%;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>DEMO</title>
</head>
<body>
<canvas></canvas>
</body>
</html>
Even for most basic examples! What is wrong? And why are frames not the same size?

Related

Why does my mousefollow method not work on different browsers

Here is a link to the code pen
https://codepen.io/shahman28/pen/mdXraRE
This is a part of a larger project that I am working on. I am attempting to place circles when the mouse is clicked. As you can see in the codepen above the mouse follows well and places the circles at the correct locations, but when I try to do it in browser the cursor has an offset from the mouse and the circles are placed incorrectly. In firefox it is completely arbitrary, but in chrome it places them in the location of the cursor(which is in the incorrect location). I am recycling some code from previous projects so that is why there is the border in the html and css.
const canvas = document.getElementById('canvas1');
const ctx = canvas.getContext('2d');
points = [];
class Mouse {
constructor(c) {
this.x = 0;
this.y = 0;
this.easing = 0.05;
let rect = canvas.getBoundingClientRect();
canvas.onmousemove = e => {
this.x = e.clientX - rect.left;
this.y = e.clientY - rect.top;
}
}
}
class Point {
constructor(x, y, color) {
this.x = x;
this.y = y;
this.color = color;
}
draw() {
ctx.fillStyle = this.color;
ctx.beginPath();
ctx.arc(this.x, this.y, 5, 0, 2 * Math.PI);
ctx.stroke();
ctx.fill();
}
}
function random_hex_color_code() {
let n = (Math.random() * 0xfffff * 1000000).toString(16);
return '#' + n.slice(0, 6);
};
canvas.addEventListener('click', function(e) {
let rect = canvas.getBoundingClientRect();
x = e.clientX - rect.left
y = e.clientY - rect.top;
point = new Point(x, y, '#FF0000');
points.push(point);
})
w = canvas.width = window.innerWidth,
h = canvas.height = window.innerHeight,
mousePosition = new Mouse(canvas);
function animate() {
ctx.fillStyle = '#4A7DB9';
ctx.beginPath();
ctx.arc(mousePosition.x, mousePosition.y, 5, 0, Math.PI * 2);
ctx.closePath();
ctx.fill();
}
function handlePoints() {
for (let i = 0; i < points.length; i++) {
points[i].draw();
}
}
function render() {
ctx.clearRect(0, 0, w, h);
handlePoints();
animate();
window.requestAnimationFrame(render);
}
render();
body {
background: black;
}
#canvas1 {
border: 1px solid black;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 900px;
height: 600px;
background: white;
}
<!DOCTYPE html>
<html lang="en">
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]> <html class="no-js"> <!--<![endif]-->
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device.width, initial-scale=1.0">
<title>Tower Defense</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<button onClick="start()">Start Combat</button>
<canvas id="canvas1"></canvas>
<script src="script.js"></script>
</body>
</html>
Does anyone know how to make it so that the the cursor and placed arcs are consistent?
The problem is that at one point the canvas is set to have fixed px dimensions and at another point it is set to have the dimensions of the viewport.
This snippet removes the settings in the stylesheet and just uses viewport dimensions. It seems to work fine (tested on Windows10 Edge/Chrome and Firefox).
You need to decide which setting you want and to stick with that rather than try to use both which leads to the inconsistency.
const canvas = document.getElementById('canvas1');
const ctx = canvas.getContext('2d');
points = [];
class Mouse {
constructor(c) {
this.x = 0;
this.y = 0;
this.easing = 0.05;
let rect = canvas.getBoundingClientRect();
canvas.onmousemove = e => {
this.x = e.clientX - rect.left;
this.y = e.clientY - rect.top;
}
}
}
class Point {
constructor(x, y, color) {
this.x = x;
this.y = y;
this.color = color;
}
draw() {
ctx.fillStyle = this.color;
ctx.beginPath();
ctx.arc(this.x, this.y, 5, 0, 2 * Math.PI);
ctx.stroke();
ctx.fill();
}
}
function random_hex_color_code() {
let n = (Math.random() * 0xfffff * 1000000).toString(16);
return '#' + n.slice(0, 6);
};
canvas.addEventListener('click', function(e) {
let rect = canvas.getBoundingClientRect();
x = e.clientX - rect.left
y = e.clientY - rect.top;
point = new Point(x, y, '#FF0000');
points.push(point);
})
w = canvas.width = window.innerWidth,
h = canvas.height = window.innerHeight,
mousePosition = new Mouse(canvas);
function animate() {
ctx.fillStyle = '#4A7DB9';
ctx.beginPath();
ctx.arc(mousePosition.x, mousePosition.y, 5, 0, Math.PI * 2);
ctx.closePath();
ctx.fill();
}
function handlePoints() {
for (let i = 0; i < points.length; i++) {
points[i].draw();
}
}
function render() {
ctx.clearRect(0, 0, w, h);
handlePoints();
animate();
window.requestAnimationFrame(render);
}
render();
body {
background: black;
}
#canvas1 {
border: 1px solid black;
position: absolute;
left 0;
top: 0;
/* removed
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 900px;
height: 600px;
*/
background: white;
}
<meta name="viewport" content="width=device.width, initial-scale=1.0">
<!--<button onClick = "start()">Start Combat</button>-->
<canvas id="canvas1"></canvas>

How to translate and make canvas responsive?

I am trying to move to translate the canvas to (100,100) but it is not moving.
And the canvas is not responsive, when I try to change the size of canvas using CSS the circles are shrinking.
How can I add a button to toggle the drawing on canvas by the circle (i.e.: when button pressed don't draw then the circle should not draw on canvas, when pressed draw it should draw)
requestAnimationFrame(animate);
var ctx = canvas1.getContext('2d');
ctx.translate(100,100);
canvas1.width = innerWidth;
canvas1.height = innerHeight;
const bgCan = copyCanvas(canvas1);
const redSize = 6, blueSize = 5; // circle sizes on pixels
const drawSpeed = 1; // when button down draw speed in pixels per frame
var X = 50, Y = 50;
var angle = 0;
var mouseButtonDown = false;
document.addEventListener('mousedown', () => mouseButtonDown = true);
document.addEventListener('mouseup', () => mouseButtonDown = false);
function copyCanvas(canvas) {
const can = Object.assign(document.createElement("canvas"), {
width: canvas.width, height: canvas.height
});
can.ctx = can.getContext("2d");
return can;
}
function circle(ctx){
ctx.fillStyle = 'black';
ctx.beginPath();
ctx.arc(X, Y, redSize, 0, Math.PI*2);
ctx.fill();
}
function direction(ctx){
const d = blueSize + redSize + 3;
ctx.fillStyle = 'blue';
ctx.beginPath();
ctx.arc(d * Math.sin(angle) + X, d * Math.cos(angle) + Y, blueSize, 0, Math.PI*2);
ctx.fill();
}
function animate(){
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.drawImage(bgCan, 0, 0);
if (mouseButtonDown) {
circle(bgCan.ctx);
X += Math.sin(angle) * drawSpeed;
Y += Math.cos(angle) * drawSpeed;
} else {
angle += 0.1;
circle(ctx);
}
direction(ctx);
requestAnimationFrame(animate);
}
#canvas1{
position: absolute;
top:0;
left: 0;
width: 100%;
height: 100%;
border-width: 1px;
border-style: solid;
border-color: Black;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Canvas basics</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<canvas id="canvas1"></canvas>
<input onclick="change()" type="button" value="Write" id="mybutton1"></input>
<script src="script.js"></script>
</body>
</html>
the translate(100, 100) gets reset by new width/height of the canvas. It just needs to be executed after width/height is set
The easiest way is to have a window resize listener and update canvas style width/height
I'm not sure why, but for some reason canvas has a higher z-index therefor button's onclick() never fired
In the code below I've added boundaries restriction, it's affected by translate(100, 100).
requestAnimationFrame(animate);
var ctx = canvas1.getContext('2d');
canvas1.width = innerWidth;
canvas1.height = innerHeight;
ctx.translate(100, 100);
const bgCan = copyCanvas(canvas1);
const redSize = 6,
blueSize = 5; // circle sizes on pixels
const drawSpeed = 1; // when button down draw speed in pixels per frame
const drawButton = document.getElementById("mybutton1");
var draw = true;
var X = 50,
Y = 50;
var angle = 0;
var mouseButtonDown = false;
document.addEventListener('mousedown', onMouseEvent);
document.addEventListener('mouseup', onMouseEvent);
function copyCanvas(canvas) {
const can = Object.assign(document.createElement("canvas"), {
width: canvas.width,
height: canvas.height
});
can.ctx = can.getContext("2d");
return can;
}
function circle(ctx, mousedown) {
if (mousedown && !draw)
return;
ctx.fillStyle = 'black';
ctx.beginPath();
ctx.arc(X, Y, redSize, 0, Math.PI * 2);
ctx.fill();
}
function direction(ctx) {
const d = blueSize + redSize + 3;
ctx.fillStyle = draw ? 'blue' : 'red';
ctx.beginPath();
ctx.arc(d * Math.sin(angle) + X, d * Math.cos(angle) + Y, blueSize, 0, Math.PI * 2);
ctx.fill();
}
function animate() {
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.drawImage(bgCan, 0, 0);
if (mouseButtonDown) {
circle(bgCan.ctx, mouseButtonDown);
const x = X + Math.sin(angle) * drawSpeed,
y = Y + Math.cos(angle) * drawSpeed;
if (x > (blueSize + redSize) * 2 && x < canvas1.width - (blueSize + redSize) * 2 &&
y > (blueSize + redSize) * 2 && y < canvas1.height - (blueSize + redSize) * 2)
{
X = x;
Y = y;
}
} else {
angle += 0.1;
circle(ctx);
}
direction(ctx);
requestAnimationFrame(animate);
}
function onMouseEvent(e) {
if (e.target === drawButton) {
if (e.type == "mouseup")
{
draw = !draw;
document.getElementById("mybutton1").value = draw ? "Write" : "Move";
}
return;
}
mouseButtonDown = e.type == "mousedown";
}
window.addEventListener("resize", handleResize)
function handleResize ()
{
const ratio = canvas1.width / canvas1.height;
let h = window.innerHeight,
w = h * ratio;
if (w > window.innerWidth) {
w = window.innerWidth;
h = w / ratio;
}
canvas1.style.width = w + 'px';
canvas1.style.height = h + 'px';
};
handleResize(); // First draw
#canvas1 {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border-width: 1px;
border-style: solid;
border-color: Black;
z-index: -1; /* let other elements receive events */
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Canvas basics</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<canvas id="canvas1" scaleMode='fill'></canvas>
<input type="button" value="Write" id="mybutton1" />
<script src="script.js"></script>
</body>
</html>

How do you draw a line from the last position of the mouse to the present position of the mouse?

So, I'm creating some drawing maker thing, but when I move the mouse it doesn't draw circles in a line. I don't know how to say it well, but I want it to draw a line from point A (last position of mouse) to point B (present position of mouse).
Start drawing here and you will understand:
const c = document.getElementById('c')
const ctx = c.getContext('2d')
c.height = window.innerHeight
c.width = window.innerWidth
function pen(e, colorHEX) {
let mouseX = e.clientX
let mouseY = e.clientY
ctx.fillStyle = colorHEX
ctx.beginPath()
ctx.arc(mouseX, mouseY, 2, 0, Math.PI * 2)
ctx.fill()
ctx.closePath()
}
$('body').mousedown(function(eObj){
$('body').mousemove(function(e) {
pen(e, '#000000')
})
})
$('body').mouseup(function(eObj) {
$('body').unbind('mousemove')
})
body {
margin: 0;
overflow: hidden;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link href="style.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<canvas id="c"></canvas>
<script type="text/javascript" src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script src="script.js"></script>
</body>
</html>
I think you're trying to draw a contiguous line (you don't need to do that by painting circles). You'll need to store the last mouse position, and then draw a line from there to the current mouse position.
const c = document.getElementById('c')
const ctx = c.getContext('2d')
c.height = window.innerHeight
c.width = window.innerWidth
let lastPos // state variable
function pen(e, colorHEX) {
const pos = {x:e.clientX, y: e.clientY}
lastPos = (lastPos || pos) // Default to current pos
ctx.beginPath()
ctx.strokeStyle = colorHEX
ctx.lineWidth = 1
ctx.moveTo(lastPos.x, lastPos.y)
ctx.lineTo(pos.x, pos.y)
ctx.stroke()
ctx.closePath()
// Update the state variable
lastPos = pos
}
$('body').mousedown(function(eObj){
$('body').mousemove(function(e) {
pen(e, '#000000')
})
})
$('body').mouseup(function(eObj) {
$('body').unbind('mousemove')
lastPos = undefined
})
body {
margin: 0;
overflow: hidden;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link href="style.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<canvas id="c"></canvas>
<script type="text/javascript" src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script src="script.js"></script>
</body>
</html>
You can use the lineTo method
To make it move while you are dragging the line will take an extra script that includes angles and math.
const c = document.getElementById('c')
const ctx = c.getContext('2d')
c.height = window.innerHeight
c.width = window.innerWidth
let startX;
let startY;
function pen(e, colorHEX) {
let endX = e.clientX
let endY = e.clientY
ctx.fillStyle = colorHEX
ctx.beginPath()
ctx.moveTo(startX, startY)
ctx.lineTo(endX, endY)
ctx.fill()
ctx.closePath()
ctx.stroke()
}
$('body').mousedown(function(e){
startX = e.clientX;
startY = e.clientY;
})
$('body').mouseup(function(e) {
pen(e, "#000000");
})
body {
margin: 0;
overflow: hidden;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link href="style.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<canvas id="c"></canvas>
<script type="text/javascript" src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script src="script.js"></script>
</body>
</html>
Drawing with mouse
You have two options.
Draw a line segment from A to B setting the line width to match the circles diameter and the line cap to round.
Interpolate the points from A to B drawing a circle (or any shape) at points 1px apart.
I said two but there are a zillion ways to do this type of thing, but that would put this answer in the TLDR category.
Which method you use will depend on the finer details of your needs. The two example below drawing using the most basic solid line look identical.
What I think you may be having a problem with is because you are turning the event listeners on and off, the last mouse position you have is the last mouse up.
I have added two examples. One for each of the drawing options, and the top one uses an always on mouse listeners and a second turns on and of the mouse listeners as needed.
Examples
The mouse has its state put into an object called mouse.
Each time the mouse changes position the last position is put into mouse.lastX, mouse.lastY.
If the mouse event.type is mousedown the mouse.button is set to true and to false if mouseup
Mouse up and down are also used to turn on and off things like cursor, add and remove events (second example)
At the bottom of the listener it checks if the mouse is down (mouse.button is true) and draws a line from the last position to the current position.
Using line segments
Draws by using 2D API's stroke function.
Use always on mouse listeners.
const ctx = c.getContext('2d');
const BORDER = 1; // I added a 1px border to canvas.
c.height = innerHeight - BORDER * 2;
c.width = innerWidth - BORDER * 2;
const mouse = {x: 0, y: 0, lastX: 0, lastY: 0, button: false};
function drawLine(xA, yA, xB, yB, col, width) {
ctx.strokeStyle = col;
ctx.lineCap = "round";
ctx.lineWidth = width;
ctx.beginPath()
ctx.lineTo(xA, yA);
ctx.lineTo(xB, yB);
ctx.stroke();
}
function mouseEvent(e) {
if (e.type === "mousedown") {
mouse.button = true;
c.classList.add("hideMouse");
} else if (e.type === "mouseup") {
mouse.button = false;
c.classList.remove("hideMouse");
}
mouse.lastX = mouse.x;
mouse.lastY = mouse.y;
mouse.x = e.clientX - BORDER;
mouse.y = e.clientY - BORDER;
if (mouse.button) {
drawLine(mouse.lastX, mouse.lastY, mouse.x, mouse.y, "#000", 4);
}
}
addEventListener("mousedown", mouseEvent);
addEventListener("mouseup", mouseEvent);
addEventListener("mousemove", mouseEvent);
body {
margin: 0;
overflow: hidden;
font-family: arial;
}
canvas {
border: 1px solid black;
cursor: crosshair;
}
.hideMouse {
cursor: none;
}
div {
background: #FFF8;
position: absolute;
top: 4px;
left: 4px;
}
<canvas id="c"></canvas>
<div>Click and drag mouse to draw</div>
Interpolate line
Replaces drawLine function body with interpolation algorithum.
Adds mouse listeners mousemove and mouseup, on mousedown. Note that the up listener has the option {once:true} when added so does not need to be manually removed.
const ctx = c.getContext('2d');
const BORDER = 1; // I added a 1px border to canvas.
c.height = innerHeight - BORDER * 2;
c.width = innerWidth - BORDER * 2;
const mouse = {x: 0, y: 0, lastX: 0, lastY: 0, button: false};
function drawLine(xA, yA, xB, yB, col, width) {
var i = 0;
const dx = xB - xA;
const dy = yB - yA;
const length = Math.hypot(dx, dy);
const stepX = length > 0 ? dx / length : 0;
const stepY = length > 0 ? dy / length : 0;
ctx.beginPath();
ctx.fillStyle = col;
while (i <= length) {
ctx.moveTo(xA + width / 2, yA);
ctx.arc(xA, yA, width / 2, 0, Math.PI * 2);
xA += stepX;
yA += stepY;
i ++;
}
ctx.fill();
}
function mouseEvent(e) {
if (e.type === "mousedown") {
mouse.button = true;
c.classList.add("hideMouse");
addEventListener("mouseup", mouseEvent, {once: true});
addEventListener("mousemove", mouseEvent);
// Set mouse pos so last pos is not where the last mouse up was
mouse.x = e.clientX - BORDER;
mouse.y = e.clientY - BORDER;
} else if (e.type === "mouseup") {
mouse.button = false;
c.classList.remove("hideMouse");
removeEventListener("mousemove", mouseEvent);
}
mouse.lastX = mouse.x;
mouse.lastY = mouse.y;
mouse.x = e.clientX - BORDER;
mouse.y = e.clientY - BORDER;
if (mouse.button) {
drawLine(mouse.lastX, mouse.lastY, mouse.x, mouse.y, "#000", 4);
}
}
addEventListener("mousedown", mouseEvent);
body {
margin: 0;
overflow: hidden;
font-family: arial;
}
canvas {
border: 1px solid black;
cursor: crosshair;
}
.hideMouse {
cursor: none;
}
div {
background: #FFF8;
position: absolute;
top: 4px;
left: 4px;
}
<canvas id="c"></canvas>
<div>Click and drag mouse to draw</div>
Side note...
jQuery is dead
BTW jQuery is not needed, it became irrelevant about 5 years ago.
Using it puts you many years behind modern front end development.
In the past 5 years the demand for jQuery experience coders has dropped a significant amount. A trend that will continue as jQuery has painted its self into a corner from which the only way out is via re branding and re targeting its purpose.
Every time you use jQuery you are investing your most valuable asset, time. Time spent learning and gaining experience. Be wise and direct that time learning what is applicable and growing in the future, and not into what started dying over a decade ago.
For more details Should you use or learn jQuery in 2020?

Why can't I move my circle inside the canvas?

I'm trying to move two circles separately, but I can't seem to make the two circles move despite searching over w3school or youtube, I know how to move one circle but when I try to move two circle by creating a constructor it fails.
I'm sure this is a dumb question but I just can't help but ask.
let canvas = document.querySelector("#canvas");
let ctx = canvas.getContext("2d");
let ball = new drawCircle(50, 50, 20);
let ballTwo = new drawCircle(100, 100, 20);
function drawCircle(x, y, r) {
this.x = x;
this.y = y;
this.r = r;
this.draw = function() {
ctx.beginPath();
ctx.arc(x, y, r, 0, Math.PI *2);
ctx.fillStyle = "lightskyblue";
ctx.fill();
}
}
function draw() {
ball.x += 1;
ball.draw();
ballTwo.x += 1;
ballTwo.draw();
if (x + r > canvas.width || x < r) {
dx = -dx;
}
if (y + r > canvas.width || y < r) {
dy = -dy;
}
requestAnimationFrame(draw)
}
draw();
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Círculo</title>
<style>
body {
margin: 0;
display: flex;
justify-content: center;
}
#canvas {
border: 1px solid black;
}
</style>
</head>
<body>
<canvas id="canvas" width="300" height="300"></canvas>
</body>
<script src="/js/canvasTwo.js"></script>
</html>

Auto-adjust canvas by itself in all possible sizes

I have one canvas-fx code ("stars" coming from deep to front, all centered, simulating space-navigation; it was not done by me) that I want to put in one website as a background.
I want it so that when a user resizes the window (dragging to right or left or resizing or whatever), the effect can auto-adjust itself so that the stars always come from the center in any size or even changing the desktop resolution (I refer the FX can auto-reset by itself the same it does when rendering the webcode).
Also I want it so that the code can adjust itself to the size of the content of the body (i.e. adding content from up to down, etc).
Finally, how can I quit the bottom bar, leaving only the scroll bar from the right?
Here is the complete code I am using:
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="utf-8">
<title>FX TEST</title>
<STYLE type="text/css">
html, body {
width:100%;
height:100%;
}
#Canvas2D {
position:absolute;
top:0;
left:0;
}
#content {
z-index: 10;
position: relative;
}
</STYLE>
<script language="JavaScript">
function setup() {
var fov = 150;
var SCREEN_WIDTH = 1920;
var SCREEN_HEIGHT = 1080;
var HALF_WIDTH = SCREEN_WIDTH / 2;
var HALF_HEIGHT = SCREEN_HEIGHT / 2;
var numPoints = 300;
function draw3Din2D(point3d) {
x3d = point3d[0];
y3d = point3d[1];
z3d = point3d[2];
var scale = fov / (fov + z3d);
var x2d = (x3d * scale) + HALF_WIDTH;
var y2d = (y3d * scale) + HALF_HEIGHT;
c.lineWidth = scale;
c.strokeStyle = "rgb(255,255,255)";
c.beginPath();
c.moveTo(x2d, y2d);
c.lineTo(x2d + scale, y2d);
c.stroke();
}
var canvas = document.getElementById('Canvas2D');
var c = canvas.getContext('2d');
var points = [];
function initPoints() {
for(i = 0; i < numPoints; i++) {
point = [(Math.random() * 400) - 200, (Math.random() * 400) - 200, (Math.random() * 400) - 200];
points.push(point);
}
}
function render() {
c.fillStyle = "rgb(0,0,0)";
c.fillRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
for(i = 0; i < numPoints; i++) {
point3d = points[i];
z3d = point3d[2];
z3d -= 4;
if(z3d < -fov) z3d += 400;
point3d[2] = z3d;
draw3Din2D(point3d);
}
}
initPoints();
var loop = setInterval(function () {
render();
}, 50);
}
</script>
</head>
<body onload="setup();">
<canvas id="Canvas2D" width="1920" height="1080">NOT USING HTML5 SUPPORT</canvas>
<div id="content">
<z-index: 0></z-index:>
</div>
</body>
</html>
Live Demo
Full screen demo
Below are the modifications I made to make it work. First remove the size in your canvas element. Change it to
<canvas id="Canvas2D"></canvas>
Next here is what I use for my CSS when Im doing anything full screen with canvas.
html, body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
#Canvas2D {
position:absolute;
top:0;
left:0;
}
And here is the JS required to make it all work
// set the width and height to the full windows size
var SCREEN_WIDTH = window.innerWidth;
// Change to scroll height to make it the size of the document
var SCREEN_HEIGHT = document.documentElement.scrollHeight;
// Make sure to set the canvas to the screen height and width.
canvas.width = SCREEN_WIDTH;
canvas.height = SCREEN_HEIGHT;
// everytime we resize change the height and width to the window size, and reset the
// center point
window.onresize = function () {
SCREEN_HEIGHT = canvas.height = document.documentElement.scrollHeight;
SCREEN_WIDTH = canvas.width = document.body.offsetWidth;
HALF_WIDTH = SCREEN_WIDTH / 2;
HALF_HEIGHT = SCREEN_HEIGHT / 2;
};
Well, first of all, thanks a lot to #Loktar for your inner support.
Now i had been working on the code that i will put in my own Official Website (relaunching it).
After the help of #Loktar, the problem was that the vertically autoadjust was not working, so i changed this :
var SCREEN_HEIGHT = document.documentElement.scrollHeight;
To this :
var SCREEN_HEIGHT = window.innerHeight;
And this :
SCREEN_HEIGHT = canvas.height = document.documentElement.scrollHeight;
Changed To this :
SCREEN_HEIGHT = canvas.height = document.body.offsetHeight;
Now it centers good vertically too.
The second problem was that when you doesn´t give to canvas command an exactly number of size it doesn´t show scrollbars, so i fund an style code that after i adadpt to this fx, the way now you can now have scrollbars horizontally and vertically. What you need to do is to add this to the style of your website :
div.scroll
{
width:100%;
height:100%;
overflow:scroll;
}
For after call it in the div of the content with a class, as you can see below :
<div id="content" class="scroll">
Now you will have scrollbars activated when needed. It was tested at Internet Explorer and Firefox and works. I hope it will help to apply to several other canvas codes.
Finally, here i left how the final code looks, and partially how it will look at my Official Website :
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="utf-8">
<title>FX TEST</title>
<STYLE type="text/css">
html, body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
#Canvas2D {
position:absolute;
top:0;
left:0;
}
#content {
z-index: 10;
position: relative;
}
div.scroll
{
width:100%;
height:100%;
overflow:scroll;
}
</STYLE>
<script language="JavaScript">
function setup() {
var fov = 150;
var SCREEN_WIDTH = window.innerWidth;
var SCREEN_HEIGHT = window.innerHeight;
var HALF_WIDTH = SCREEN_WIDTH / 2;
var HALF_HEIGHT = SCREEN_HEIGHT / 2;
var numPoints = 300;
function draw3Din2D(point3d) {
x3d = point3d[0];
y3d = point3d[1];
z3d = point3d[2];
var scale = fov / (fov + z3d);
var x2d = (x3d * scale) + HALF_WIDTH;
var y2d = (y3d * scale) + HALF_HEIGHT;
c.lineWidth = scale;
c.strokeStyle = "rgb(255,255,255)";
c.beginPath();
c.moveTo(x2d, y2d);
c.lineTo(x2d + scale, y2d);
c.stroke();
}
var canvas = document.getElementById('Canvas2D');
var c = canvas.getContext('2d');
canvas.width = SCREEN_WIDTH;
canvas.height = SCREEN_HEIGHT;
var points = [];
function initPoints() {
for (i = 0; i < numPoints; i++) {
point = [(Math.random() * 400) - 200, (Math.random() * 400) - 200, (Math.random() * 400) - 200];
points.push(point);
}
}
function render() {
c.fillStyle = "rgb(0,0,0)";
c.fillRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
for (i = 0; i < numPoints; i++) {
point3d = points[i];
z3d = point3d[2];
z3d -= 4;
if (z3d < -fov) z3d += 400;
point3d[2] = z3d;
draw3Din2D(point3d);
}
}
initPoints();
var loop = setInterval(function () {
render();
}, 50);
window.onresize = function () {
SCREEN_HEIGHT = canvas.height = document.body.offsetHeight;
SCREEN_WIDTH = canvas.width = document.body.offsetWidth;
HALF_WIDTH = SCREEN_WIDTH / 2;
HALF_HEIGHT = SCREEN_HEIGHT / 2;
};
}
setup();
</script>
</head>
<body onload="setup();">
<canvas id="Canvas2D"></canvas>
<div id="content" class="scroll">
<z-index: 0>
</z-index:>
</div>
</body>
</html>
set the width and height of the canvas to 100%.

Categories

Resources