Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

JavaScript

Touchstart and Touchend on Canvas

I have some simple squares drawn on canvas and I was trying to make it change color when using touchstart and touchend. The idea is to add the toggle functionality to each square object so it can be multitouch. Any clue?

Here is the code I have for now:

var canvas = document.getElementById('appArea');
var ctx = canvas.getContext('2d');
var width = window.innerWidth;
var height = window.innerHeight;
var shapelist = [];


var Square = function (x, y, size, ctx) {
    this.x = x;
    this.y = y;
    this.size = size;
    this.ctx = ctx;
    this.selected = false;
    this.color = 'black';
}

Square.prototype.render = function() {
    ctx.beginPath();
    ctx.rect(this.x, this.y, this.size, this.size);
    if (this.selected) {
        ctx.fillStyle = "green";
    } else  {
        ctx.fillStyle = this.color;
    }
    ctx.fill();

};


//Thinking on change object behaviour using an activated functionality
/*
Square.prototype.activated = function(color) {

};
*/


var generateSquares = function () {
    for (var i = 0; i < 3; i++) {
        var theX = i * 30;
        var theY = 20;
        var the Size = 10;
        var square = new Square(theX, theY, theSize, ctx);
        square.render();
        shapelist.push(square);
    };
}

var getCoords = function (x, y) {
    var validCoords = [];

    for(var index in shapelist){
        var shape = shapelist[index];
        var startX = shape.x;
        var endX = shape.x + shape.size;
        var startY = shape.y;
        var endY = shape.y + shape.size;

        if (x >= startX && x <= endX && y >= startY && y <= endY) {
            validCoords.push(shape);
        }
    }
    return validCoords;
} 


var startEvent = function(e) {
    var self = this;
    canvas.addEventListener('touchstart', function (e) {
        resetShapeSelection();
        var shapes = getCoords(e.offsetX, e.offsetY);
        console.log(shapes[shapes.length-1]);
        // if shapes exists from a touch event   
        if (shapes.length) {       
            var selectedShape = shapes[shapes.length-1];
            selectedShape.selected = true;
        }
        render();
    }, false);
}


function resetShapeSelection() {
   for(index in shapelist){
    var shape = shapelist[index];
       shape.selected=false;
   }
}


var render = function(){
    ctx.clearRect(0, 0, this.width, this.height);
    for(index in shapelist){
        shapelist[index].render();
    }
}

generateSquares();
startEvent();
render();

2 Answers

Kenneth Camilleri
Kenneth Camilleri
7,816 Points

<p>Try adding the touchstart / touchend event listeners in the Square's constructor. I don't have the source HTML file so I can't really test this out myself.</p> <pre>``` var Square = function (x, y, size, ctx) { this.x = x; this.y = y; this.size = size; this.ctx = ctx; this.selected = false; this.color = 'black'; this.addEventListener('touchstart', function(e)) { // Code to change colour on boxes } }

<p>This way, each square will create its own touchstart event listener upon being instantiated. I'm not really sure if I answered your question but I don't get the multitouch bit but at least you know that you can add the event listener to every square by modifying the constructor.</p>
<p>For future questions, it always helps to give a mockup or screenshot with arrows pointing at areas saying how you want some parts to behave.</p>

Thanks! I have solved the issue with another technique but anyway I think yours is mucho more effective.