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:
- Create two canvases, one main and one draft on top
- Set the alpha directly on the top element using CSS (opacity) and always keep
globalAlpha=1
- For each stroke (pen down, pen up) draw on draft canvas (use lines between each point)
- On pen up, set
globalAlpha
on main canvas equal the CSS opacity of top canvas - Draw top canvas to main canvas using
drawImage()
. - 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
Why Does CSS Padding Increase Size of Element
Making a Paragraph in HTML Contain a Text from a File
Ios7 Font Size Change When Create Nsattributedstring from HTML
How to Display Text, a Dotted Line Then More Text Spanning the Width of the Page
Convert Attributed String, To, "Simple" Tagged HTML
Why Is 100% Height Not 100% of the Browser Height
Darken a Background Image Without Affecting the Text
Fill Svg Element with With a Background-Image with an Offset
Absolute Position and Overflow:Hidden
How to Detect HTML 5 Compatibility in Browser
How to Indent Multiple Levels of Select Optgroup with CSS
How to Make Images Stay Within the Rows of a CSS Grid Container
Border Corner Shape Scoop Doesn't Work