HTML Canvas & JavaScript - Selection Menu - Setting Initial and Sustaining Current Selection

后端 未结 2 1740
长情又很酷
长情又很酷 2021-01-23 01:26

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 JavaScrip

2条回答
  •  执笔经年
    2021-01-23 02:26

    The issue is that your resize handler calls paintCanvas and in your paintCanvas method you are assigning your global paint variable to new an entirely new instance of paint. This entirely wipes out your state and forces the canvas to be redrawn to match the initial state of an initial page load. Instead, you need to maintain your state, clear your canvas and render it again with its existing state but just with new sizes.

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

    Commenting out //paint = new Paint(c); leaves your state intact. You still some remnants you need to flush out and redraw since you are no longer destroying your state.

    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= 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; ic.width*(400/750) && y>c.height*(25/500) && y
    canvas {
      z-index: -1;
      margin: 1em auto;
      border: 1px solid black;
      display: block;
      background: #9F3A9B;
    }
    
    
    
    	
    	uTalk Demo
    	
    
    
    	

提交回复
热议问题