Canvas element in Webview being drawn only some of the time - javascript

I'm using a Webview in my android app. I'm placing a 2d canvas over a webgl canvas (webgl commented out here). Now, when I start up the app, half the time it draws the expected path, and half the time it draws nothing. Am I missing something? Could this be a caching problem or something?
<!DOCTYPE html>
<html lang="en">
<head>
<title>Cardboard container</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
margin: 0px;
overflow: hidden;
/*background-color: black;*/
}
#container {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 1;
display: none;
}
#stamp {
position: absolute;
top: 0px;
left: 160px;
width: 38px;
height: 38px;
background-color: red;
z-index: 0;
}
#bezier{
z-index: 2;
}
</style>
</head>
<body>
<div id="container"></div>
<div id="stamp"></div>
<canvas id="bezier">Error creating bezier canvas</canvas>
<script src="js/third-party/threejs/three.js"></script>
<script src="js/third-party/threejs/StereoEffect.js"></script>
<script src="js/webgl.js"></script>
<script src="js/bezier.js"></script>
<script>
var consecutiveAbsentFrames = 6;
var totalFrames = 90;
var frameCount = 0;
var straightLineSpeed = 0.05;
var scaleFactor = 0.9;
var numGridPoints = 196;
var fovRadius = 9;
var fovXoffset = 0.5;
var gridPoints = []; // Points are an array [x0,y0,x1,y1,...]
var gridPoints2d = [];
var completePath = [];
var pathIndex = 0;
init();
function init() {
stamp = document.getElementById('stamp');
init2d();
}
function init2d(){
var b = document.getElementById('bezier');
b.width = window.innerWidth * scaleFactor * 0.5;
b.height = window.innerHeight;
var ctx=b.getContext('2d');
ctx.moveTo(0,0);
ctx.lineTo(100,100);
ctx.stroke();
}
</script>
</body>
</html>
EDIT:
Behavior is normal on a Moto X with Android 5.1, incorrect on Note 5 with 5.1.1

Related

(JS/CANVAS/HTML) - isPoinToPath inaccurate?

Below here, the provided snippet for testing purpose.
The yellow(y) represent the canvas area, return "n" on click
The red(r) represent the click area, return "y" on click
The trouble(x) represent the error, return "y" when clicked
How to make it right?
yyyyyyyyyyyyyyy
yyrrrrrrrrrrryy
yyrrrrrrrrrrryy
yyxxxxxxxxxxxyy
yyyyyyyyyyyyyyy
const canvas = document.getElementById('test');
const context = canvas.getContext('2d');
testClicker();
function testClicker() {
const buttonz = new Path2D();
buttonz.rect(canvas.width / 2 - 125, canvas.height / 2 - 70, 250, 80);
context.fillStyle = 'red';
context.fill(buttonz);
var mouseEvent = (event) => {
// Check whether point is inside rect
const isPointInPath = context.isPointInPath(buttonz, event.offsetX, event.offsetY);
let a = isPointInPath ? 'y' : 'n';
alert(a);
}
canvas.addEventListener("click", mouseEvent, false);
}
* {
margin: 0px;
padding: 0px;
}
#test {
position: fixed;
top: 1%;
left: calc(50% - 150px);
width: 300px;
height: 100px;
background: yellow;
}
<!DOCTYPE html>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<link rel="stylesheet" href="style.css">
<html>
<body>
<canvas id="test"></canvas>
</body>
<script src="main.js"></script>
</html>
You have a mismatch between the CSS setting of height of canvas (100px) and the canvas's attribute height (set to 150px by default).
You are using canvas.height as the basis for setting the path drawing on the canvas.
This snippet makes things match up by setting the height attribute of the canvas to 100.
const canvas = document.getElementById('test');
const context = canvas.getContext('2d');
testClicker();
function testClicker() {
const buttonz = new Path2D();
alert(canvas.height);
buttonz.rect(canvas.width / 2 - 125, canvas.height / 2 - 70, 250, 80);
context.fillStyle = 'red';
context.fill(buttonz);
var mouseEvent = (event) => {
// Check whether point is inside rect
alert(event.offsetY);
const isPointInPath = context.isPointInPath(buttonz, event.offsetX, event.offsetY);
let a = isPointInPath ? 'y' : 'n';
alert(a);
}
canvas.addEventListener("click", mouseEvent, false);
}
* {
margin: 0px;
padding: 0px;
}
#test {
position: fixed;
top: 1%;
left: calc(50% - 150px);
width: 300px;
height: 100px;
background: yellow;
}
<!DOCTYPE html>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<link rel="stylesheet" href="style.css">
<html>
<body>
<canvas id="test" width="300" height="100"></canvas>
</body>
<script src="main.js"></script>
</html>
See MDN for further explanation of the difference between setting dimensions of the canvas using the width/height attributes and using CSS. If they differ you get scaling/distortion.

How can we do this so that when the screen is clicked, a line is created by a canvas from one vertex to the clicked location?

I have created a circle here so that when the screen is clicked, the circle will move there. And I also have a fixed point (vertex) that I want these two points to be the origin and destination of a line.
const coordinates = document.querySelector(".coordinates");
const circle = document.querySelector(".circle");
const result = document.querySelector(".result");
const numbers = document.querySelectorAll("p");
coordinates.addEventListener("click", e => {
circle.style.setProperty('--x', `${e.clientX}px`);
circle.style.setProperty('--y', `${e.clientY}px`);
})
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.moveTo(0,0);
ctx.lineTo(50,100);
ctx.stroke();
canvas {
color: rgb(255, 255, 255);
}
.circle {
width: 20px;
height: 20px;
border-radius: 50%;
position: fixed;
--x: 47px;
left: calc(var(--x) - 10px);
--y: 47px;
top: calc(var(--y) - 10px);
background-color: white;
}
.bg {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: #24232e;
}
.coordinates {
height: 100%;
}
<!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">
</head>
<body>
<div class="bg">
<div class="coordinates">
<canvas id="myCanvas" width="200" height="100" style=""></canvas>
</div>
</div>
<div class="circle">
</div>
</body>
</html>
How to do this with canvas?
! would appreciate <3
You can detect the mouse position on the canvas and draw a line to the coordinates. to get the canvas x and y of the mouse, you have to do some calculations because the site coordinates are a bit different than the canvas ones.
A more detailed description is here: https://stackoverflow.com/a/17130415/14076532
This will work only, if the canvas is big enough, logically...
Hope this helps:
const coordinates = document.querySelector(".coordinates");
const circle = document.querySelector(".circle");
const result = document.querySelector(".result");
const numbers = document.querySelectorAll("p");
coordinates.addEventListener("click", e => {
clicked(e);
circle.style.setProperty('--x', `${e.clientX}px`);
circle.style.setProperty('--y', `${e.clientY}px`);
})
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.strokeStyle = "#de7270"; // change your color here NOTE: this will remain until you change it
ctx.moveTo(0,0);
ctx.lineTo(50,100);
ctx.stroke();
function clicked(event) {
ctx.save(); // some canvas-safety-stuff
ctx.beginPath();
let mousepos = getMousePos(event); // get the mouse position in "canvas-cooridnates"
ctx.clearRect(0,0, c.width, c.height) // erease the canvas
ctx.moveTo(0, 0);
ctx.lineTo(mousepos.x, mousepos.y); // draw the line to the mouse
ctx.closePath();
ctx.stroke(); // closing of the canvas-safety-stuff
ctx.restore();
}
function getMousePos (evt) {
var rect = c.getBoundingClientRect(), // abs. size of element
scaleX = c.width / c.width, // relationship bitmap vs. element for X
scaleY = c.height / rect.height; // relationship bitmap vs. element for Y
return {
x: (evt.clientX - rect.left) * scaleX, // scale mouse coordinates after they have
y: (evt.clientY - rect.top) * scaleY // been adjusted to be relative to element
}
}
canvas {
color: rgb(255, 255, 255);
}
.circle {
width: 20px;
height: 20px;
border-radius: 50%;
position: fixed;
--x: 47px;
left: calc(var(--x) - 10px);
--y: 47px;
top: calc(var(--y) - 10px);
background-color: white;
}
.bg {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: #24232e;
}
.coordinates {
height: 100%;
}
<!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">
</head>
<body>
<div class="bg">
<div class="coordinates">
<canvas id="myCanvas" width="200" height="100" style=""></canvas>
</div>
</div>
<div class="circle">
</div>
</body>
</html>

Having problems to generate a random array and visualize it using <div> elements in VS Code?

I am a beginner at web dev and am trying to build a sorting visualizer.
I am unable to get the output for generating a visualization of a random array by using the (div)
element of html.
This is the code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>sorting visualizer</title>
<style>
/* *{
margin: 0;
padding: 0;
} */
#array_container{
position: absolute;
left: 100px;
right: 100px;
bottom: 100px;
height: 100%;
width: 100%;
/* margin-left: 50px;
margin-right: 50px; */
background-color: turquoise;
}
</style>
</head>
<body>
<script>
function random_array(min, max){
return Math.floor(Math.random() * (max - min)) + min;
function generate_array(){
var cont = document.getElementById("array_container");
var bar;
var arr = [];
for ( var i = 0; i < 100; i++){
arr.push(random_array(5, 1000));
bar = document.createElement("div");
bar.style = "height:"+arr[i]+";width:2px;margin:0 1px;background-color:pink;display:inline-block;";
cont.appendChild(bar);
}
}
}
</script>
<div id="array_container">
</div>
<button id="btn1" onclick="generate_array">generate</button>
</body>
</html>
please help me by finding the ERROR and also suggest me some other methods for visualizing array in a bar graph format.
A couple minor syntax bugs I found:
You're missing the parenthesis () at the end of your function name when you pass it to the generate button's onclick
The brackets around your functions were offset, which was causing errors
Your code isn't broken beyond those minor syntax bugs, the problem you're facing is that your generated divs aren't respecting the height you're passing them, because you didn't give them a height unit.
You need to specify a unit like px, otherwise the height will get thrown out and ignored.
Working example (You'll want to adjust some other styles if you want them to fit in your box):
function random_array(min, max) {
return Math.floor(Math.random() * (max - min)) + min;
}
function generate_array() {
var cont = document.getElementById("array_container");
var bar;
var arr = [];
for (var i = 0; i < 100; i++) {
arr.push(random_array(5, 1000));
bar = document.createElement("div");
bar.style = "height:" + arr[i] + "px;width:2px;margin:0 1px;background-color:pink;display:inline-block;";
cont.appendChild(bar);
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>sorting visualizer</title>
<style>
#array_container {
position: absolute;
left: 100px;
right: 100px;
bottom: 100px;
height: 100%;
width: 100%;
background-color: turquoise;
}
</style>
</head>
<body>
<div id="array_container"></div>
<button id="btn1" onclick="generate_array()">generate</button>
</body>
</html>

why can't log keycode value to the console window?

Hey guy's I'm trying to make a snake game in JS. Right now I'm making the function that will determine the direction of the snake, but at the moment I just want to log the keycode of any given key to the console, but it comes up as undefined? Why is this? I have the keycode stored into a variable before I log it? thanks for the help:)
const canvas = document.querySelector('#canvas');
const ctx = canvas.getContext('2d');
//set canvas dimension equal to css dimension
canvas.width = 750;
canvas.height = 500;
//create stroke
ctx.strokeStyle = 'limegreen';
ctx.strokeRect(375, 250, 15, 15);
//create square
ctx.fillStyle = 'limegreen';
ctx.fillRect(375, 250, 15, 15);
//read user's direction
document.addEventListener('keydown', changeDirection);
function changeDirection(e) {
let code = e.keycode;
console.log(code);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Snake Game</title>
<style>
body {
background-color: #333;
}
canvas {
background-color: #4d4d4d;
margin: auto;
display: block;
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
width: 750px;
height: 500px;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script src="script.js"></script>
</body>
</html>
Try e.keyCode instead of e.keycode

Position elements on screen using Javascript

I am attempting to use Javascript to position some of my elements on the screen/window. I am doing this to make sure that what ever the dimensions of the users screen, my elements will always be in the centre.
I know that padding & margin can also achieve this, but I am using a custom movement script called raphael.js, & in order to move my elements I need to set out my elements absolutely (its a custom home page, where you click blocks(that are links) & they fly off the screen).
My javascript function to move my elements fails to move my elements. Any suggestions on how to position my elements using javascript would be really helpful.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="dropDownMenu.js"></script>
<title></title>
<script src="javascript/raphael.js"></script> <!-- I am using a custom drawing/moving script which is why I cant put the img(id=bkImg) inside the div element -->
<script LANGUAGE="JavaScript" type = "text/javascript">
<!--
function getScreenSize()
{
var res = {"width": 630, "height": 460};
if (document.body)
{
if (document.body.offsetWidth) res["width"] = document.body.offsetWidth;
if (document.body.offsetHeight) res["height"] = document.body.offsetHeight;
}
if (window.innerWidth) res["width"] = window.innerWidth;
if (window.innerHeight) res["height"] = window.innerHeight;
alert( res["width"] );
alert( res["height"] );
return res;
}
function positionBlocksAccordingToScreenSize()
{
// The problem is that the blocks position does not change but they should?
var scrDim = getScreenSize();
var BK_WIDTH = 800;
var BK_HEIGHT = 600;
var X_OFFSET = (scrDim["width"]-BK_WIDTH) / 2; // variable that changes according to the width of the screen
var BLOCK_POS_X = [160, 80, 280, 20, 200, 400];
var BLOCK_POS_Y = [26, 203, 203, 380, 380, 380];
for ( var i=1; i<=5; i++ )
{
//document.getElementById("block"+i).setAttribute( "offsetLeft", X_OFFSET + BLOCK_POS_X[i] ); // doesn't work
//document.getElementById("block"+i).setAttribute( "offsetTop", BLOCK_POS_Y[i] ); // doesn't work
document.getElementById("block"+i).style.left = X_OFFSET + BLOCK_POS_X[i]; // doesn't work
document.getElementById("block"+i).style.top = BLOCK_POS_Y[i]; // doesn't work
}
}
-->
</script>
<style type="text/css" media="all">
<!--
#import url("styles.css");
#blockMenu { z-index: -5; padding: 0; position: absolute; width: 800px;
height: 600px; /*background-image: url("images/menuBk.png");*/ }
#bkImg { z-index: -5; position: relative; }
#block1 { z-index: 60; position: absolute; top: 26px; left: 160px; margin: 0; padding: 0; }
#block2 { z-index: 50; position: absolute; top: 203px; left: 80px; margin: 0; padding: 0; }
#block3 { z-index: 40; position: absolute; top: 203px; left: 280px; margin: 0; padding: 0; }
#block4 { z-index: 30; position: absolute; top: 380px; left: 20px; margin: 0; padding: 0; }
#block5 { z-index: 20; position: absolute; top: 380px; left: 200px; margin: 0; padding: 0; }
#block6 { z-index: 10; position: absolute; top: 380px; left: 400px; margin: 0; padding: 0; }
-->
</style>
</head>
<body onload="positionBlocksAccordingToScreenSize()" style="margin-top: 10%; text-align: center; margin-bottom: 10%; position: relative;">
<img id="bkImg" src="images/menuBk.png" width="800px;" height="600px" alt=""/>
<!-- The above image should be displayed behind the below div. I am using the raphael.js movement script, so I cannot place
this image inside the div, because it will get erased when I call raphael.clear(); -->
<div id="blockMenu">
<div id="block1"><img src="images/block1.png" width="200" height="200"/></div>
<div id="block2"><img src="images/block2.png" width="200" height="200"/></div>
<div id="block3"><img src="images/block3.png" width="200" height="200"/></div>
<div id="block4"><img src="images/block4.png" width="200" height="200"/></div>
<div id="block5"><img src="images/block5.png" width="200" height="200"/></div>
<div id="block6"><img src="images/block6.png" width="200" height="200"/></div>
</div>
</body>
</html>
You're not setting the left and top properties correctly, you need to add the unit e.g 'px' for pixels.
document.getElementById("block"+i).style.left = X_OFFSET + BLOCK_POS_X[i] + 'px';
document.getElementById("block"+i).style.top = BLOCK_POS_Y[i] + 'px';
"Would you be able to suggest a line of jQuery code that could place my elements correctly?"
The following code uses jQuery and will center an absolutely positioned element on load and on window resize.
http://jsfiddle.net/Fu3L6/
HTML...
<div id="element">Test</div>
CSS...
#element {
position: absolute;
background-color: red;
width: 200px;
}
jQuery...
$(document).ready(function () {
centerInViewport('#element');
$(window).resize(function () {
centerInViewport('#element');
});
});
function centerInViewport(e) {
$docWidth = $(document).width();
$elWidth = $(e).width();
$offset = ($docWidth - $elWidth) / 2;
$(e).css("marginLeft", $offset + "px");
}

Categories

Resources