HTML画布& JavaScript - 选择菜单 - 设置初始和持续当前选择 [英] HTML Canvas & JavaScript - Selection Menu - Setting Initial and Sustaining Current Selection

查看:106
本文介绍了HTML画布& JavaScript - 选择菜单 - 设置初始和持续当前选择的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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



此外,与此相关,我试图设置在第一个画布上选择的初始选择,直到选择其中一个选项。在这种情况下,当脚本最初加载时,我希望自动选择/显示数字1及其对应的图像,直到进行新的选择。再次,将它分配为 initialSelection 变量或调用 makeCurvedRect 独立留下静态选择,我的意思是 bendRect (image)不动画 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 [数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 =白色; 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(-the);} curvRect.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))+'Noto Sans' // check ctx.fillStyle ='white'; ctx.textAlign =中心; 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 =填充颜色; ctx.fillRect(c.width *(400/750),this.y,c.width *(350/750),c.height *(100/500))ctx.stroke(); ctx.font = c.height *(10/500)+'Noto Sans ctx.fillStyle =白色; ctx.textAlign =左; 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){}尝试{if(this.shapes [i] .lastClicked == true){this.shapes [i] .rect.makeCurvedRect(); }} catch(err){}} ctx.beginPath(); ctx.fillStyle =白色; 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 =中心; 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 [我] ==形状} 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];返回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);如果(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();油漆=新油漆(c); selection = []; for(var i = 0; i< numbers.length; i ++){selection.push(new selectionForMenu(i + 1,numbers [i],c.height *(25/500)+(c.height * * 100)/ 500))));对于(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;对于(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;保证金:1em自动;边框:1px纯黑色;显示:块;背景:#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>  

div>

解决方案

你必须让paint类(在代码中)一次,



  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(); //初始选择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(鼠标移动,函数(EVT){game.hover(的getX(EVT)的getY(EVT)); game.render();}); this.lement.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 =中心; 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);打破; }}}; 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 =中心; 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(上下文); this.sideButtons.render(上下文); this.board.render(上下文); 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; //或 - > 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>  


In the HTML canvas below I have a selection menu which triggers the drawing of an image beside it dependent on what is selected (numbers 1-5 in the example below). The JavaScript uses the pseudo-object approach to storing/manipulating images drawn on the canvas. Besides the EventListener's attached to the canvas, there is one EventListener attached to the whole window which resizes the canvas within a strict aspect ratio when the window size is changed.

The problem I am currently having with this is that the selection is cleared when the EventListener is triggered (when the window size is changed). To replicate this in the example below, you will have to run the code snippet in full screen mode and change your browser window's size. Instead, I would like the the current selection to be maintained after the window (and correspondingly, the canvas') size change. I have tried assigning the current selection to a variable, but I could only get it to leave a static selection where the onHover animation does not work.

Also, related to this, I am trying to set an initial selection that is selected on the first canvas draw until one of the other options is selected. In this case, when the script initially loads, I would like the number 1 and its corresponding image to be automatically selected/displayed until a new selection is made. Again, assigning this as an initialSelection variable or calling makeCurvedRect independently leaves a static selection, by which I mean the curvedRect (image) is not animated onHover.

I'm very unsure how to achieve either of these results so any help will be much appreciated. Apologies for the large amount of code but I could not manage to condense it any more than this.

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>

解决方案

you must make the paint class (in your code) once,

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>

这篇关于HTML画布&amp; JavaScript - 选择菜单 - 设置初始和持续当前选择的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆