【问题标题】:Maximum size of cards inside a canvas画布内卡片的最大尺寸
【发布时间】:2024-04-12 08:50:02
【问题描述】:

我现在正在使用一个 Web 应用程序,它需要在一个固定的矩形画布上绘制一些卡片。以下是标准:

  1. Web 应用程序启动时画布大小固定为宽度“w”和高度“h”。

  2. 有“n”号。启动后不会更改的卡片数量。

  3. 所有卡片的大小必须相同,宽度“cw”和高度“ch”具有固定比例,卡片可以在画布内调整大小。

在这种情况下,我想计算每张卡片的最大宽度和高度。有人可以帮忙吗?

【问题讨论】:

  • 最大尺寸?你是说最大面积吗?
  • 是的,我想找出每张卡片允许的最大宽度和高度

标签: html math canvas


【解决方案1】:

您的问题缺少很多信息。请阅读代码中的 cmets。希望我的回答能帮到你。

// initiate the canvas
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
let cw = canvas.width = 300,
  cx = cw / 2;
let ch = canvas.height = 300,
  cy = ch / 2;

// number of cards
let n = 12;
// the horizontal and vertical ratio 
let ratio = {x:.2,y:.3}
// the width and the height of a card
let w = cw*ratio.x;
let h = ch*ratio.y;
// a counter
let i = 0;
//a double for loop to draw the cards
for(let y = 0; y<ch; y+=h){
for(let x = 0; x<cw; x+=w){
  if(i < n)
  {drawCard(x,y);
  i++}
}
}

function drawCard(x,y){
  ctx.beginPath();
  ctx.strokeRect(x,y,w,h);
}
canvas {
  border:1px solid #d9d9d9;
}
&lt;canvas id="canvas"&gt;&lt;/canvas&gt;

【讨论】:

    【解决方案2】:

    最后,我自己找到了解决方案。

    这种性能可能不是最佳性能,但该解决方案为我提供了新卡宽度、新卡高度、每行卡数和每列卡数。这样卡片几乎可以覆盖画布。

    function crwh(col, row, n, cw, ch, w, h, exactN) {
    		// Methods
    		this.fn_init = function(col, row) {
    			this.col = col;
    			this.row = row;
    			
    			if (this.col > 0 && this.row > 0) {
    				// Calculate new card width & card height base on col
    				this.cw_new = (this.w / this.col);
    				this.ch_new = (this.cw_new / this.cw * this.ch);
    					
    				if (this.fn_valid() == false) {
    					// Calculate new card height & card width base on row
    					this.ch_new = (this.h / this.row);
    					this.cw_new = (this.ch_new / this.ch * cw);
    				}
    			}
    		}
    		
    		this.fn_area = function() {
    			// Get the size the rectangle
    			return this.cw_new * this.ch_new;
    		}
    		
    		this.fn_valid = function() {
    			var valid = true;
    			
    			// True if col * row must equal to no. of cards, False allow col * row greater than no. of cards
    			valid = valid && ((this.exactN == true && (this.col * this.row) == this.n) || (this.exactN == false && (this.col * this.row) >= this.n));
    			// col * card width (new) must be shorter than canvas width
    			
    			valid = valid && ((this.col * this.cw_new) <= this.w);
    			
    			// row * card height (new) must be shorter than canvas height
    			valid = valid && ((this.row * this.ch_new) <= this.h);
    			
    			return valid;
    		}
    		
    		// Properties
    		this.n = n;
    		this.cw = cw;
    		this.ch = ch;
    		this.w = w;
    		this.h = h;
    		this.exactN = exactN;
    
    		this.col = 0;
    		this.row = 0;
    		
    		this.cw_new = 0;
    		this.ch_new = 0;
    		
    		this.fn_init(col, row);
    	}
    
    	function fn_getCardDimensions(n, cw, ch, w, h, exactN) {
    		var crwh_max = new crwh(0, 0);
    		
    		// Loop thru 1 to n for col & row to see which combination allow a maximum card size
    		for (var col = 1; col <= n; col++) {
    			for (var row = 1; row <= n; row++) {
    				if ((col * row) >= n) {
    					var crwh_cur = new crwh(col, row, n, cw, ch, w, h, exactN);
    					
    					if (crwh_cur.fn_valid()) {
    						
    						if (crwh_cur.fn_area() > crwh_max.fn_area()) {
    							crwh_max = crwh_cur;
    						}
    					}
    				}
    			}
    		}
    
    		return [crwh_max.col, crwh_max.row, crwh_max.cw_new, crwh_max.ch_new];
    	}
    	
    	var n = 80;				// No. of Cards
    	var cw = 344;			// Card Width (orig)
    	var ch = 512;			// Card Height (orig)
    	var w = 0;				// Canvas Width
    	var h = 0;				// Canvas Height
    	var exactN = true;		// True if col * row must equal to no. of cards
    	
    	
    	function fn_drawCards() {
    		var canvas = document.getElementById("canvas");
    		var ctx = canvas.getContext("2d");
    		
    		w = canvas.width;
    		h = canvas.height;
    		
    		[col, row, cw_new, ch_new] = fn_getCardDimensions(n, cw, ch, w, h, exactN);
    		
    		for (var i = 0; i < col; i++) {
    			for (var j = 0; j < row; j++) {
    				ctx.beginPath();
    				ctx.strokeRect(i * cw_new, j * ch_new, cw_new, ch_new);
    			}
    		}		
    	}
      
      fn_drawCards();
    canvas {
    		border:1px solid #00FF00;
    	}
    &lt;canvas id="canvas"&gt;&lt;/canvas&gt;

    【讨论】: