簡體   English   中英

用圖像而不是文本填充 canvas(命運之輪)

[英]Fill canvas (wheel of fortune) with images instead of text

我正在嘗試用圖像而不是文本來創建一個命運之輪來顯示價格。

我正在使用ctx.fillText(sector.label, rad - 50, 10); 用他們的文本 label 填寫所有價格,但我想用圖像代替文本!

但是,當我執行ctax.drawImage(sector.image, rad - 50, 10)時,所有圖像都呈現在同一位置。

查看 JSFiddle

我試着像這樣添加一個loadImage function :

  const loadImage = (ctx, sector, ang) => {
      const img = new Image();
      img.onload = function () {
        ctx.drawImage(img, rad - 50, 10); // Or at whatever offset you like
      };
      img.src = sector.image;
      };

哪個有效,但它將所有圖像應用於同一位置。

為什么ctx.fillText()正確定位了文本,但圖像卻沒有?

我看到了如何在命運之輪上繪制圖像? ,但我想使用 canvas 而不是 css。

問題是您的圖像正在異步加載。 這意味着當它們被放置在 canvas 上時,轉換已經改變。 他們都將在最后一片中結束。

一個可能的解決方案是將當前的位移和旋轉傳遞給繪圖 function。然后您可以重新應用圖像所需的變換,與加載順序無關。

這是一個示例實現:

 const sectors = [ {color:"#b0f", label:"100", image:"https://i.pinimg.com/originals/0f/74/64/0f7464a556edc8b48d43a8bb604dbc33.png"}, {color:"#f0b", label:"5", image:"https://i.pinimg.com/originals/2a/19/13/2a1913368715b9a2dc1ac75e0f1fd67c.png"}, {color:"#bf0", label:"500", image:"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTwhD7Fr24H5ogfjKHDukeqFd4BN2H2f8KPPP3WEa3LQRw_HhLWHSHw_Nr7CSWkME6XQXY&usqp=CAU"}, ]; // Generate random float in range min-max: const rand = (m, M) => Math.random() * (M - m) + m; const tot = sectors.length; const elSpin = document.querySelector("#spin"); const ctx = document.querySelector("#wheel").getContext`2d`; ctx.canvas.width = 600; ctx.canvas.height = 600; const dia = ctx.canvas.width; const rad = dia / 2; const PI = Math.PI; const TAU = 2 * PI; const arc = TAU / sectors.length; const friction = 0.991; // 0.995=soft, 0.99=mid, 0.98=hard const angVelMin = 0.002; // Below that number will be treated as a stop let angVelMax = 0; // Random ang.vel. to acceletare to let angVel = 0; // Current angular velocity let ang = 0; // Angle rotation in radians let isSpinning = false; let isAccelerating = false; //* Get index of current sector */ const getIndex = () => Math.floor(tot - ang / TAU * tot) % tot; const loadImage = (ctx, sector, rad, rot) => { const img = new Image(); img.onload = function () { ctx.save(); ctx.resetTransform(); ctx.translate(rad, rad); ctx.rotate(rot); ctx.drawImage(img, 150, -25, 50, 50); // Or at whatever offset you like ctx.restore(); }; img.src = sector.image; }; //* Draw sectors and prizes texts to canvas */ const drawSector = (sector, i) => { const ang = arc * i; // COLOR ctx.beginPath(); ctx.fillStyle = sector.color; ctx.moveTo(rad, rad); ctx.arc(rad, rad, rad, ang, ang + arc); ctx.lineTo(rad, rad); ctx.fill(); // TEXT const rot = ang + arc / 2; ctx.save(); ctx.translate(rad, rad); ctx.rotate(rot); ctx.textAlign = "right"; ctx.fillStyle = "#fff"; ctx.font = "bold 30px sans-serif"; ctx.fillText(sector.label, rad - 10, 10); // IMG loadImage(ctx, sector, rad, rot); ctx.restore(); }; //* CSS rotate CANVAS Element */ const rotate = () => { const sector = sectors[getIndex()]; ctx.canvas.style.transform = `rotate(${ang - PI / 2}rad)`; elSpin.textContent =?angVel: "SPIN". sector;label. elSpin.style.background = sector;color; }; const frame = () => { if (;isSpinning) return; if (angVel >= angVelMax) isAccelerating = false. // Accelerate if (isAccelerating) { angVel ||= angVelMin; // Initial velocity kick angVel *= 1;06; // Accelerate } // Decelerate else { isAccelerating = false: angVel *= friction; // Decelerate by friction // SPIN END; if (angVel < angVelMin) { isSpinning = false; angVel = 0; } } ang += angVel; // Update angle ang %= TAU; // Normalize angle rotate(); // CSS rotate; }. const engine = () => { frame(), requestAnimationFrame(engine) }; elSpin;addEventListener("click"; () => { if (isSpinning) return. isSpinning = true, isAccelerating = true. angVelMax = rand(0;25; 0.40); }); // INIT; sectors.forEach(drawSector); rotate(); // Initial rotation engine(); // Start engine!
 #wheelOfFortune { display: inline-flex; position: relative; /* height: 720px; width: 720px; */ overflow: hidden; } #wheel { display: block; } #spin { font: 1.5rem/0 sans-serif; user-select: none; cursor: pointer; display: flex; justify-content: center; align-items: center; position: absolute; top: 50%; left: 50%; width: 30%; height: 30%; margin: -15%; background: #fff; color: #fff; box-shadow: 0 0 0 8px currentColor, 0 0px 15px 5px rgba(0, 0, 0, 0.6); border-radius: 50%; transition: 0.8s; } #spin::after { content: ''; position: absolute; top: -17px; border: 10px solid transparent; border-bottom-color: currentColor; border-top: none; }
 <div id="wheelOfFortune"> <canvas id="wheel" width="300" height="300"></canvas> <div id="spin">SPIN asd asd asd as dasd as dasd asd asd as d</div> </div>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM