How to move an animated line in html 5 canvas? - javascript

I have this animated line that I am building using HTML5 Canvas class. I am trying to move the line to the left when I hit up left button. I am still new to web development and just started messing around with HTML and JS. Therefore, I request you to help me out. Please explain in detail so I can learn what I am doing wrong! Thanks! I have this following code
<!DOCTYPE HTML>
<html>
<head>
<style>
body {
margin: 0px;
padding: 0px;
}
</style>
</head>
<body>
<canvas id="canvas" width="600" height="400"></canvas>
<button type="button" id="startButton">Start</button>
<button type="button" id="left">Left</button>
<button type="button" id="left">Right</button>
<script>
(function(){
function init(){
var canvas = document.getElementById("canvas"),
ctx = canvas.getContext("2d");
var direction=0;
canvas.width = 200;
canvas.height = 200;
var points = [],
currentPoint = 20000,
nextTime = new Date().getTime()+500,
pace = 200;
var startingx=25,startingy=0;
// make some points
for (var i = 0; i < canvas.height ; i++) {
for (var k = 0; k < canvas.width ; k++){
points.push({
x: i ,
y: k
});
}
}
function draw(){
if(new Date().getTime() > nextTime){
nextTime = new Date().getTime() + pace;
currentPoint++;
}
ctx.clearRect(0,0,canvas.width, canvas.height);
ctx.beginPath();
ctx.moveTo(points[20000].x, points[20000].y);
ctx.lineWidth = 2;
ctx.strokeStyle = '#FF0000';
ctx.fillStyle = '#FF0000';
for (var p = 20000, plen = currentPoint; p < plen; p++) {
if(direction==0)
{ctx.lineTo(points[p].x, points[p].y);ctx.stroke();}
else if(direction==1)
{ctx.lineTo(points[p+200].x, points[p+200].y);ctx.stroke();}
else if(direction==2)
{ctx.lineTo(points[p-2].x, points[p-2].y);ctx.stroke();}
else if(direction==3)
{ctx.lineTo(points[p-200].x, points[p-200].y);
ctx.stroke();}
}
cancelMe = requestAnimationFrame(draw);
}
function startAnimation(event){
if(this.textContent === "Start"){
requestAnimationFrame(draw);
this.textContent = 'Pause';
}
else{
cancelAnimationFrame(cancelMe);
this.textContent = 'Start';
}
}
function leftTurn(event){
direction++;
if(direction>3)
{
direction=0;
}
}
function rightTurn(event){
direction--;
if(direction<0)
{
direction=3;
}
}
var startButton = document.getElementById('startButton');
startButton.addEventListener('click',startAnimation,false);
var leftButton = document.getElementById('left');
var rightButton = document.getElementById('right');
leftButton.addEventListener('click',leftTurn,false);
rightButton.addEventListener('click',rightTurn,false);
}
//invoke function init once document is fully loaded
window.addEventListener('load',init,false);
}()); //self invoking function
</script>
</body>
</html>

Related

How to take notes on PDF files using JavaScript and HTML

I don't understand why this code is not working. No matter how much I fix it, it doesn't work. Is it not available in PDF? If it's not possible, I'd appreciate it if you could tell me how to replace it.
Also, I would like to ask if it is possible to save the handwritten file as a PDF file again, or if it is possible to save it using a DB on the web server, and if possible, please provide an example code.
index.html
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>lol</title>
</head>
<body>
<div class="palette">
<label>색상<input id="color" type="color"></label>
<label>두께<input id="width" type="number" min="1" max="30"></label>
<input type="button" class="btn" id="delete_canvas" value="그림 초기화" onClick="delete_canvas()">
</div>
<iframe width="100%" height="1295" src="./src/krlang.pdf"></iframe>
<canvas id="canvas" width="1600" height="900"></canvas><br>
<script type="text/javascript">
var elements = document.getElementsByClassName("drag-and-drop");
var array = [];
for (var i = 0; i < elements.length; i++) {
array[i] = {}
array[i].top = elements[i].style.top;
array[i].left = elements[i].style.left;
}
function all_reset() {
ret = confirm('모두 재설정합니다.');
if (ret == true) {
for (var i = 0; i < elements.length; i++) {
elements[i].style.top = array[i].top;
elements[i].style.left = array[i].left;
}
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
}
</script>
<script type="text/javascript" src="canvas.js"></script>
</body>
</html>
canvas.js
var drawing = false;
var before_x = 0;
var before_y = 0;
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
canvas.addEventListener('mousemove', draw_canvas);
canvas.addEventListener('mousedown', function(e) {
drawing = true;
var rect = e.target.getBoundingClientRect();
before_x = e.clientX - rect.left;
before_y = e.clientY - rect.top;
});
canvas.addEventListener('mouseup', function() {
drawing = false;
});
function draw_canvas(e) {
if (!drawing){
return
};
var rect = e.target.getBoundingClientRect();
var x = e.clientX - rect.left;
var y = e.clientY - rect.top;
var w = document.getElementById('width').value;
var color = document.getElementById('color').value;
var r = parseInt(color.substring(1,3), 16);
var g = parseInt(color.substring(3,5), 16);
var b = parseInt(color.substring(5,7), 16);
ctx.lineCap = 'round';
ctx.strokeStyle = 'rgb('+ r + ',' + g + ',' + b + ')';
ctx.lineWidth = w;
ctx.beginPath();
ctx.moveTo(before_x, before_y);
ctx.lineTo(x, y);
ctx.stroke();
ctx.closePath();
before_x = x;
before_y = y;
}
function delete_canvas(){
ret = confirm('그리기 내용 삭제');
if (ret == true){
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
}
var pen = document.getElementById('pencil');
var era = document.getElementById('eraser');
Edit
I decided to do a webview app instead of running this html code on a web server, please tell me how to do it with a local database

Javascript subroutines don't run

So I am new to javascript and a beginner programmer. I know the initialization subroutine always go first. I don't get why the subroutines aren't running. And I was wondering if any variables in the initialization subroutine can be used in any other subroutines. I am trying to make a program using Bresenham Line Algorithm.
<html>
<head>
<body>
<canvas id="canvas" width="500" height="500" style="border: 1px solid black;" onclick="coordinates(event)">></canvas>
</body>
<script type="text/javascript" src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script type="text/javascript">
intialization();
drawGrid();
mouseClick();
//Intialization--------------------------------
//Intialization--------------------------------
function intialization() {
var cnv = document.getElementById("canvas");
var Width = cnv.width;
var Height = cnv.height;
var ctx = cnv.getContext('2d');
var click_counter = 0; //switching between storing first and second point coordinates
p1x = 0; //stores user's click on canvas
p1y = 0; //stores user's click on canvas
p2x = 0; //stores user's click on canvas
p2y = 0; //stores user's click on canvas
}
//Intialization--------------------------------
//GRID---------------------------------
function drawGrid() {
var gridLines = {
Lines: {
space: 10,
// color: "'#xxxxxx'"
}
};
drawGridLines(cnv, gridLines.Lines);
return;
}
function drawGridLines(cnv, lineOptions) {
ctx.strokeStyle = lineOptions.color;
ctx.strokeWidth = 1;
ctx.beginPath();
var counter = null;
var i = null;
var x = null;
var y = null;
counter = Math.floor(Width / lineOptions.space);
for (i = 1; i <= counter; i++) {
x = (i * lineOptions.space);
ctx.moveTo(x, 0);
ctx.lineTo(x, Height);
ctx.stroke();
}
counter = Math.floor(Height / lineOptions.space);
for (i = 1; i <= counter; i++) {
y = (i * lineOptions.space);
ctx.moveTo(0, y);
ctx.lineTo(Width, y);
ctx.stroke();
}
ctx.closePath();
return;
}
//GRID---------------------------------
//MOUSE---------------------------------
function mouseClick {
if (click_counter = 0) {
function coordinates(event) {
var x1 = event.offsetX;
var y1 = event.offsetY;
p1x = x1;
p1y = y1;
console.log("x coords: " + p1x + ", y coords: " + p1y);
} else
function coordinates(event) {
var x1 = event.offsetX;
var y1 = event.offsetY;
p2x = x1;
p2y = y1;
console.log("x coords: " + p2x + ", y coords: " + p2y);
}
}
//MOUSE---------------------------------
//MOUSE---------------------------------
</script>
</head>
</html>
Your initialization and drawGrid functions are being called before the document is even loaded so this will fail. You should use the jquery method-
$(document).ready(function(){
//callyour functions here
})
Another issue you have is that you are trying to use variables which are out of scope. Like cnv for example. You should declare a object like canvas at the top of your js:
canvas = {}
and add all of the variables you want to share to this. for instance :
canvas.cnv = document.getElementById("canvas");
canvas.Width = canvas.cnv.width;
canvas.Height = canvas.cnv.height;
canvas.ctx = canvas.cnv.getContext('2d');
Here is a simple example of how to use the canvas:
<html>
<head>
<script src="index.js"></script>
<body>
<canvas id="canvas" width="500" height="500" style="border: 1px solid black;" onmousemove="mouseClick(event)">></canvas>
</body>
<script type="text/javascript" src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script>
canvas = {}
var isMouseDown = false;
document.addEventListener('mousedown', function(event) {
if ( event.which ) isMouseDown = true;
}, true);
document.addEventListener('mouseup', function(event) {
if ( event.which ) isMouseDown = false;
}, true);
$(document).ready(function(){
canvas.cnv = document.getElementById("canvas");
canvas.Width = canvas.cnv.width;
canvas.Height = canvas.cnv.height;
canvas.ctx = canvas.cnv.getContext('2d');
});
function mouseClick(e) {
console.log(isMouseDown)
if (isMouseDown){
var x1 = event.offsetX;
var y1 = event.offsetY;
canvas.ctx.lineTo(x1, y1);
canvas.ctx.stroke();
}
}
</script>
</head>
</html>

Image puzzle game

Edited to include entire code I found this cool image puzzle creator at [here][1] but I can't figure out how to adapt it so that upon clicking a "New Puzzle button" it changes the image to start a new puzzle? My first thought was creating an array??? Not sure, still very new to JS. Any help is appreciated.
window.onload = onReady;
var can;
var ctx;
var img;
var clickX;
var clickY;
var selected1;
var selected2;
var blockSize = 160;
var piecesArray = new Array();
function onReady()
{
can = document.getElementById('myCanvas');
if(navigator.userAgent.toLowerCase().indexOf('firefox') >= 0 || !can.getContext)
{
can.style.display = 'none';
document.getElementById('sorry').style.display = 'inline';
return;
}
ctx = can.getContext('2d');
img = new Image();
img.onload = onImage1Load;
img.src = "cat.jpg";
}
function onImage1Load()
{
var r;
for(var i = 0; i < 4; i++)
{
for(var j = 0; j < 3; j++)
{
r = new Rectangle(i * blockSize, j * blockSize, i*blockSize + blockSize, j * blockSize + blockSize);
piecesArray.push(r);
}
}
scrambleArray(piecesArray, 30);
drawImage();
}
function Rectangle(left, top, right, bottom)
{
this.left = left;
this.top = top;
this.right = right;
this.bottom = bottom;
this.width = right - left;
this.height = bottom - top;
}
function scrambleArray(ar, times)
{
var count = 0;
var temp;
var index1;
var index2;
while(count < times)
{
index1 = Math.floor(Math.random()*piecesArray.length);
index2 = Math.floor(Math.random()*piecesArray.length);
temp = piecesArray[index1];
piecesArray[index1] = piecesArray[index2];
piecesArray[index2] = temp;
count++;
}
}
function drawImage()
{
var r;
for(var i = 0; i < 4; i++)
{
for(var j = 0; j < 3; j++)
{
r = piecesArray[i*3+j];
ctx.drawImage(img, r.left, r.top, r.width, r.height, i*blockSize, j*blockSize, blockSize, blockSize);
}
}
}
function highlightRect(drawX, drawY)
{
ctx.beginPath();
ctx.moveTo(drawX, drawY);
ctx.lineTo(drawX + blockSize, drawY);
ctx.lineTo(drawX + blockSize, drawY + blockSize);
ctx.lineTo(drawX, drawY + blockSize);
ctx.lineTo(drawX, drawY);
ctx.lineWidth = 2;
// set line color
ctx.strokeStyle = "#ff0000";
ctx.stroke();
}
function swapRects(r1, r2)
{
var index1;
var index2;
var temp = r1;
index1 = piecesArray.indexOf(r1);
index2 = piecesArray.indexOf(r2);
piecesArray[index1] = r2;
piecesArray[index2] = temp;
}
function onCanvasClick(evt)
{
clickX = evt.offsetX;
clickY = evt.offsetY;
var drawX = Math.floor(clickX / blockSize);
var drawY = Math.floor(clickY / blockSize);
var index = drawX * 3 + drawY;
var targetRect = piecesArray[index];
var drawHighlight = true;
drawX *= blockSize;
drawY *= blockSize;
ctx.clearRect(0, 0, 640, 480);
if(selected1 != undefined && selected2 != undefined)
{
selected1 = selected2 = undefined;
}
if(selected1 == undefined)
{
selected1 = targetRect;
}
else
{
selected2 = targetRect;
swapRects(selected1, selected2);
drawHighlight = false;
}
drawImage();
if(drawHighlight)
highlightRect(drawX, drawY);
}
<html>
<head>
<title>HTML5 Puzzle Game</title>
<script type="text/javascript">
</script>
</head>
<body style="background-color:#fbfbfb;" >
<div style="margin:0 auto; width:640px; height:480px; border: 4px solid #cc6699;">
<img id="sorry" src="sorry.jpg" style="display:none;"/>
<canvas id="myCanvas" width="640" height="480" onclick="onCanvasClick(event);">
</canvas>
</div>
</body>
</html>
1) Remove This from if condition block navigator.userAgent.toLowerCase().indexOf('firefox') >= 0, It got stucked on firefox. So no need to write this in if condition.
2) As you want a button "New Puzzle button" to replace new image
<button id="some id here">New Puzzle button</button> put this in html below the canvas(or wherever you want).
bind CLICK event on button using button's ID document.getElementById("some ID here").onclick = somefunction(){ onReady() };
As you see above the onReady() inside of button onclick function.
Now final thing use Array of images and use math.random or for loop inside of onReady function before img.src and assign the value like imagearray[somenumber here].

can't use function more than once

For some reason i can't seem to be able use my "player" function more than once so it means i can't update it's positioning can anyone help and explain why?
heres my code:
var gridHeight = 1000, gridWidth = 1000, canvasHeight = 250, canvasWidth = 250, p = 0;
var currentPositionX = 0;
var currentPositionY = 0;
function buildGrid() {
$("body").append("<canvas></canvas").css({
height: canvasHeight,
width: canvasWidth,
border: "2px solid #000"
});
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
$("#canvas").css({height: canvasHeight, width: canvasWidth});
for (var x = 0; x <= gridWidth; x += 40) {
context.moveTo(0.5 + x + p, p);
context.lineTo(0.5 + x + p, gridHeight + p);
}
for (var x = 0; x <= gridHeight; x += 20) {
context.moveTo(p, 0.5 + x + p);
context.lineTo(gridWidth + p,x + p);
}
context.strokeStyle = "black";
context.stroke();
function player(x, y, w, h, c) {
this.x = x || 0;
this.y = y || 0;
this.h = h || 20;
this.w = w || 40;
this.c = c || "#FF0000";
}
function draw() {
player = new player();
context.fillstyle = player.c;
context.fillRect(player.x,player.y,player.w,player.h);
$("#right").on("click", function() {
player.x += player.w;
return player.x;
})
}
setInterval(draw, 500)
}
$(document).ready(function() {
buildGrid();
})
* {
padding: 0px;
margin: 0px;
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="css/game.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript" src="scripts/game.js"></script>
</head>
<body style=" background: lightblue;">
<canvas id="canvas"></canvas>
<div id="controls">
<button class="control" id="up">Up</button>
<button class="control" id="left">Left</button>
<button class="control" id="down">Down</button>
<button class="control" id="right">Right</button>
<button class="control" id="newPlayer">new player</button>
</div>
</body>
</html>
Can anyone help? My aim is make the buttons move the square around the grid. But also it have inheritable properties for further functionality late on.
player = new player(); you overwrite your function definition with the result of its execution in draw().
If you just add var in front of this line, the player var will be restricted to the scope of draw(), which might be what you want.
jsFiddle : https://jsfiddle.net/j2q2qn2e/
snippet of javascript
function player(x, y, w, h, c) {
this.x = x || 0;
this.y = y || 0;
this.h = h || 20;
this.w = w || 40;
this.c = c || "#FF0000";
}
player = new player();
...
function draw() {
context.fillstyle = player.c;
context.fillRect(player.x,player.y,player.w,player.h);
}
setInterval(draw, 3)
Basically you where creating a new player per draw, but what I have done is moved your player "class" outside of your calling functions and created it outside so we can create one basic player. I also moved your
$("#right").on("click", function() {
player.x += player.w;
return player.x;
});
to inside the jQuery doc ready because it needs to assign the event here not inside of your draw function or you would be adding multiple event listeners. So you can now use your right button correctly.

Keep track and display arrival order of array elements after animation ends in JavaScript

So, I have created an array of 10 blocks(rectangles) that move horizontally towards a "finish" line (end of canvas width) with variable speeds. I'm looking for a way to keep track of the arrival order of each array element and display it on top of each rectangle as it stops moving. I've tried using a counter and the fillText method to do that, but it only works until other elements come to a full stop and then it replaces the order. For a better view of what happens, here is my code. If anyone has any suggestions on what to use in order to fulfill my goal, it is very much appreciated. Keep in mind that I only use plain JavaScript as in no jQuery or other frameworks as I am learning the basics. Thanks in advance.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Cars</title>
<style>
canvas {
border:1px solid #3D0404;
}
h2 {
margin-left:23%;
}
</style>
<script>
var c;
var ctx;
var cars = [];
var width = 100;
var height = 100;
var x = 0;
var y = 0;
var i;
var temp;
var cw = 1000;
var ch = 1000;
window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function( callback ){
window.setTimeout(callback, 1000 / 60);
};
})();
function init() {
c = document.getElementById("myCanvas");
ctx = c.getContext("2d");
pushCar();
}
function CreateCar(x,y,width,height,speed){
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.speed = speed;
}
function pushCar(){
for (var i=0; i<10; i++){
var speed = Math.random() * 10;
var car = new CreateCar(x,y,width,height,speed);
cars.push(car);
y += 100;
}
drawAll();
}
function clear (){
ctx.clearRect (0,0,cw,ch);
}
function draw(cars){
ctx.beginPath();
ctx.fillStyle = "#f00";
ctx.fillRect(temp.x, temp.y, width, height);
ctx.strokeStyle = "#000";
ctx.outlineWidth = 2;
ctx.strokeRect(temp.x, temp.y, width, height);
ctx.closePath();
}
function drawAll(){
clear();
var z = 1;
for (var i=0; i<cars.length; i++){
temp = cars[i];
draw(temp);
if (temp.x+100 < c.width){
temp.x += temp.speed;
}else {
ctx.font = "20pt Verdana";
ctx.fillStyle = "#000";
ctx.fillText(z, 950, temp.y+55);
z++;
}
}
requestAnimFrame(drawAll, c);
}
</script>
</head>
<body onLoad = "init()">
<canvas id="myCanvas" width="1000" height="1000"></canvas>
</body>
</html>
You need to put the z variable outside the loop, and save the position of each car in an object. You also need to check if position[i] is already defined to avoid incrementing the current position more times than needed.
var z;
var position;
function drawAll() {
clear();
for (var i = 0; i < cars.length; i++) {
temp = cars[i];
draw(temp);
if (temp.x + 100 < c.width) {
temp.x += temp.speed;
} else {
if (!position[i]) {
position[i] = z;
z++;
}
ctx.font = "20pt Verdana";
ctx.fillStyle = "#000";
ctx.fillText(position[i], 950, temp.y + 55);
}
}
requestAnimFrame(drawAll, c);
}
http://jsfiddle.net/acasaccia/u2vhaqyt/

Categories

Resources