HTML Canvas& JavaScript - 选择菜单 - 设置初始和持续当前选择

时间:2017-07-12 15:43:16

标签: javascript html html5 events canvas

在下面的HTML画布中,我有一个选择菜单,它会触发在它旁边绘制图像,具体取决于所选内容(下例中的数字1-5)。 JavaScript使用伪对象方法来存储/操作在画布上绘制的图像。除了附加到画布的EventListener之外,还有一个EventListener附加到整个窗口,当窗口大小发生变化时,它会以严格的宽高比调整画布的大小。

我目前遇到的问题是,当触发EventListener时(当窗口大小改变时),选择被清除。要在下面的示例中复制此内容,您必须以全屏模式运行代码段并更改浏览器窗口的大小。相反,我希望在窗口(以及相应的,画布')大小更改后保持当前选择。我已经尝试将当前选择分配给变量,但我只能让它留下静态选择,其中onHover动画不起作用。

此外,与此相关,我试图设置在第一个画布绘制上选择的初始选择,直到选择其中一个选项。在这种情况下,当脚本最初加载时,我希望自动选择/显示数字1及其相应的图像,直到进行新的选择。同样,将其指定为initialSelection变量或单独调用makeCurvedRect会留下静态选择,我的意思是curvedRect(图片)不是动画onHover

我非常不确定如何实现这些结果中的任何一项,因此我们将非常感谢任何帮助。为大量代码道歉,但我无法将其压缩为此。



var c=document.getElementById('game'),
    rect = c.getBoundingClientRect(),
		ctx=c.getContext('2d');

c.width  = window.innerWidth;
c.height = (2/3)*c.width;

numberImages = ['https://i.stack.imgur.com/TZIUz.png','https://i.stack.imgur.com/6beTF.png','https://i.stack.imgur.com/wZk2H.png','https://i.stack.imgur.com/1K743.png','https://i.stack.imgur.com/jMMmQ.png'];

var curvedRect = function(number, x, y, w, h) {
    this.text = number.toString();
	this.img = new Image();
	this.img.src=numberImages[number-1];
	this.x = x;
	this.y = y;
	this.w = w;
	this.h = h;
	this.hovered = false;
	this.clicked = false;
	this.visible = false;
}

var selected;
curvedRect.prototype.makeCurvedRect = function() {
	var delta=0, theta=0;
	if (this.hovered) {
		delta = (c.height*(3/500));
		theta = -0.01;
		shadowColor = '#000000';
		shadowBlur = 20;
		shadowOffsetX = 5;
		shadowOffsetY = 5;
	} else {
		delta = 0;
		theta = 0;
		shadowColor = '#9F3A9B';
		shadowBlur = 0;
		shadowOffsetX = 0;
		shadowOffsetY = 0;
	}
	var x = this.x-delta;
	var y = this.y-delta;
	var w = this.w+(2*delta);
	var h = this.h+(2*delta);
	var cornerRounder = (c.height*(10/500))
	ctx.rotate(theta);
	ctx.beginPath();
	ctx.lineWidth='12';
	ctx.strokeStyle='white';
	ctx.moveTo(x+cornerRounder, y);
	ctx.lineTo(x+w-cornerRounder, y);
	ctx.quadraticCurveTo(x+w, y, x+w, y+cornerRounder);
	ctx.lineTo(x+w, y+h-cornerRounder);
	ctx.quadraticCurveTo(x+w, y+h, x+w-cornerRounder, y+h);
	ctx.lineTo(x+cornerRounder, y+h);
	ctx.quadraticCurveTo(x, y+h, x, y+h-cornerRounder);
	ctx.lineTo(x, y+cornerRounder);
	ctx.quadraticCurveTo(x, y, x+cornerRounder, y);
	ctx.shadowColor = shadowColor;
	ctx.shadowBlur = shadowBlur;
	ctx.shadowOffsetX = shadowOffsetX;
	ctx.shadowOffsetY = shadowOffsetY;
	ctx.stroke();
	ctx.shadowBlur = 0;
	ctx.shadowOffsetX = 0;
	ctx.shadowOffsetY = 0;
	ctx.drawImage(this.img, x+(c.width*(2.5/750)), y+(c.height*(2.5/500)), w-cornerRounder/2, h-cornerRounder/2);
	ctx.rotate(-theta);
}

curvedRect.prototype.hitTest = function(x, y) {
	return (x >= this.x) && (x <= (this.w+this.x)) && (y >= this.y) && (y <= (this.h+this.y));
}

var selectionForMenu = function(id, text, y) {
	this.id = id;
	this.text = text;
	this.y = y;
	this.hovered = false;
	this.clicked = false;
	this.lastClicked = false;
	this.visible = true;
}

function makeTextForSelected(text, y) {
	ctx.font='bold '+(c.height*(12/500))+'px Noto Sans'; // check
	ctx.fillStyle='white';
	ctx.textAlign='center';
	ctx.fillText(text, (c.width*(200/750)), y);
}

selectionForMenu.prototype.makeSelection = function() {
	ctx.globalAlpha=0.75;
	var fillColor='#A84FA5';
	if (this.hovered) {
		if (this.clicked) {
			if (this.lastClicked) {
				fillColor='#E4C7E2';
				makeTextForSelected(this.text, c.height*(375/500));
			} else {
				fillColor='#D5A9D3';
			}
		} else if (this.lastClicked) {
			fillColor='#D3A4D0';
			makeTextForSelected(this.text, c.height*(375/500));
		} else {
			fillColor='#BA74B7';
		}
	} else if (this.lastClicked) {
		fillColor='#C78DC5';
		makeTextForSelected(this.text, c.height*(375/500));
	} else {
		fillColor='#A84FA5';
	}
	ctx.beginPath();
	ctx.fillStyle=fillColor;
	ctx.fillRect(c.width*(400/750), this.y, c.width*(350/750), c.height*(100/500))
	ctx.stroke();

	ctx.font=c.height*(10/500)+'px Noto Sans';
	ctx.fillStyle='white';
	ctx.textAlign='left';
	ctx.fillText(this.text, c.width*(410/750), this.y+(c.height*(38/500)));

	ctx.globalAlpha=1;
}

selectionForMenu.prototype.hitTest = function(x, y) {
	return (x >= (c.width*(400/750)) && (x <= c.width) && (y >= this.y) &&
	(y <= (this.y+(c.height*(100/500))) && !((x >= c.width*(400/750) && (y > c.height*(450/500))))));
}

var Paint = function(element) {
	this.element = element;
	this.shapes = [];
}

Paint.prototype.addShape = function(shape) {
	this.shapes.push(shape);
}

Paint.prototype.render = function() {

	ctx.clearRect(0, 0, this.element.width, this.element.height);

	for (var i=0; i<this.shapes.length; i++) {
		try {
			this.shapes[i].makeSelection();
		}
		catch(err) {}
		try {
			if(this.shapes[i].lastClicked == true) {
				this.shapes[i].rect.makeCurvedRect();
			}
		}
		catch(err) {}
	}

	ctx.beginPath();
	ctx.fillStyle='white';
	ctx.fillRect(0, 0, c.width, (c.height*(25/500)));
	ctx.stroke();

	ctx.beginPath();
	ctx.fillStyle='#BC77BA';
	ctx.fillRect(0, (c.height*(450/500)), c.width, (c.height*(50/500)));
	ctx.stroke();

	ctx.font='bold '+(c.height*(10/500))+'px Noto Sans';
	ctx.fillStyle='#9F3A9B';
	ctx.textAlign='center';
	ctx.fillText('Test', (c.width*(365/750)), (c.height*(17/500)));
}

Paint.prototype.setHovered = function(shape) {
	for (var i=0; i<this.shapes.length; i++) {
		this.shapes[i].hovered = this.shapes[i] == shape;
	}
	this.render();
}

Paint.prototype.setClicked = function(shape) {
	for (var i=0; i<this.shapes.length; i++) {
		this.shapes[i].clicked = this.shapes[i] == shape;
	}
	this.render();
}

Paint.prototype.setUnclicked = function(shape) {
	for (var i=0; i<this.shapes.length; i++) {
		if (shape.constructor.name==this.shapes[i].constructor.name) {
			this.shapes[i].clicked = false;
		 	if (shape instanceof selectionForMenu) {
				this.shapes[i].lastClicked = this.shapes[i] == shape;
				if (this.shapes[i].lastClicked == true) {
					this.shapes[i].rect.visible = true;
				} else {
					this.shapes[i].rect.visible = false;
				}
			}
		}
	}
	this.render();
}

Paint.prototype.select = function(x, y) {
	for (var i=this.shapes.length-1; i >= 0; i--) {
		if (this.shapes[i].visible == true && this.shapes[i].hitTest(x, y)) {
			return this.shapes[i];
		}
	}
	return null
}

var numbers = [1,2,3,4,5];
var paint = new Paint(c);
var selection = [];
for (var i=0; i<numbers.length; i++) {
	selection.push(new selectionForMenu(i+1, numbers[i], c.height*(25/500)+(c.height*((i*100)/500))));
}
for (var i=0; i<numbers.length; i++) {
	var img = new curvedRect(i+1, (c.width*(112.5/750)), (c.height*(100/500)), (c.height*(175/500)), (c.height*(175/500)));
	paint.addShape(img)
	selection[i].rect = img;
}

for (var i=0; i<numbers.length; i++) {
	paint.addShape(selection[i])
}

paint.render();

var clickedShape, clickIndex=0;
function mouseDown(event) {
	var x = (event.pageX-rect.left)/(rect.right-rect.left)*c.width;
	var y = (event.pageY-rect.top)/(rect.bottom-rect.top)*c.height;
	var shape = paint.select(x, y);
	if (shape instanceof selectionForMenu) {
		if (clickIndex==0) {
			clickedShape=shape;
			clickIndex=1;
		} else if (clickIndex==1) {
			clickIndex=0;
		}
	}
	paint.setClicked(shape);
}

function mouseUp(event) {
	var x = (event.pageX-rect.left)/(rect.right-rect.left)*c.width;
	var y = (event.pageY-rect.top)/(rect.bottom-rect.top)*c.height;
	var shape = paint.select(x, y);
	if (clickedShape instanceof selectionForMenu) {
		if (x>c.width*(400/750) && y>c.height*(25/500) && y<c.height*(450/500)) {
			paint.setUnclicked(shape);
		} else if (shape && !(shape instanceof selectionForMenu)) {
			paint.setUnclicked(shape);
		}
	}
}

function mouseMove(event) {
	var x = (event.pageX-rect.left)/(rect.right-rect.left)*c.width;
	var y = (event.pageY-rect.top)/(rect.bottom-rect.top)*c.height;
	var shape = paint.select(x, y);

	paint.setHovered(shape);
}

function paintCanvas() {
  c.width  = window.innerWidth;
  c.height = (2/3)*c.width;
  ctx=c.getContext('2d');
  rect = c.getBoundingClientRect();

  paint = new Paint(c);
  selection = [];
  for (var i=0; i<numbers.length; i++) {
    selection.push(new selectionForMenu(i+1, numbers[i], c.height*(25/500)+(c.height*((i*100)/500))));
  }
  for (var i=0; i<numbers.length; i++) {
    var img = new curvedRect(i+1, (c.width*(112.5/750)), (c.height*(100/500)), (c.height*(175/500)), (c.height*(175/500)));
    paint.addShape(img)
    selection[i].rect = img;
  }

  for (var i=0; i<numbers.length; i++) {
    paint.addShape(selection[i])
  }
  paint.render();
}

paintCanvas();

window.addEventListener('resize', paintCanvas);
c.addEventListener('mousedown', mouseDown);
c.addEventListener('mouseup', mouseUp);
c.addEventListener('mousemove', mouseMove);
&#13;
canvas {
  z-index: -1;
  margin: 1em auto;
  border: 1px solid black;
  display: block;
  background: #9F3A9B;
}
&#13;
<!doctype html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>uTalk Demo</title>
	<link rel='stylesheet' type='text/css' href='wordpractice.css' media='screen'></style>
</head>
<body>
	<div id='container'>
		<canvas id="game"></canvas>
	</div>
  <script type='text/javascript' src='scaleStack.js'></script>
</body>
</html>
&#13;
&#13;
&#13;

2 个答案:

答案 0 :(得分:1)

你必须做一次涂料类(在你的代码中),

function Game (elementID,width,height){
	this.elementID = elementID;
	this.element   = document.getElementById(elementID);
	this.width = width;
	this.height = height;

	this.palette = {
		color1:'#fff',
		color2:'#000',
		color3:'#9F3A9B',
		color4:'#a84ea5',
		color5:'#b56ab2',
		color6:'#bf7dbd',
		color7:'#d5a8d2'
	}; 

	this.element.style.width = width + 'px';
	this.element.style.height= height + 'px';
	this.element.style.border='solid thin ' + this.palette.color2;
	this.element.style.display= 'block';
	//this.element.style.margin='1em auto';
	this.element.style.background=this.palette.color3;


	this.initialGame();
}

Game.prototype.initialGame = function(){
	this.canvas  = document.createElement("canvas");
	this.canvas.width  =  this.width;
	this.canvas.height =  this.height;
	this.element.appendChild(this.canvas);

	this.initialTitle();
	this.initialSideButtons();
	this.initialBoard();
	this.initialFooter();

    // initial selection
    this.sideButtons.select(this.sideButtons.buttons[0]);

	this.resize(this.width,this.height);
	this.render();
	this.attachEvents();
}

Game.prototype.attachEvents = function(){
	var element = this.element;
	
	var getX = function(evt){return evt.offsetX || evt.layerX || (evt.clientX - element.offsetLeft);};
	var getY = function(evt){return evt.offsetY || evt.layerY || (evt.clientY - element.offsetTop);};
 
	var game = this;
	this.element.addEventListener('mousemove',function(evt){
		game.hover(getX(evt),getY(evt));
		game.render();
	});

	this.element.addEventListener('click',function(evt){
		game.sideButtons.click();
		game.render();
	});
}

Game.prototype.onSelect = function(button){
	this.selected = button;
};

Game.prototype.hover=function(x,y){
	this.hoverX = x;
	this.hoverY = y;
};

Game.prototype.initialBoard = function(){
	var game = this;
	var Board = function(){
		this.left = 0;
		this.top  = 0;
		this.width =0;
		this.height=0;
	};

	Board.prototype.render = function(ctx){
		if(game.selected){

			var shapeWidth = this.width/3;

			ctx.fillStyle = game.palette.color1;
			ctx.strokeStyle = game.palette.color1;
			var fontSize =  14;
			ctx.font = 'bold '+ fontSize +'px Noto Sans';
			ctx.textAlign='center';
			ctx.lineWidth=8;
			ctx.lineJoin = 'round';
			ctx.strokeRect(this.left + this.width/2 - (shapeWidth/2),this.height/2-(shapeWidth/2) + this.top,shapeWidth,shapeWidth);
			ctx.fillText(game.selected.text,this.left + this.width/2,this.height/2 + this.top );
		}
	};

	this.board =  new Board();
};

Game.prototype.initialSideButtons = function(){
	var game = this;
	var ButtonBar =function(text){
		this.text = text;
		this.left = 0;
		this.top  = 0;
		this.width = 1;
		this.height= 1;
		this.selected=false;
	};

	ButtonBar.prototype.hitTest=function(x,y){
		return 	(this.left < x) && (x < (this.left + this.width)) &&
				(this.top <y) && (y < (this.top + this.height));
	};

	ButtonBar.prototype.getColor=function(){
		var hovered = this.hitTest(game.hoverX,game.hoverY);
		
		if(this.selected){
			if(hovered)
			{
				return game.palette.color7;
			}
			return game.palette.color6;
		}
		
		if(hovered){
			return game.palette.color5;
		}
		return game.palette.color4;
	};

	ButtonBar.prototype.render = function(ctx){
		var fontSize = 14;
		ctx.fillStyle = this.getColor();
		ctx.fillRect(this.left,this.top,this.width,this.height);
		ctx.fillStyle = game.palette.color1;
		ctx.textAlign = 'left';
		ctx.font ='bold '+ fontSize +'px Noto Sans';
		ctx.fillText(this.text,this.left + 10,this.top+ this.height/2);
	};

	var SideButtons = function(){
		this.buttons = [];
		this.width = 1;
		this.height= 1;
		this.left=1;
		this.top=1;
	};

	SideButtons.prototype.render = function(ctx){
		if(!this.buttons.length){
			return;
		}

		var height = this.height / this.buttons.length ;
		for(var i=0;i<this.buttons.length;i++){
			var btn = this.buttons[i];
			btn.left = this.left;
			btn.top = i * height + this.top;
			btn.width = this.width;
			btn.height = height;
			this.buttons[i].render(ctx);
		}
	};

	SideButtons.prototype.click = function(){
            var current = null;
		for(var i=0;i<this.buttons.length;i++){
			var btn = this.buttons[i];
                    if(  btn.hitTest(game.hoverX,game.hoverY))
                     {
				this.select(btn);
                            break;
			 }
		}
	};

    SideButtons.prototype.select = function(btn)
    {
       for(var i=0;i<this.buttons.length;i++)
       {
          this.buttons[i].selected = false;
       }
       btn.selected=true;
       game.onSelect(btn);
    };

	this.sideButtons = new SideButtons();

	var btn1 = new ButtonBar('Button 1');
	var btn2 = new ButtonBar('Button 2');
	var btn3 = new ButtonBar('Button 3');
	var btn4 = new ButtonBar('Button 4');

	this.sideButtons.buttons.push(btn1);
	this.sideButtons.buttons.push(btn2);
	this.sideButtons.buttons.push(btn3);
	this.sideButtons.buttons.push(btn4);

};

Game.prototype.initialTitle = function(){
	var Title = function(value,width,height){
		this.value=value;
		this.width = width;
		this.height= height;
	};

	var game = this;
	Title.prototype.render=function(ctx){
		var k = 2;
		var fontSize =  this.height / k;
		ctx.fillStyle=game.palette.color1;
		ctx.fillRect(0,0,this.width,this.height);
		ctx.font='bold '+ fontSize +'px Noto Sans'; // check
		ctx.fillStyle=game.palette.color3;
		ctx.textAlign='center';
		ctx.fillText(this.value,this.width/2,this.height - fontSize/2);

	};

	this.title = new Title('Test',this.width,this.height / 10);
}

Game.prototype.initialFooter = function(){
	var Footer = function(){
		this.width = 1;
		this.height= 1;
		this.left=0;
		this.top=0;
	}
	var game = this;
	Footer.prototype.render = function(ctx){
		ctx.fillStyle =  game.palette.color5;
		ctx.fillRect(this.left,this.top,this.width,this.height);
	};

	this.footer = new Footer();
};

Game.prototype.resetCanvas = function(){
	this.canvas.width  =  this.width;
	this.canvas.height =  this.height;
};

Game.prototype.render = function(){
	this.resetCanvas();

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

	this.title.render(context);
	this.sideButtons.render(context);
	this.board.render(context);
	this.footer.render(context);

};

Game.prototype.resize =  function (width,height){
	this.width = width;
	this.height= height;

	this.element.style.width = width + 'px';
	this.element.style.height= height+ 'px';
	
	this.title.height = this.height / 14;
	this.title.width   = this.width;

	this.footer.height = this.title.height;
	this.footer.width  = this.width;
	this.footer.top = this.height - this.footer.height;
	this.footer.left = 0;

	this.board.top   = this.title.height;
	this.board.left  = 0;
	this.board.width = this.width  - 250;//or -> this.width / 2
	this.board.height= this.height - this.title.height - this.footer.height;

	this.sideButtons.left= this.board.width;
	this.sideButtons.top = this.board.top;
	this.sideButtons.width = this.width - this.board.width;
	this.sideButtons.height = this.board.height;

	this.render();
};


var game = new Game('game',window.innerWidth -50,window.innerWidth * 2/3);

window.addEventListener('resize', function(){
	game.resize(window.innerWidth -50,window.innerWidth * 2/3);
});
	<div id='container'>
		<div id="game"></div>
	</div>

答案 1 :(得分:0)

问题是您的调整大小处理程序调用了paintCanvas,并且在您的paintCanvas方法中,您将全局paint变量分配给新的paint实例。这会完全消除您的状态并强制重绘画布以匹配初始页面加载的初始状态。相反,您需要保持状态,清除画布并使用现有状态再次渲染它,但只需使用新尺寸。

function paintCanvas() {
    c.width  = window.innerWidth;
    c.height = (2/3)*c.width;
    ctx=c.getContext('2d');
    rect = c.getBoundingClientRect();

    //paint = new Paint(c);

评论//paint = new Paint(c);会使您的州完好无损。因为你不再破坏你的状态,你仍然需要冲洗和重绘一些残余物。

var c=document.getElementById('game'),
    rect = c.getBoundingClientRect(),
		ctx=c.getContext('2d');

c.width  = window.innerWidth;
c.height = (2/3)*c.width;

numberImages = ['https://i.stack.imgur.com/TZIUz.png','https://i.stack.imgur.com/6beTF.png','https://i.stack.imgur.com/wZk2H.png','https://i.stack.imgur.com/1K743.png','https://i.stack.imgur.com/jMMmQ.png'];

var curvedRect = function(number, x, y, w, h) {
    this.text = number.toString();
	this.img = new Image();
	this.img.src=numberImages[number-1];
	this.x = x;
	this.y = y;
	this.w = w;
	this.h = h;
	this.hovered = false;
	this.clicked = false;
	this.visible = false;
}

var selected;
curvedRect.prototype.makeCurvedRect = function() {
	var delta=0, theta=0;
	if (this.hovered) {
		delta = (c.height*(3/500));
		theta = -0.01;
		shadowColor = '#000000';
		shadowBlur = 20;
		shadowOffsetX = 5;
		shadowOffsetY = 5;
	} else {
		delta = 0;
		theta = 0;
		shadowColor = '#9F3A9B';
		shadowBlur = 0;
		shadowOffsetX = 0;
		shadowOffsetY = 0;
	}
	var x = this.x-delta;
	var y = this.y-delta;
	var w = this.w+(2*delta);
	var h = this.h+(2*delta);
	var cornerRounder = (c.height*(10/500))
	ctx.rotate(theta);
	ctx.beginPath();
	ctx.lineWidth='12';
	ctx.strokeStyle='white';
	ctx.moveTo(x+cornerRounder, y);
	ctx.lineTo(x+w-cornerRounder, y);
	ctx.quadraticCurveTo(x+w, y, x+w, y+cornerRounder);
	ctx.lineTo(x+w, y+h-cornerRounder);
	ctx.quadraticCurveTo(x+w, y+h, x+w-cornerRounder, y+h);
	ctx.lineTo(x+cornerRounder, y+h);
	ctx.quadraticCurveTo(x, y+h, x, y+h-cornerRounder);
	ctx.lineTo(x, y+cornerRounder);
	ctx.quadraticCurveTo(x, y, x+cornerRounder, y);
	ctx.shadowColor = shadowColor;
	ctx.shadowBlur = shadowBlur;
	ctx.shadowOffsetX = shadowOffsetX;
	ctx.shadowOffsetY = shadowOffsetY;
	ctx.stroke();
	ctx.shadowBlur = 0;
	ctx.shadowOffsetX = 0;
	ctx.shadowOffsetY = 0;
	ctx.drawImage(this.img, x+(c.width*(2.5/750)), y+(c.height*(2.5/500)), w-cornerRounder/2, h-cornerRounder/2);
	ctx.rotate(-theta);
}

curvedRect.prototype.hitTest = function(x, y) {
	return (x >= this.x) && (x <= (this.w+this.x)) && (y >= this.y) && (y <= (this.h+this.y));
}

var selectionForMenu = function(id, text, y) {
	this.id = id;
	this.text = text;
	this.y = y;
	this.hovered = false;
	this.clicked = false;
	this.lastClicked = false;
	this.visible = true;
}

function makeTextForSelected(text, y) {
	ctx.font='bold '+(c.height*(12/500))+'px Noto Sans'; // check
	ctx.fillStyle='white';
	ctx.textAlign='center';
	ctx.fillText(text, (c.width*(200/750)), y);
}

selectionForMenu.prototype.makeSelection = function() {
	ctx.globalAlpha=0.75;
	var fillColor='#A84FA5';
	if (this.hovered) {
		if (this.clicked) {
			if (this.lastClicked) {
				fillColor='#E4C7E2';
				makeTextForSelected(this.text, c.height*(375/500));
			} else {
				fillColor='#D5A9D3';
			}
		} else if (this.lastClicked) {
			fillColor='#D3A4D0';
			makeTextForSelected(this.text, c.height*(375/500));
		} else {
			fillColor='#BA74B7';
		}
	} else if (this.lastClicked) {
		fillColor='#C78DC5';
		makeTextForSelected(this.text, c.height*(375/500));
	} else {
		fillColor='#A84FA5';
	}
	ctx.beginPath();
	ctx.fillStyle=fillColor;
	ctx.fillRect(c.width*(400/750), this.y, c.width*(350/750), c.height*(100/500))
	ctx.stroke();

	ctx.font=c.height*(10/500)+'px Noto Sans';
	ctx.fillStyle='white';
	ctx.textAlign='left';
	ctx.fillText(this.text, c.width*(410/750), this.y+(c.height*(38/500)));

	ctx.globalAlpha=1;
}

selectionForMenu.prototype.hitTest = function(x, y) {
	return (x >= (c.width*(400/750)) && (x <= c.width) && (y >= this.y) &&
	(y <= (this.y+(c.height*(100/500))) && !((x >= c.width*(400/750) && (y > c.height*(450/500))))));
}

var Paint = function(element) {
	this.element = element;
	this.shapes = [];
}

Paint.prototype.addShape = function(shape) {
	this.shapes.push(shape);
}

Paint.prototype.render = function() {

	ctx.clearRect(0, 0, this.element.width, this.element.height);

	for (var i=0; i<this.shapes.length; i++) {
		try {
			this.shapes[i].makeSelection();
		}
		catch(err) {}
		try {
			if(this.shapes[i].lastClicked == true) {
				this.shapes[i].rect.makeCurvedRect();
			}
		}
		catch(err) {}
	}

	ctx.beginPath();
	ctx.fillStyle='white';
	ctx.fillRect(0, 0, c.width, (c.height*(25/500)));
	ctx.stroke();

	ctx.beginPath();
	ctx.fillStyle='#BC77BA';
	ctx.fillRect(0, (c.height*(450/500)), c.width, (c.height*(50/500)));
	ctx.stroke();

	ctx.font='bold '+(c.height*(10/500))+'px Noto Sans';
	ctx.fillStyle='#9F3A9B';
	ctx.textAlign='center';
	ctx.fillText('Test', (c.width*(365/750)), (c.height*(17/500)));
}

Paint.prototype.setHovered = function(shape) {
	for (var i=0; i<this.shapes.length; i++) {
		this.shapes[i].hovered = this.shapes[i] == shape;
	}
	this.render();
}

Paint.prototype.setClicked = function(shape) {
	for (var i=0; i<this.shapes.length; i++) {
		this.shapes[i].clicked = this.shapes[i] == shape;
	}
	this.render();
}

Paint.prototype.setUnclicked = function(shape) {
	for (var i=0; i<this.shapes.length; i++) {
		if (shape.constructor.name==this.shapes[i].constructor.name) {
			this.shapes[i].clicked = false;
		 	if (shape instanceof selectionForMenu) {
				this.shapes[i].lastClicked = this.shapes[i] == shape;
				if (this.shapes[i].lastClicked == true) {
					this.shapes[i].rect.visible = true;
				} else {
					this.shapes[i].rect.visible = false;
				}
			}
		}
	}
	this.render();
}

Paint.prototype.select = function(x, y) {
	for (var i=this.shapes.length-1; i >= 0; i--) {
		if (this.shapes[i].visible == true && this.shapes[i].hitTest(x, y)) {
			return this.shapes[i];
		}
	}
	return null
}

var numbers = [1,2,3,4,5];
var paint = new Paint(c);
var selection = [];
for (var i=0; i<numbers.length; i++) {
	selection.push(new selectionForMenu(i+1, numbers[i], c.height*(25/500)+(c.height*((i*100)/500))));
}
for (var i=0; i<numbers.length; i++) {
	var img = new curvedRect(i+1, (c.width*(112.5/750)), (c.height*(100/500)), (c.height*(175/500)), (c.height*(175/500)));
	paint.addShape(img)
	selection[i].rect = img;
}

for (var i=0; i<numbers.length; i++) {
	paint.addShape(selection[i])
}

paint.render();

var clickedShape, clickIndex=0;
function mouseDown(event) {
	var x = (event.pageX-rect.left)/(rect.right-rect.left)*c.width;
	var y = (event.pageY-rect.top)/(rect.bottom-rect.top)*c.height;
	var shape = paint.select(x, y);
	if (shape instanceof selectionForMenu) {
		if (clickIndex==0) {
			clickedShape=shape;
			clickIndex=1;
		} else if (clickIndex==1) {
			clickIndex=0;
		}
	}
	paint.setClicked(shape);
}

function mouseUp(event) {
	var x = (event.pageX-rect.left)/(rect.right-rect.left)*c.width;
	var y = (event.pageY-rect.top)/(rect.bottom-rect.top)*c.height;
	var shape = paint.select(x, y);
	if (clickedShape instanceof selectionForMenu) {
		if (x>c.width*(400/750) && y>c.height*(25/500) && y<c.height*(450/500)) {
			paint.setUnclicked(shape);
		} else if (shape && !(shape instanceof selectionForMenu)) {
			paint.setUnclicked(shape);
		}
	}
}

function mouseMove(event) {
	var x = (event.pageX-rect.left)/(rect.right-rect.left)*c.width;
	var y = (event.pageY-rect.top)/(rect.bottom-rect.top)*c.height;
	var shape = paint.select(x, y);

	paint.setHovered(shape);
}

function paintCanvas() {
  c.width  = window.innerWidth;
  c.height = (2/3)*c.width;
  ctx=c.getContext('2d');

  rect = c.getBoundingClientRect();
 
  //paint = new Paint(c);
  selection = [];
  for (var i=0; i<numbers.length; i++) {
    selection.push(new selectionForMenu(i+1, numbers[i], c.height*(25/500)+(c.height*((i*100)/500))));
  }
  for (var i=0; i<numbers.length; i++) {
    var img = new curvedRect(i+1, (c.width*(112.5/750)), (c.height*(100/500)), (c.height*(175/500)), (c.height*(175/500)));
    paint.addShape(img)
    selection[i].rect = img;
  }

  for (var i=0; i<numbers.length; i++) {
    paint.addShape(selection[i])
  }
  paint.render();
}

paintCanvas();

window.addEventListener('resize', paintCanvas);
c.addEventListener('mousedown', mouseDown);
c.addEventListener('mouseup', mouseUp);
c.addEventListener('mousemove', mouseMove);
canvas {
  z-index: -1;
  margin: 1em auto;
  border: 1px solid black;
  display: block;
  background: #9F3A9B;
}
<!doctype html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>uTalk Demo</title>
	<link rel='stylesheet' type='text/css' href='wordpractice.css' media='screen'></style>
</head>
<body>
	<div id='container'>
		<canvas id="game"></canvas>
	</div>
  <script type='text/javascript' src='scaleStack.js'></script>
</body>
</html>