【问题标题】:how to draw a wheel of fortune?命运之轮怎么画?
【发布时间】:2016-02-24 07:53:53
【问题描述】:

我正在尝试使用本教程创建一个转轮游戏:

http://www.emanueleferonato.com/2015/07/31/create-a-wheel-of-fortune-for-your-html5-games-with-phaser-in-only-a-few-lines/

但是,本教程使用图像作为轮子,我想在 html5/js 中创建它。有点像这样:

https://www.winkbingo.com/images/lp/301114/spin_the_wheel_image.png 这是我目前所拥有的:

var ctx = canvas.getContext("2d");
var end = 0;
var color = ['#F0F8FF','#FAEBD7','#00FFFF','#7FFFD4','#00FF00','#FF8C00'];
var labels = ['label1', 'label2','label3','label4','label5','label6'];
var slices = 6

for (var i = 0; i < slices; i++) {
ctx.fillStyle = color[i];
ctx.beginPath();
ctx.moveTo(canvas.width/2,canvas.height/2);
ctx.arc(canvas.width/2,canvas.height/2,canvas.height/2,end, ((1/slices)*Math.PI*2)+end ,false);
ctx.lineTo(canvas.width/2,canvas.height/2);
ctx.fill();
end += ((1/slices)*Math.PI*2)+end;
}

我希望能够通过更改变量切片(1-6 之间)来更改段数。我还想在顶部显示标签。然后我想使用这个画布而不是那个教程代码中的图像,这样轮子就会随着文本旋转。希望这不会令人困惑。任何人都知道如何做到这一点>我不介意使用任何库等。

【问题讨论】:

  • 这里有一个修复(如果你觉得很难):jsbin.com/bokure/2/edit?html,css,js,output
  • 你有什么尝试应用labels 为什么它没有工作? (我似乎没有在您的代码中找到您绘制labels[n] 的任何地方)。
  • 我还没用过标签,因为我不知道该怎么做

标签: javascript html html5-canvas


【解决方案1】:

使用 JS Canvas 的幸运之轮

const sectors = [
  {color:"#f82", label:"Stack"},
  {color:"#0bf", label:"10"},
  {color:"#fb0", label:"200"},
  {color:"#0fb", label:"50"},
  {color:"#b0f", label:"100"},
  {color:"#f0b", label:"5"},
  {color:"#bf0", label:"500"},
];

const rand = (m, M) => Math.random() * (M - m) + m;
const tot = sectors.length;
const EL_spin = document.querySelector("#spin");
const ctx = document.querySelector("#wheel").getContext('2d');
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
let angVel = 0; // Angular velocity
let ang = 0; // Angle in radians

const getIndex = () => Math.floor(tot - ang / TAU * tot) % tot;

function drawSector(sector, i) {
  const ang = arc * i;
  ctx.save();
  // 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
  ctx.translate(rad, rad);
  ctx.rotate(ang + arc / 2);
  ctx.textAlign = "right";
  ctx.fillStyle = "#fff";
  ctx.font = "bold 30px sans-serif";
  ctx.fillText(sector.label, rad - 10, 10);
  //
  ctx.restore();
};

function rotate() {
  const sector = sectors[getIndex()];
  ctx.canvas.style.transform = `rotate(${ang - PI / 2}rad)`;
  EL_spin.textContent = !angVel ? "SPIN" : sector.label;
  EL_spin.style.background = sector.color;
}

function frame() {
  if (!angVel) return;
  angVel *= friction; // Decrement velocity by friction
  if (angVel < 0.002) angVel = 0; // Bring to stop
  ang += angVel; // Update angle
  ang %= TAU; // Normalize angle
  rotate();
}

function engine() {
  frame();
  requestAnimationFrame(engine)
}

// INIT
sectors.forEach(drawSector);
rotate(); // Initial rotation
engine(); // Start engine
EL_spin.addEventListener("click", () => {
  if (!angVel) angVel = rand(0.25, 0.35);
});
#wheelOfFortune {
  display: inline-block;
  position: relative;
  overflow: hidden;
}

#wheel {
  display: block;
}

#spin {
  font: 1.5em/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</div>
</div>

【讨论】:

  • 漂亮的糖果粉碎机在命运之轮上“旋转”(双关语)! :-)
  • 我们可以在angular 2中使用它吗
  • @RokoC.Buljan 如何在不同的幻灯片上添加不同的背景图片而不是颜色。
  • @RokoC。 buljan 怎样才能停在用户定义的位置??
  • @HardikShah 见this answer
【解决方案2】:

html5 的简单 canvas 具有绘制非常漂亮的“命运之轮”所需的一切,代码很少,不需要库。

  • 您可以使用arc 绘制饼图切片
  • 您可以使用translate/rotate 全局变换来绘制旋转文本
  • 您可以添加阴影和发光效果
  • 您可以使用径向和线性渐变来模拟照明
  • 您可以使用多通道渲染(例如,在已绘制的内容上渲染照明渐变
  • 现代浏览器的速度相当不错...足够快以实时渲染旋转的轮子(我希望绘制单个预先计算的旋转图像会更快,尤其是在移动设备上,但是这种方法需要在旋转轮顶部的另一幅画布中具有阴影)。

例如,这就是我得到的大约 100 行 html 行(3.5k 缩小):

http://raksy.dyndns.org/wheel.html 上的实时示例

【讨论】:

  • 令人印象深刻的发光、阴影和发光效果——加上缓动!!
  • 您好,从现在开始,我一直在使用您的代码,试图弄清楚您如何提出以正确角度选择奖品的公式。速度控制会选择哪个奖品?
  • @POGI:我重新阅读了我的代码,确实是的,speed 决定了指针最终会位于哪个扇区。这也是真正的幸运之轮中发生的情况,但可能更好(保证统一)的方法是选择最后一个扇区,然后播放动画即可到达它。
  • @6502 感谢您的回复。 “选择最后一个扇区”这实际上是我正在尝试做的,但仍然没有进展。在您的代码中,您有以下公式:“angle = angle0 + (speedt - 0.5*speedt*t)*100”。如果你不介意,你能解释一下你是怎么想出来的吗?非常感谢您的帮助,非常感谢。
  • @POGI:我已经更新了源代码,现在spin 调用接受一个参数,即获胜指数和动画时间。在使用基于 sigmoid 的动画在所需的获胜者索引处停止之前,车轮将旋转大约 5 圈。如果您没有看到源强制重新加载页面的任何变化。
【解决方案3】:

我是一个名为 Winwheel.js 的 Javascript 库的创建者,它允许在 HTML 画布上轻松创建获胜/奖品轮盘。

轮子可以是代码绘制或使用图形丰富的图像,它利用 Greensock 的动画平台来实现旋转和其他动画效果。

这是一个使用 Winwheel.js 创建基本代码绘制轮子的简单示例...

var theWheel = new Winwheel({
  'numSegments'  : 8,
  'segments'     :
  [
    {'fillStyle' : '#eae56f', 'text' : 'Prize 1'},
      {'fillStyle' : '#89f26e', 'text' : 'Prize 2'},
      {'fillStyle' : '#7de6ef', 'text' : 'Prize 3'},
      {'fillStyle' : '#e7706f', 'text' : 'Prize 4'},
      {'fillStyle' : '#eae56f', 'text' : 'Prize 5'},
      {'fillStyle' : '#89f26e', 'text' : 'Prize 6'},
      {'fillStyle' : '#7de6ef', 'text' : 'Prize 7'},
      {'fillStyle' : '#e7706f', 'text' : 'Prize 8'}
  ],
  'animation' :
  {
    'type'     : 'spinToStop',
    'duration' : 5,
    'spins'    : 8
  }
});

有一整套 Winwheel.js 教程可帮助您开始使用我的网站。有兴趣请访问http://dougtesting.net/

【讨论】:

  • 我在我的应用程序中使用 winwheel.js,我想为每个段应用渐变颜色。有什么办法可以做到吗?
  • 嗨@user3878988 是的,应该是可能的;几年前我尝试过渐变,它们奏效了。您可以将每个段的 fillStyle 设置为渐变,如w3schools.com/tags/canvas_fillstyle.asp的“更多示例”部分中所见@
  • 嗨@dougtesting.net,非常感谢您的回复。从示例中,似乎将渐变设置为整个画布,但是,我的要求是为每个段设置不同的渐变。你的网站上有没有我可以参考的例子。再次感谢您对此提供的帮助。
  • @user3878988 抱歉,我的网站上没有渐变示例。现在你提醒我,回想几年前我摆弄它的时候,尝试为每个单独的部分做渐变有点时髦。老实说,我不确定我是否找到了解决方案。
  • 嗨 @dougtesting.net 我怎样才能将它集成到 Reactjs 中,你能给我一些例子吗?
猜你喜欢
  • 1970-01-01
  • 2022-01-18
  • 2016-10-25
  • 1970-01-01
  • 2021-03-01
  • 2012-11-25
  • 1970-01-01
  • 2023-02-12
  • 2012-06-23
相关资源
最近更新 更多