Como os anticipe, al final de mi página canvas, tenía que hacer esta página, combinándo la etiqueta canvas, con animaciones implementadas, con un poco de javascript, ya que esta es una de las principales virtudes del elemento canvas.
Ejemplos de canvas animados de este sitio que os voy a ir mostrándo en contenedores de código, que he construido, como un web component, en los que podeís exáminar todo el código del ejemplo y la propia demo.
Para este canvas se emplean los eventos mousemove y mouseout, ya sabeís, similar al :hover, de CSS.
<body style="margin: 0;">
<canvas id="canvas"></canvas>
</body>
let canvas = document.getElementById("canvas");
let c = canvas.getContext("2d");
let radius = 15;
function drawCircle(mouseX, mouseY){
// Resize to the screen
if(canvas.width != window.innerWidth || canvas.width != window.innerWidth){
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
}
// Limpia el background
c.clearRect(0, 0, canvas.width, canvas.height);
// Dibuja el circulo
c.beginPath();
c.arc(mouseX, mouseY, radius, 0 , 2 * Math.PI, false);
// Relleno del circulo
c.fillStyle = '#00F0FF';
c.fill();
// Borde (stroke) del circulo
c.lineWidth = 2;
c.strokeStyle = 'black';
c.stroke();
}
// función que va redibujando el circulo al movimiento del ratón (cursor)
canvas.addEventListener('mousemove',function(e){
drawCircle(e.clientX, e.clientY);
});
// Limpia el canvas cuando el ratón sale del canvas
canvas.addEventListener('mouseout',function(e){
c.clearRect(0, 0, canvas.width, canvas.height);
});
// Dibuja un circulo en el centro inicialmente
drawCircle(canvas.width / 2, canvas.height / 2);
<body>
<canvas id="canvas"></canvas>
<script src="/assets/js/modulos/requestAnimFrame.js"></script>
</body>
let canvas = document.getElementById("canvas");
let c = canvas.getContext("2d");
let radius = 32;
let lineWidth = 4;
let gravity = 0.1;
let dampening = 0.995;
let mousePullStrength = 0.005;
let animate = false;
let mouse = {
x : 0,
y : 0,
down: false
};
let circle = {
x : canvas.width/2,
y : canvas.height/2,
vx: 0, // 'v' stands for 'velocity'
vy: 0
};
function executeFrame() {
if(animate)
requestAnimFrame(executeFrame);
incrementSimulation();
c.clearRect(0, 0, canvas.width, canvas.height);
drawBox();
drawCircle();
if(mouse.down) drawLineToMouse();
}
function incrementSimulation() {
// Pull the circle toward the mouse
if(mouse.down) {
let dx = mouse.x - circle.x,
dy = mouse.y - circle.y,
distance = Math.sqrt(dx*dx + dy*dy),
unitX = dx / distance,
unitY = dy / distance,
force = distance * mousePullStrength;
circle.vx += unitX * force;
circle.vy += unitY * force;
}
// Execute gravity
circle.vy += gravity;
// Execute dampening (slowing down)
circle.vx *= dampening;
circle.vy *= dampening;
// Increment the position by the velocity
circle.x += circle.vx;
circle.y += circle.vy;
// Bounce off the floor
if(circle.y + radius > canvas.height) {
circle.y = canvas.height - radius;
circle.vy = - Math.abs(circle.vy);
}
// Bounce off the ceiling
else if(circle.y - radius < 0) {
circle.y = radius;
circle.vy = Math.abs(circle.vy);
}
// Bounce off the right wall
if(circle.x + radius > canvas.width) {
circle.x = canvas.width - radius;
circle.vx = - Math.abs(circle.vx);
}
// Bounce off the left wall
else if(circle.x - radius < 0) {
circle.x = radius;
circle.vx = Math.abs(circle.vx);
}
}
function drawBox(){
// Resize to the screen
if(canvas.width != window.innerWidth || canvas.width != window.innerWidth) {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
}
c.lineWidth = 1;
c.strokeRect(0.5, 0.5, canvas.width - 1, canvas.height - 1);
}
function drawCircle(){
c.beginPath();
c.arc(circle.x, circle.y, radius - lineWidth/2, 0 , 2 * Math.PI, false);
c.fillStyle = '#00F0FF';
c.fill();
c.lineWidth = 4;
c.strokeStyle = 'black';
c.stroke();
}
function drawLineToMouse() {
c.lineWidth = 2;
c.moveTo(circle.x, circle.y);
c.lineTo(mouse.x, mouse.y);
c.stroke();
}
canvas.addEventListener('mousedown',function(e) {
mouse.down = true;
mouse.x = e.pageX;
mouse.y = e.pageY;
});
canvas.addEventListener('mousemove', function(e) {
mouse.x = e.pageX;
mouse.y = e.pageY;
});
canvas.addEventListener('mouseup', function(e) {
mouse.down = false;
});
// Start animating when the mouse enters the canvas
canvas.addEventListener('mouseover', function(e) {
animate = true;
executeFrame();
});
// Stop animating when the mouse exits the canvas
canvas.addEventListener('mouseout', function(e) {
mouse.down = false;
animate = false;
});
// Draw the initial scene once, so something
// is displayed before animation starts.
executeFrame();
<body>
<canvas id="canvas"></canvas>
<script src="/assets/js/modulos/requestAnimFrame.js"></script>
</body>
let canvas = document.getElementById("canvas");
let c = canvas.getContext("2d");
let gravity = 0.1;
let radius = 20;
let numCircles = 10;
let dampeningFactor = 0.99;
let circles = [];
let i, j, circle, circle2;
let mouse = {
x: 0,
y: 0,
down: false
};
let circleUnderMouse;
let ballMouseY, ballMouseX, pullForceY, pullForceX;
let r, g, b;
let animate = false;
initializeCircles();
function executeFrame() {
if(animate) requestAnimFrame(executeFrame);
iterateSimulation();
c.fillStyle = 'rgba(255,255,255,0.3)';
c.fillRect(0,0,canvas.width,canvas.height);
drawCircles();
}
function initializeCircles() {
circles = [];
for(i = 0; i < numCircles; i++){
circle = {
x: Math.random() * canvas.width,
y: Math.random() * canvas.height,
velocity:{x:0, y:0}
};
circles.push(circle);
}
}
function drawCircles() {
// Resize to the screen
if(canvas.width != window.innerWidth || canvas.width != window.innerWidth) {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
initializeCircles();
iterateSimulation();
}
// draw rectangle border
c.lineWidth = "3";
c.strokeRect(0,0,canvas.width,canvas.height);
// draw circles
for(i = 0; i < numCircles; i++) {
circle = circles[i];
r = i * 5;
g = i * 10;
b = i * 15;
// draw connecting line from ball to mouse
if(circle == circleUnderMouse) {
c.beginPath();
c.moveTo(circle.x, circle.y);
c.lineTo(mouse.x, mouse.y);
c.lineWidth = "2";
c.strokeStyle="black";
c.stroke();
}
c.beginPath();
c.arc(circle.x, circle.y, radius, 0, 2 * Math.PI);
if(circle == circleUnderMouse) {
c.fillStyle = "#C1FF24";
c.lineWidth = "5";
c.stroke();
}
else c.fillStyle = 'rgb('+r+', '+g+', '+b+')';
c.fill();
}
}
function iterateSimulation() {
for(i = 0; i < numCircles; i++){
circle = circles[i];
// pull ball to mouse
pullBallToMouse();
// Add gravity
circle.velocity.y += gravity;
// slows things down
circle.velocity.x *= dampeningFactor;
circle.velocity.y *= dampeningFactor;
// Add velocity to position
circle.x += circle.velocity.x;
circle.y += circle.velocity.y;
// Make them bounce off the floor
if(circle.y > canvas.height - radius) {
circle.y = canvas.height - radius;
circle.velocity.y = - Math.abs(circle.velocity.y);
}
// bounce off ceiling
if(circle.y < radius) {
circle.y = radius;
circle.velocity.y = Math.abs(circle.velocity.y);
}
// bounce off right wall
if(circle.x > canvas.width - radius) {
circle.x = canvas.width - radius;
circle.velocity.x = -Math.abs(circle.velocity.x);
}
// bounce off left wall
if(circle.x < radius) {
circle.x = radius;
circle.velocity.x = Math.abs(circle.velocity.x);
}
// REPULSION between circles
for(j = i + 1; j < numCircles; j++) {
circle2 = circles[j];
let dx = circle2.x - circle.x;
let dy = circle2.y - circle.y;
let d = Math.sqrt(dx*dx + dy*dy);
if(d < 2*radius) {
if(d === 0) d = 0.1;
let unitX = dx/d;
let unitY = dy/d;
let force = -2;
let forceX = unitX * force;
let forceY = unitY * force;
circle.velocity.x += forceX;
circle.velocity.y += forceY;
circle2.velocity.x -= forceX;
circle2.velocity.y -= forceY;
}
}
}
}
function pullBallToMouse() {
if(circle == circleUnderMouse) {
ballMouseY = mouse.y - circle.y;
ballMouseX = mouse.x - circle.x;
pullForceY = ballMouseY * 0.02;
pullForceX = ballMouseX * 0.02;
circle.velocity.y += pullForceY;
circle.velocity.x += pullForceX;
}
}
canvas.addEventListener("mousemove", function(e) {
mouse.x = e.x;
mouse.y = e.y;
});
canvas.addEventListener("mousedown", function(e) {
mouse.down = true;
mouse.x = e.x;
mouse.y = e.y;
for(i = 0; i < circles.length; i++) {
let circle = circles[i]; // get circle out of array
let dx = mouse.x - circle.x;
let dy = mouse.y - circle.y;
let d = Math.sqrt(dx*dx + dy*dy);
if(d < radius){
circleUnderMouse = circle;
break; // break (stop) the for loop
}
}
});
canvas.addEventListener("mouseup", function(e) {
mouse.down = false;
circleUnderMouse = null;
});
canvas.addEventListener("mouseout", function(e) {
mouse.down = false;
circleUnderMouse = null;
});
// Kick off the animation when the mouse enters the canvas
canvas.addEventListener('mouseover', function(e) {
animate = true;
executeFrame();
});
// Pause animation when the mouse exits the canvas
canvas.addEventListener("mouseout",function(e) {
animate = false;
});
// Draw the first frame to start animation
executeFrame();
<body>
<canvas id="canvas" width="400" height="400"></canvas>
</body>
let canvas = document.getElementById("canvas");
let c = canvas.getContext("2d");
let centerX = canvas.width / 2;
let trunkHeight = 100;
let branchLengthRatio = 0.75;
let branchAngleDifference = 0.27;
let branchingDepth = 10;
function drawTree(x1, y1, x2, y2, branchLength, branchAngle, depth) {
if(depth == 0) return;
else {
c.beginPath();
c.moveTo(x1, y1);
c.lineTo(x2, y2);
c.closePath();
c.stroke();
branchLength *= branchLengthRatio;
function branch(angle) {
let branchX2 = x2 + branchLength * Math.cos(angle);
let branchY2 = y2 + branchLength * Math.sin(angle);
drawTree(x2, y2, branchX2, branchY2, branchLength, angle, depth - 1);
}
// Right branch
branch(branchAngle + branchAngleDifference);
// Left branch
branch(branchAngle - branchAngleDifference);
}
}
function redrawTree() {
c.clearRect(0,0, canvas.width, canvas.height);
let x1 = centerX;
let y1 = canvas.height;
let x2 = centerX;
let y2 = canvas.height - trunkHeight;
drawTree(x1, y1, x2, y2, trunkHeight, - Math.PI / 2, branchingDepth);
}
canvas.addEventListener("mousemove",function(e) {
branchLengthRatio = e.x / 300;
branchAngleDifference = e.y / canvas.height * Math.PI;
redrawTree();
console.log("branchLengthRatio = "+branchLengthRatio);
console.log("branchAngleDifference = "+branchAngleDifference);
});
redrawTree();
<body>
<canvas id="canvas"></canvas>
<button type="button" class="btn" id="fullscr">Go Fullscreen</button>
<script src="/assets/js/modulos/requestAnimFrame.js"></script>
<script src="/assets/js/modulos/fullscreen.js"></script>
</body>
#canvas {
width: 100%;
height: 100%;
}
.btn {
position: fixed;
bottom: 5%;
right: 0px;
transform: translateX(-50%);
border: 1px solid #000;
border-radius: 5px;
font-size: 0.9rem;
padding: 0.5rem 0.7em;
background-color: transparent;
color: #ffffff;
font-family: Verdana, Geneva, Tahoma, sans-serif;
-webkit-font-smoothing: antialiased;
cursor: pointer;
transition: all .3s;
z-index: 100;
}
.btn:hover {background: #1B1734; color: #ffffff;}
let canvas = document.getElementById("canvas");
let c = canvas.getContext("2d");
let numStars = 1000;
let radius = 1;
let focalLength = canvas.width;
let centerX, centerY;
let stars = [], star;
let i;
let animate = false;
initializeStars();
function executeFrame() {
if(animate) requestAnimFrame(executeFrame);
moveStars();
drawStars();
}
function initializeStars() {
centerX = canvas.width / 2;
centerY = canvas.height / 2;
stars = [];
for(i = 0; i < numStars; i++) {
star = {
x: Math.random() * canvas.width,
y: Math.random() * canvas.height,
z: Math.random() * canvas.width
};
stars.push(star);
}
}
function moveStars() {
for(i = 0; i < numStars; i++) {
star = stars[i];
star.z--;
if(star.z <= 0) star.z = canvas.width;
}
}
function drawStars() {
let pixelX, pixelY, pixelRadius;
// Condición para cuando se redimensione la ventana
if(canvas.width != window.innerWidth || canvas.height != window.innerHeight) {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
initializeStars();
}
c.fillStyle = "black";
c.fillRect(0,0, canvas.width, canvas.height);
c.fillStyle = "white";
for(i = 0; i < numStars; i++) {
star = stars[i];
pixelX = (star.x - centerX) * (focalLength / star.z);
pixelX += centerX;
pixelY = (star.y - centerY) * (focalLength / star.z);
pixelY += centerY;
pixelRadius = radius * (focalLength / star.z);
c.beginPath();
c.arc(pixelX, pixelY, pixelRadius, 0, 2 * Math.PI);
c.fill();
}
}
canvas.addEventListener("mousemove",function(e) {
focalLength = e.x;
});
// Animación cuando el ratón entre en el canvas
canvas.addEventListener('mouseover', function(e) {
animate = true;
executeFrame();
});
// Para la animación cuando el ratón sale del canvas
canvas.addEventListener("mouseout",function(e) {
// mouseDown = false;
animate = false;
});
// Dibuja el primer frame y comienza la animación
executeFrame();
Este simulador de ondas esta basado ecuación de onda
<body>
<canvas id="canvas"></canvas>
<script src="/assets/js/modulos/requestAnimFrame.js"></script>
</body>
let canvas = document.getElementById("canvas");
let c = canvas.getContext("2d");
let pullStrength = 0.01;
let dampeningFactor = 0.99;
let initialHeight = 0.5;
let cells = [];
let gridSize = 100;
let conservationOfMassCorrection = 0;
let cellWidth = 1 / (gridSize-1) * canvas.width;
let mouseX, mouseY, mouseDown;
let animate = false;
// This function executes once per animation frame
function executeFrame() {
if(animate) requestAnimFrame(executeFrame);
clearCanvas();
drawCells();
iterateSimulation();
executeMouseInteraction();
}
// Initialize the water height
for(let i = 0; i < gridSize; i++) {
cells.push({
// for a still initial surface
// height: 0.5,
// for an initial wave:
height: i === Math.floor(gridSize*1/4) ? 1 : initialHeight,
velocity: 0
});
}
function clearCanvas() {
// resizes to full screen
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
cellWidth = 1 / (gridSize-1) * canvas.width;
}
function drawCells() {
c.beginPath();
c.moveTo(canvas.width, canvas.height);
c.lineTo(0, canvas.height);
for(let i = 0; i < gridSize; i++){
let cell = cells[i];
let x = i / (gridSize-1) * canvas.width;
let y = canvas.height - cell.height * canvas.height;
c.lineTo(x,y);
}
c.closePath();
c.fill();
}
// Increment the wave simulation:
// Neighboring cells pull on one another.
function iterateSimulation() {
let avgHeight = 0;
for(let i = 0; i < gridSize; i++) {
// center cell
let c = cells[i];
// left neighbor
let l = cells[((i - 1) + gridSize) % gridSize];
// right neighbor
let r = cells[(i + 1) % gridSize];
// pull toward neighbors
c.velocity += pullStrength * (l.height - c.height);
c.velocity += pullStrength * (r.height - c.height);
// increment velocity
c.height += c.velocity;
// ensure conservation of mass
c.height += conservationOfMassCorrection;
// apply dampening
c.velocity *= dampeningFactor;
avgHeight += c.height;
}
avgHeight /= (gridSize - 1);
conservationOfMassCorrection = initialHeight - avgHeight;
}
// Pull the wave cell closest to the mouse
function executeMouseInteraction() {
if(mouseDown) {
for(let i = 0; i < gridSize; i++) {
let x = i / (gridSize-1) * canvas.width;
if(Math.abs(x - mouseX) < cellWidth) {
let cell = cells[i];
cell.height = 1 - mouseY/canvas.height;
cell.velocity = 0;
}
}
}
}
// Record when the mouse is pressed
canvas.addEventListener("mousedown",function(e) {
mouseDown = true;
mouseX = e.clientX;
mouseY = e.clientY;
});
// Record when the mouse is moved
canvas.addEventListener("mousemove",function(e) {
mouseX = e.clientX;
mouseY = e.clientY;
});
// Record when the mouse is released
canvas.addEventListener("mouseup",function(e) {
mouseDown = false;
});
// Kick off the animation when the mouse enters the canvas
canvas.addEventListener('mouseover', function(e) {
animate = true;
executeFrame();
});
// Pause animation when the mouse exits the canvas
canvas.addEventListener("mouseout",function(e) {
mouseDown = false;
animate = false;
});
// Draw the first frame
executeFrame();
Este simulador de ondas esta basado ecuación de onda
<body>
<canvas id="canvas"></canvas>
<script src="/assets/js/modulos/requestAnimFrame.js"></script>
</body>
let canvas = document.getElementById("canvas");
let c = canvas.getContext("2d");
let pullStrength = 0.005;
let dampeningFactor = 0.98;
let initialHeight = 0.5;
let cells = [];
let gridSize = 50;
let conservationOfMassCorrection = 0;
let cellWidth = 1 / (gridSize-1) * canvas.width;
let cellHeight = 1 / (gridSize-1) * canvas.height;
let mouseX, mouseY, mouseDown;
let animate = false;
function executeFrame() {
if(animate) requestAnimFrame(executeFrame);
clearCanvas();
drawCells();
iterateSimulation();
executeMouseInteraction();
};
// Store the color strings as an object re-use optimization.
// (otherwise new string objects would be created for each color each frame)
let grayStrings = [];
for(let gray = 0; gray < 255; gray++) {
// this transforms strings from 'rgb(255,190,201)' to '#FF564B'
c.fillStyle = 'rgb('+gray+','+gray+','+gray+')';
// store the colors of the form '#FF564B'
grayStrings.push(c.fillStyle);
}
for(let i = 0; i < gridSize; i++) {
for(let j = 0; j < gridSize; j++) {
// Raise a single cell so the simulation is
// initialized with something that looks interesting
let isRaisedCell = false;
if(i === Math.floor(gridSize*1/4))
if(j === Math.floor(gridSize*1/4))
isRaisedCell = true;
cells.push({
// for a still initial surface
//height: 0.5,
// for an initial wave:
height: isRaisedCell ? 4 : initialHeight,
velocity: 0
});
}
}
function clearCanvas() {
// resizes to full screen
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
cellWidth = 1 / (gridSize-1) * canvas.width;
cellHeight = 1 / (gridSize-1) * canvas.height;
}
function drawCells(){
for(let i = 0; i < gridSize; i++) {
for(let j = 0; j < gridSize; j++) {
let cell = cells[i + j * gridSize];
let x = i / (gridSize-1) * canvas.width;
let y = j / (gridSize-1) * canvas.height;
let gray = Math.floor(cell.height * 255);
gray = gray > 255 ? 255 : gray < 0 ? 0 : gray;
console.log(gray);
// This commented method of defining the colors
// would create lots of new String objects.
// Better to re-use existing objects so that
// no memory is allocated/released each frame.
// c.fillStyle = 'rgb('+gray+','+gray+','+gray+')';
c.fillStyle = grayStrings[gray];
c.fillRect(x, y, cellWidth+1, cellHeight+1);
}
}
}
function iterateSimulation() {
let avgHeight = 0;
for(let i = 0; i < gridSize; i++) {
for(let j = 0; j < gridSize; j++) {
// center cell
let c = cells[i + j * gridSize];
for(let di = -1; di <= 1; di++) {
for(let dj = -1; dj <= 1; dj++) {
if(di !== 0 || dj !== 0) {
let ni = ((i + di) + gridSize) % gridSize;
let nj = ((j + dj) + gridSize) % gridSize;
let neighbor = cells[ni + nj * gridSize];
// pull toward neighbors
c.velocity += pullStrength * (neighbor.height - c.height);
}
}
}
// increment velocity
c.height += c.velocity;
// ensure conservation of mass
c.height += conservationOfMassCorrection;
// apply dampening
c.velocity *= dampeningFactor;
avgHeight += c.height;
}
}
avgHeight /= Math.pow(gridSize - 1,2);
conservationOfMassCorrection = initialHeight - avgHeight;
}
function executeMouseInteraction() {
if(mouseDown) {
let i = Math.floor((gridSize-1) * mouseX / canvas.width);
let j = Math.floor((gridSize-1) * mouseY / canvas.height);
let cell = cells[i + j * gridSize];
cell.height = 2;
cell.velocity = 0;
}
}
canvas.addEventListener("mousedown",function(e) {
mouseDown = true;
mouseX = e.offsetX;
mouseY = e.offsetY;
});
canvas.addEventListener("mousemove",function(e) {
mouseX = e.offsetX;
mouseY = e.offsetY;
});
canvas.addEventListener("mouseup",function(e) {
mouseDown = false;
});
// Kick off the animation when the mouse enters the canvas
canvas.addEventListener('mouseover', function(e) {
animate = true;
executeFrame();
});
// Pause animation when the mouse exits the canvas
canvas.addEventListener("mouseout",function(e) {
mouseDown = false;
animate = false;
});
// Iterate the simulation a couple of times
// so the program shows something before animation starts.
for(let i = 0; i < 7; i++)
iterateSimulation();
// Draw the first frame
executeFrame();
<body>
<canvas id="canvas"></canvas>
<script src="/assets/js/modulos/requestAnimFrame.js"></script>
</body>
let canvas = document.getElementById('canvas');
let c = canvas.getContext('2d');
canvas.width = innerWidth;
canvas.height = innerHeight;
c.fillRect(0,0,canvas.width, canvas.height);
let paintColors = {};
let mouseId = 'mouse';
let mouseDown = false;
function addMouseListeners() {
canvas.addEventListener('mousemove', function(e) {
if(mouseDown){
c.fillStyle = paintColors[mouseId];
drawCircle(e.clientX, e.clientY);
}
});
canvas.addEventListener('mousedown', function(e) {
mouseDown = true;
setRandomPaintColor(mouseId);
});
canvas.addEventListener('mouseup', function(e) {
mouseDown = false;
});
canvas.addEventListener('dblclick', function(e) {
c.fillStyle = 'black';
c.fillRect(0,0,canvas.width, canvas.height);
});
}
function setRandomPaintColor(id) {
function rand255(){ return Math.floor(Math.random()*255);}
paintColors[id] = 'rgb('+rand255()+','+rand255()+','+rand255()+')';
}
function drawCircle(x, y) {
c.beginPath();
c.arc(x, y, 3, 0, 2 * Math.PI);
c.fill();
}
function addMultiTouchListeners() {
canvas.addEventListener('touchmove',function(e) {
let i, touch;
setRandomPaintColor();
for(i = 0; i < e.targetTouches.length; i++) {
touch = e.targetTouches[i];
c.fillStyle = paintColors[touch.identifier];
drawCircle(touch.pageX, touch.pageY);
}
});
canvas.addEventListener('touchstart',function(e) {
let i, touch;
for(i = 0; i < e.changedTouches.length; i++) {
touch = e.changedTouches[i];
setRandomPaintColor(touch.identifier);
}
});
canvas.addEventListener('touchend',function(e) {
let i, touch;
for(i = 0; i < e.changedTouches.length; i++) {
touch = e.changedTouches[i];
console.log("removing "+touch.identifier);
delete paintColors[touch.identifier];
}
});
}
// prevent scrolling
document.body.addEventListener('touchmove', function(event) {
event.preventDefault();
}, false);
addMouseListeners();
addMultiTouchListeners();
Si has llegado hasta aquí, y has leido el código de los ejemplos que he mostrado, observarás que para trabajar con canvas, hay que aprender javascript, los eventos, los diferentes métodos para manejar y controlar el ancho (width) y el alto (height), tanto de la ventana (window), como de los elementos html, en nuestro caso canvas.