Drawing a Dot on HTML5 Canvas

Drawing a dot on HTML5 canvas

For performance reasons, don't draw a circle if you can avoid it. Just draw a rectangle with a width and height of one:

ctx.fillRect(10,10,1,1); // fill in the pixel at (10,10)

Draw dots on html5 canvas

Here i created a simple example. Hope it'd be helpful to you.

  var canvas = document.getElementById('mycanvas');

var context = canvas.getContext('2d');

var sizeX = canvas.width / 10;

var sizeY = canvas.height / 10;

var total = 15;

var count = 0;

for (var j = 0; j < 10; j++) {

for (var i = 0; i < 10; i++) {

context.beginPath();

context.arc(sizeX * (i+.5), sizeY * (j+.5), sizeX / Math.PI, 0, 2 * Math.PI, false);

context.fillStyle = total > count ? 'green' : 'red';

context.fill();

count++;

}

}
<canvas id="mycanvas" width="200" height="200" style="border:1px solid black;"></canvas>

Drawing with touch html canvas only drawing dots

Seems like the canvase_touchStart event is causing the issue.

You may remove the line canvas.addEventListener('touchstart', canvase_touchStart, false); and the corresponding function function canvases_touchStart() {...}

CODEPEN

Hope this helps.

PS: To know how to create a smoother effect, you may refer to this CODEPEN as well.

Drawing a path of points html canvas

Your improvement idea is great. You can indeed have two canvases!

There are two ways to go about it.

Offscreen canvas

Using what's called an offscreen canvas (a canvas that is created in JavaScript but not added to the DOM), you can draw all the points onto it and then using drawImage (which can accept a canvas element) pass the canvas to the main context.

var offscreenCanvas = document.createElement('canvas');
var offscreenC = offscreenCanvas.getContext('2d');

offscreenCanvas.width = canvas.width;
offscreenCanvas.height = canvas.height;

// in animate function, draw points onto the offscreen canvas instead
// of the regular canvas as they are added
if(trace.includes([x2, y2]) != true){
trace.push([x2,y2]);
var i = trace.length-1;

if (i > 1) {
offscreenC.strokeStyle = 'white'
offscreenC.beginPath();
offscreenC.moveTo(trace[i][0], trace[i][1])
offscreenC.lineTo(trace[i-1][0], trace[i-1][1])
offscreenC.stroke();
}
}

c.drawImage(offscreenCanvas, 0, 0);

Layered Canvases

One of the downsides to the offscreen canvas approach is that you have to draw it to the main canvas every frame. You can further improve the approach by layering two canvases on top of one another, where the top one is just the pendulum and the bottom one the trace.

This way, you never have to redraw the offscreen canvas onto the main canvas, and save yourself some rendering time.

Updated jsfiddle

Drawing on canvas with opacity (dots in line) javascript

Yes, that is to be expected as each line is overdrawn at the connection points, and their alpha data will add up.

I would suggest the following approach and attach a proof-of-concept demo at the end, feel free to adopt that code to your project:

  1. Create two canvases, one main and one draft on top
  2. Set the alpha directly on the top element using CSS (opacity) and always keep globalAlpha=1
  3. For each stroke (pen down, pen up) draw on draft canvas (use lines between each point)
  4. On pen up, set globalAlpha on main canvas equal the CSS opacity of top canvas
  5. Draw top canvas to main canvas using drawImage().
  6. Clear top canvas, eat, sleep, repeat (from 3).

Proof-of-concept

var draft = document.getElementById("draft");

var main = document.getElementById("main");

var ctx = draft.getContext("2d");

var mctx = main.getContext("2d");

var isDown = false, prev, alpha = 0.4;

// setup pen

ctx.strokeStyle = "rgb(0,200,127)";

ctx.lineWidth = 16;

ctx.lineCap = "round"; // important to make lines cont.

// set up alpha

draft.style.opacity = alpha; // CSS alpha for draft

mctx.globalAlpha = alpha; // context alpha for main

draft.onmousedown = function(e){

isDown = true;

prev = getXY(e); // set prev. point as start

};

window.onmousemove = function(e){

if (!isDown) return;

var point = getXY(e);

ctx.beginPath(); // new path

ctx.moveTo(prev.x, prev.y); // start at prev. point

ctx.lineTo(point.x, point.y); // line to new point

ctx.stroke(); // stroke

prev = point; // update prev. point

};

window.onmouseup = function(){

isDown = false; // when up:

mctx.drawImage(draft, 0, 0); // copy drawing to main

ctx.clearRect(0, 0, draft.width, draft.height); // clear draft

};

function getXY(e) {

var r = draft.getBoundingClientRect();

return {x: e.clientX - r.left, y: e.clientY - r.top}

}
#draft {cursor:crosshair}

.sandwich {position:relative}

.sandwich>canvas {position:absolute;left:0;top:0}
<div class="sandwich">

<canvas id="main" width=600 height=600></canvas>

<canvas id="draft" width=600 height=600></canvas>

</div>

How to draw points and connect them with lines HTML on click

I would recomend using the Canvas.. You could do something like this

// HTML
<canvas id="canvas"></canvas>
// Javascript
var canvas = document.querySelector("#canvas");
var ctx = canvas.getContext('2d');
var Points = []; //The points are stored in a object array {x,y}

var Redraw = ()=>{
ctx.clearRect(0, 0, canvas.width, canvas.height);
Points.forEach((point, index, arr) => {

// This is what adds the dots on the canvas
ctx.beginPath();
ctx.arc(point.x, point.y, 2, 0, 2 * Math.PI);
ctx.fill();

if(arr.length > 1){
if(index == arr.length -1){
// This connects the last point to the first
ctx.beginPath();
ctx.moveTo(point.x, point.y);
ctx.lineTo(arr[0].x, arr[0].y);
ctx.stroke();
}
else{
// Connects the current point to the next
ctx.beginPath();
ctx.moveTo(point.x, point.y);
ctx.lineTo(arr[index + 1].x, arr[index + 1].y);
ctx.stroke();
}
}
});

}

canvas.addEventListener("click", e=> {
// Every time the canvas is clicked add the point to the Point Array
// And Redraw it
Points.push({x: e.clientX, y: e.clientY});

Redraw();
})

Redraw();

By using the Canvas Documentation you should be able to add the colors in the shapes.. This would be done by drawing the outline of the shape with the LineTo command and filling the object in stead of stroking, since that would just draw the shape

Notice in the code above that i choose to draw each line individualy in stead of the whole shape which would be ideal, but doing it this way is easier to undestand

Hope it helps..

- Steinar


Edit

Felt Bad for not completing the code.. Sorry..

var canvas = document.querySelector("#canvas");
var ctx = canvas.getContext('2d');
var Points = [{x:100, y:100}, {x:20, y:200}]

var Update = ()=>{
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Draw the shape
ctx.beginPath();
Points.forEach((point, index, arr) => {
if(arr.length > 1){

if(index == 0)
ctx.moveTo(point.x, point.y);

if(index != arr.length -1)
ctx.lineTo(arr[index + 1].x, arr[index + 1].y);

}
});
ctx.fillStyle = "#ddf7f7"; //this is the shapes color
ctx.closePath();
ctx.fill();
ctx.stroke();

// Draw the dots, this should be done last due to then they are above the path
ctx.fillStyle = "#000"
Points.forEach((point, index, arr) => {
ctx.beginPath();
ctx.arc(point.x, point.y, 2, 0, 2 * Math.PI);
ctx.fill();
});

}

canvas.addEventListener("click", e=> {
Points.push({x: e.offsetX, y: e.offsetY});
Update();
})

Update();

Spotted an error in the first verson of the code, I used clientX and clientY, it should have been offsetX and offseY.

You might also notice that in the Draw Shape part of the code, i did not use { and }, this is because when you have a if statment which only runs one line of code they are unnecessary



Related Topics



Leave a reply



Submit