I want to draw a lot of polygons on a canvas by mouse handlers with pure Javascript language. My project is here.
In my project:
I want to finish draw and create a polygon when I do double click. (I can).
After start a drawing by one click event for make new polygon. (I can't).
When I start new draw adding new point to polygon before maked.
Thank you.
My html file is here:
<html>
<head>
<title>Orhan ALTIN</title>
<meta charset="utf-8">
<style>
canvas{
border: 5px solid;
border-color: rgb(255,173,50);
}
</style>
</head>
<body>
<canvas id="tuval" width="500" height="500"></canvas>
<script>
var tuval = document.getElementById("tuval");
var kaynak = tuval.getContext("2d");
var simdiX=[];
var simdiY=[];
var sonraX=[];
var sonraY=[];
var cizgiler=[];
var cizgi={
x1:0,
y1:0
};
var bas=0;
var fare={
xx:0,
yy:0
};
var cevre=tuval.getBoundingClientRect();
var cizimyap=false;
var yeni=0;
tuval.addEventListener("click",function temizle(olay){
cizimyap=true;
fare={
xx:olay.clientX-cevre.left,
yy:olay.clientY-cevre.top
};
cizgi.x1=fare.xx;
cizgi.y1=fare.yy;
bas=bas+1;
kaynak.moveTo(fare.xx,fare.yy);
bas++;
if(bas>1){
cizgiler.push({
xx1:cizgi.x1,
yy1:cizgi.y1,
xx2:cizgi.x2,
yy2:cizgi.y2
});
}
tuval.addEventListener("mousemove", function oynat(olay){
if (cizimyap) {
kaynak.clearRect(0,0,tuval.width,tuval.height);
kaynak.beginPath();
for (var i = 0, max = cizgiler.length; i < max; i++) {
var dizi=cizgiler[i];
kaynak.moveTo(dizi.xx2,dizi.yy2);
kaynak.lineTo(dizi.xx1,dizi.yy1);
kaynak.stroke();
simdiX.push(dizi.xx1);
simdiY.push(dizi.yy1);
}
kaynak.moveTo(fare.xx,fare.yy);
kaynak.lineTo(olay.clientX-cevre.left,olay.clientY-cevre.top);
kaynak.stroke();
}
});
tuval.addEventListener("dblclick", function(){
cizimyap=false;
poligonYap(olay);
});
});
function poligonYap(olay){
simdiX.splice(simdiX.length-1,1,simdiX[0]);
simdiY.splice(simdiY.length-1,1,simdiY[0]);
kaynak.clearRect(0,0,tuval.width,tuval.height);
for (var i = 0, max = cizgiler.length; i < max; i++) {
//var dizi=cizgiler[i];
kaynak.strokeStyle="green";
kaynak.lineWidth="1";
kaynak.lineCap="round";
sonraX[i]=simdiX[i];
sonraY[i]=simdiY[i];
kaynak.lineTo(sonraX[i],sonraY[i]);
kaynak.stroke();
}
for (var i = 0, max = cizgiler.length-1; i < max; i++) {
kaynak.fillStyle="blue";
kaynak.fillRect(cizgiler[i].xx1-5/2,cizgiler[i].yy1-5/2,5,5);
kaynak.font="12px Tahoma";
kaynak.fillStyle="red";
kaynak.fillText(i+1,cizgiler[i].xx1,cizgiler[i].yy1-5);
}
}
</script>
</body>
Related
I am Japanese and I apologize for my unnatural English, but I would appreciate it if you could read it.
I learned how to convert paperscript to javascript from the official documentation.
Its means are as follows
Change the type attribute of the script tag to text/paperscript. <script type="text/paperscript" src="./main.js"></script>
Enable Paperscope for global use.  paper.install(window)
Specify the target of the canvas. paper.setup(document.getElementById("myCanvas"))
Write the main code in the onload window.onload = function(){ /* add main code */ }
Finally, add paper.view.draw()
The onFrame and onResize transforms as follows. view.onFrame = function(event) {}
onMouseDown, onMouseUp, onMouseDrag, onMouseMove, etc. are converted as follows. var customTool = new Tool(); customTool.onMouseDown = function(event) {};
I have tried these methods, but applying these to the Examples on the paper.js official site does not work correctly.
The following code is the result of trying these.
<!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">
<script type="text/javascript" src="https://unpkg.com/paper"></script>
<script type="text/javascript" src="./main.js"></script>
<title>Document</title>
</head>
<body>
<canvas id="myCanvas"></canvas>
</body>
</html>
paper.install(window);
console.log("run test")
var myCanvas = document.getElementById("myCanvas")
var customTool = new Tool();
window.onload = function(){
paper.setup(myCanvas)
var points = 25;
// The distance between the points:
var length = 35;
var path = new Path({
strokeColor: '#E4141B',
strokeWidth: 20,
strokeCap: 'round'
});
var start = view.center / [10, 1];
for (var i = 0; i < points; i++)
path.add(start + new Point(i * length, 0));
customTool.onMouseMove=function(event) {
path.firstSegment.point = event.point;
for (var i = 0; i < points - 1; i++) {
var segment = path.segments[i];
var nextSegment = segment.next;
var vector = segment.point - nextSegment.point;
vector.length = length;
nextSegment.point = segment.point - vector;
}
path.smooth({ type: 'continuous' });
}
customTool.onMouseDown=function(event) {
path.fullySelected = true;
path.strokeColor = '#e08285';
}
customTool.onMouseUp=function(event) {
path.fullySelected = false;
path.strokeColor = '#e4141b';
}
view.draw();
}
The original paperscript can be found here.
What is the problem with this code?
Thank you for reading to the end!
The var vector in the for loop is not getting the correct values in your code. Change the math operators and it will work like the paperjs demo.
Math operators (+ - * /) for vector only works in paperscript. In Javascript, use .add() .subtract() .multiply() .divide(). see http://paperjs.org/reference/point/#subtract-point
// paperscript
segment.point - nextSegment.point
// javascript
segment.point.subtract(nextSegment.point)
Here's a working demo of your example
paper.install(window);
console.log("run test")
var myCanvas = document.getElementById("myCanvas")
var customTool = new Tool();
window.onload = function() {
paper.setup(myCanvas)
var points = 15; //25
// The distance between the points:
var length = 20; //35
var path = new Path({
strokeColor: '#E4141B',
strokeWidth: 20,
strokeCap: 'round'
});
var start = view.center / [10, 1];
for (var i = 0; i < points; i++) {
path.add(start + new Point(i * length, 0));
}
customTool.onMouseMove = function(event) {
path.firstSegment.point = event.point;
for (var i = 0; i < points - 1; i++) {
var segment = path.segments[i];
var nextSegment = segment.next;
//var vector = segment.point - nextSegment.point;
var vector = segment.point.subtract(nextSegment.point);
vector.length = length;
//nextSegment.point = segment.point - vector;
nextSegment.point = segment.point.subtract(vector);
}
path.smooth({
type: 'continuous'
});
}
customTool.onMouseDown = function(event) {
path.fullySelected = true;
path.strokeColor = '#e08285';
}
customTool.onMouseUp = function(event) {
path.fullySelected = false;
path.strokeColor = '#e4141b';
}
view.draw();
}
html,
body {
margin: 0
}
canvas {
border: 1px solid red;
}
<!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">
<script type="text/javascript" src="https://unpkg.com/paper"></script>
<!-- you can add this back in -->
<!-- <script type="text/javascript" src="./main.js"></script> -->
<title>Document</title>
</head>
<body>
<!-- set any size you want, or use CSS/JS to make this resizable -->
<canvas id="myCanvas" width="600" height="150"></canvas>
</body>
</html>
I have a question about count pixels of an image in Canvas, please see code below:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Pixel Counting</title>
<script type="text/javascript">
window.onload = function() {
var img = new Image();
img.src="lena.jpg";
img.onload = function() {
countPixel(img)
};
}
function countPixel(img) {
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
// Draw the image to canvas.
context.drawImage(img, 0, 0);
// Now we can get the image data from the canvas.
var imageData = context.getImageData(0, 0, img.width, img.height);
var data = imageData.data;
// Do the pixel counting.
var redCount = new Array(256);
var greenCount = new Array(256);
var blueCount = new Array(256);
for (var i = 0; i < 256; i++) {
redCount[i] = 0;
greenCount[i] = 0;
blueCount[i] = 0;
}
for (var i = 0; i < data.length; i += 4) {
redCount[data[i]]++; // red
greenCount[data[i + 1]]++; // green
blueCount[data[i + 2]]++; // blue
}
// Write the result to table.
var pixelTable = document.getElementById('pixel_table');
for (var i = 0; i < 256; i++) {
var row = pixelTable.insertRow(-1);
row.insertCell(-1).innerHTML = i;
row.insertCell(-1).innerHTML = redCount[i];
row.insertCell(-1).innerHTML = greenCount[i];
row.insertCell(-1).innerHTML = blueCount[i];
}
}
</script>
</head>
<body>
<div>
<canvas id="canvas" width="500" height="500">
</canvas>
</div>
<div>
<table id="pixel_table" border="1">
<caption style="font-size:25px;font-weight:bold;">Pixel Count</caption>
<tr id="header"><th>Intensity</th><th>Red</th><th>Green</th><th>Blue</th></tr>
</table>
</div>
</body>
</html>
I do not understand this for loop:
for (var i = 0; i < 256; i++) {
redCount[i] = 0;
greenCount[i] = 0;
blueCount[i] = 0;
}
What does this loop here mean? This is the beginning part of the count, but why make all value to zero?
It's needed as none of the elements in the declared array are defined at that point. The loop starts at first element in the array, then goes through each single one to set an initial value to 0 (otherwise it would be undefined which would give you problems later when you try to add a number to it).
However, the better option in this case, is to replace this block:
var redCount = new Array(256);
var greenCount = new Array(256);
var blueCount = new Array(256);
for (var i = 0; i < 256; i++) {
redCount[i] = 0;
greenCount[i] = 0;
blueCount[i] = 0;
}
with typed arrays, which do have all their values initialized to 0 as well as being faster than node-based arrays:
var redCount = new Uint32Array(256);
var greenCount = new Uint32Array(256);
var blueCount = new Uint32Array(256);
If you don't do that the array will be filled with undefined values.
new Array(5);
will result in:
[undefined, undefined, undefined, undefined, undefined]
I've been trying to create a game with falling blocks that will stack on top of each other. The blocks will fall into one of 6 columns and need to stop falling down the screen when they collide with the top block on that column. I've been trying to get the y-coordinate of the top block, but that causes a problem because its still getting the newest created block and not the last finished block. Any help would be greatly appreciated!
var FPS = 60;
setInterval(function() {
//update();
draw();
}, 1000/FPS);
var y = 30;
//draw the screen
function draw() {
if(+new Date() > lastTime + minWait){
var column = Math.floor(Math.random()*6)
lastTime = +new Date();
blocks.push(new Block(5 + column*40, 30,40,40, 5, "red","black"));
}
context.clearRect(0,0,canvas.width, canvas.height);
blocks.forEach(function(e){
e.update();
e.render();
});
};
var blocks = [];
var lastTime = +new Date();
var minWait = 1000;
var topBlock = 310;
function columnTop(column){
for(var i=0; i < blocks.length; i++){
if(blocks[i].x === (5 + 40*columnTop)){
if(blocks[i].y < topBlock){
topBlock = blocks[i].y
}
}
}
}
//block functions
Block.prototype.update = function(){
var topCol1 = columnTop(1);
var topCol2 = columnTop(2);
var topCol3 = columnTop(3);
var topCol4 = columnTop(4);
var topCol5 = columnTop(5);
var topCol6 = columnTop(6);
if(this.y < 310){
this.y+= this.dy
}else{
this.dy = 0;
}
};
Block.prototype.render = function(){
Block(this.x, this.y, this.w, this.h, this.r, this.fillstyle, this.strokestyle);
};
Maintain a maximum-Y value for each column.
maximum-Y is the y-position of the last stacked block.
Whenever a block exceeds the maximum-Y, force that block to sit atop the maximum-Y.
Then reduce maximum-Y by that blocks height.
if( block.y + block.height > maxY ){
block.y = maxY - block.height;
maxY = block.y;
}
Here's code and a Demo: http://jsfiddle.net/m1erickson/FMv2q/
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" />
<script src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; }
canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
function Blocks(floor,colCount){
this.blocks=[];
this.floor=floor;
this.cols=[];
this.continueRAF=true;
for(var i=0;i<colCount;i++){
this.cols.push({maxY:floor,needsNewBlock:true});
}
}
function animate(){
if(blocks.continueRAF){ requestAnimationFrame(animate); }
for(var i=0;i<blocks.cols.length;i++){
if(blocks.cols[i].needsNewBlock){
blocks.cols[i].needsNewBlock=false;
blocks.blocks.push(new Block(i));
}
}
ctx.clearRect(0,0,canvas.width,canvas.height);
var fallingCount=0;
for(var i=0;i<blocks.blocks.length;i++){
var block=blocks.blocks[i];
fallingCount+=block.fall();
ctx.fillStyle=block.fill;
ctx.fillRect(block.x,block.y,block.w,block.h);
}
if(fallingCount==0 && blocks.continueRAF){
blocks.continueRAF=false;
alert("All done after "+blocks.blocks.length+" blocks fell.");
}
}
function Block(column){
this.column=column;
this.x=this.column*50;
this.w=parseInt(Math.random()*20+15);
this.h=parseInt(Math.random()*15+5);
this.y=-this.h;
this.vy=parseInt(Math.random()*3+4);
this.fill=randomColor();;
this.isFalling=true;
}
Block.prototype.fall=function(){
if(!this.isFalling){return(0);}
var col=blocks.cols[this.column];
if(this.y+this.h+this.vy>col.maxY){
this.isFalling=false;
this.y=col.maxY-this.h;
col.maxY=this.y;
if(col.maxY>35){
col.needsNewBlock=true;
}
}else{
this.y+=this.vy;
}
return(1);
}
var blocks=new Blocks(350,6);
animate();
function randomColor(){
return('#'+Math.floor(Math.random()*16777215).toString(16));
}
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas" width=350 height=350></canvas>
</body>
</html>
So I have this game where a worm eats his food, food randomly spawns on load but I want it to disappear onmouseover and spawn again in another spot but I have no idea what to do :c Didn't find any info on the internet either, tho not quitet sure what to search for.
p.s. made this question again because last time people hated it because they thought that I don't have anything done. Thanx
<!doctype html>
<html>
<head>
<title>Ussi l6una</title>
<script>
var kohad=new Array();
var pikkus=1, d=6, kogus=300;
var ballx=0, step=100;
var bally=0, step=100;
var monsterx=(step*parseInt(8*Math.random())), step=100;
var monstery=(step*parseInt(8*Math.random()));
function toit(){
var c=document.getElementById("tahvel");
var ctx=c.getContext("2d");
ctx.beginPath();
ctx.fillStyle = 'darkblue';
ctx.arc(monsterx+30, monstery+30, 25, 0, 2 * Math.PI, false);
ctx.fill();
ctx.lineWidth = 0;
ctx.strokeStyle = '#000000';
}
function devouring(){
if(toitx==mousex && toity==mousey){
toitx=step*parseInt(5*Math.random());
toity=step*parseInt(5*Math.random());
toit();
}
}
function looKohad(){
for(var i=0; i<kogus; i++){
kohad[i]=new Array(pikkus*i, 1200);
}
}
function arvutaUusTagumine(eesmine, tagumine){
var kaugus=new Array();
kaugus[0]=eesmine[0]-tagumine[0];
kaugus[1]=eesmine[1]-tagumine[1];
var kogukaugus=Math.sqrt(kaugus[0]*kaugus[0]+kaugus[1]*kaugus[1]);
var nihe=kogukaugus-pikkus;
var dx=kaugus[0]*nihe/kogukaugus;
var dy=kaugus[1]*nihe/kogukaugus;
return new Array(tagumine[0]+dx, tagumine[1]+dy);
}
function arvutaUuedKohad(){
console.log(kohad);
for(var i=1; i<kogus; i++){
kohad[i]=arvutaUusTagumine(kohad[i-1], kohad[i]);
}
}
function joonistaKohad(g){
for(var i=0; i<kogus; i++){
joonistaKoht(g, kohad[i])
}
}
function joonistaKoht(g, koht){
g.beginPath();
g.arc(koht[0], koht[1], d, 0, 2*Math.PI, true);
g.stroke();
}
function hiirLiigub(e){
var t=document.getElementById("tahvel");
var g=t.getContext("2d");
var tahvlikoht=t.getBoundingClientRect();
kohad[0][0]=e.clientX-tahvlikoht.left;
kohad[0][1]=e.clientY-tahvlikoht.top;
arvutaUuedKohad();
g.strokeStyle="#CC9966";
g.fillStyle="#CC9966";
g.clearRect(0, 0, t.width, t.height);
joonistaKohad(g);
toit();
}
looKohad();
</script>
</head>
<body onLoad="toit();">
<canvas id="tahvel" width="800" height="800" style="background-color:white" onmousemove="hiirLiigub(event)" onmouseover="this.style.backgroundImage = 'url(./dirt.png)'"></canvas><br />
</body>
</html>
This question already has answers here:
Javascript SetTimeout and Loops [duplicate]
(3 answers)
Closed 9 years ago.
I have researched a lot, mostly in SO, about setTimeout being "not blocking", and so being not suitable to be used inside a for loop, since the loop keeps going on and one while the function calls keep building up.
I have an HTML file which documents an image processing algorithm, so I want to display the active pixels "walking" in a "human-readable" speed. The implementation I tried and does not work is the following:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
</head>
<body onload="run();">
<canvas id="Canvas" width=501 height=601></canvas>
<script>
function run() {
reevaluate();
};
var fixedcenteri;
var fixedcenterj;
function reevaluate() {
var altura_imagem = 50;
var largura_imagem = 40;
for (var i = 0; i < altura_imagem; i++) {
for (var j = 0; j < largura_imagem; j++) {
fixedcenteri = i;
fixedcenterj = j;
setTimeout(draw, 100);
// if I uncomment this I can see what I want, but...
// alert(i+j);
};
};
};
function draw () {
var elem = document.getElementById('Canvas');
var cx = elem.getContext('2d');
w = elem.width;
h = elem.height;
cx.fillStyle = "white";
cx.fillRect(0,0,w,h);
cx.fillStyle = 'blue';
cx.fillRect(fixedcenteri, fixedcenterj, 10, 10);
}
</script>
</body>
</html>
Try RequestAnimationFrame!
RequestAnimationFrame is asynchronous just like setTimeout and it's more efficient than setTimeout.
In addition, it offers animation grouping and auto-stop for off-screen animations.
You can even throttle it to your desired FPS using this technique:
var fps = 15;
function draw() {
setTimeout(function() {
requestAnimationFrame(draw);
// your draw() stuff goes here
}, 1000 / fps);
}
The easiest implementation would be to store all you draw commands in an array and then process that array using setTimeout to wait between draw commands.
Here's a quick example -> http://jsfiddle.net/K4D84/
//in your initial loop instead of draw
drawCommands.push({i: i, j: j});
Then...
function slowDraw(index) {
index = index || 0;
var drawCommand = drawCommands[index];
if (drawCommand) {
fixedcenteri = drawCommand.i;
fixedcenterj = drawCommand.j;
setTimeout(function () {
draw();
slowDraw(++index);
}, 100);
}
}
I think this does what you are looking for.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
</head>
<body onload="draw();">
<canvas id="Canvas" width=501 height=601></canvas>
<script>
var fixedcenteri = 0;
var fixedcenterj = 0;
function draw () {
var elem = document.getElementById('Canvas');
var cx = elem.getContext('2d');
w = elem.width;
h = elem.height;
cx.fillStyle = "white";
cx.fillRect(0,0,w,h);
cx.fillStyle = 'blue';
cx.fillRect(fixedcenteri, fixedcenterj, 10, 10);
if(fixedcenteri < 50) {
if(fixedcenterj < 40) {
fixedcenterj++;
} else {
fixedcenterj = 0;
fixedcenteri++;
}
setTimeout(draw, 100);
}
}
</script>