如何解决如何在最大化的canvas元素中使Pixi.js舞台适合和居中对齐?
我已经为问题准备了完整的jsfiddle-
对于一个棋盘游戏,我试图使用两侧的jQuery UI按钮并将屏幕的其余部分分配给Pixi绘图区域。
我发现Pixi.js开发人员对scale the stage提出了一个建议,以便其子级可以自动缩放,而在下面我尝试实现它:
$(function() {
var WIDTH = 400;
var HEIGHT = 400;
var RATIO = WIDTH / HEIGHT;
var scaleX = 1,scaleY = 1,offsetX = 0,offsetY = 0,oldX,oldY;
var app = new PIXI.Application({
width: WIDTH,height: HEIGHT,view: document.getElementById('pixiCanvas'),backgroundColor: 0xFFFFFF
});
app.stage.interactive = true;
app.stage.on('pointerdown',onDragStart)
.on('pointerup',onDragEnd)
.on('pointerupoutside',onDragEnd)
.on('pointermove',onDragMove);
var background = new PIXI.Graphics();
for (var i = 0; i < 8; i++) {
for (var j = 0; j < 8; j++) {
if ((i + j) % 2 == 0) {
background.beginFill(0xCCCCFF);
background.drawRect(i * WIDTH / 8,j * HEIGHT / 8,WIDTH / 8,HEIGHT / 8);
background.endFill();
}
}
}
app.stage.addChild(background);
var bunny = PIXI.Sprite.from('https://pixijs.io/examples/examples/assets/bunny.png');
bunny.anchor.set(0.5);
bunny.scale.set(2);
bunny.x = WIDTH / 2;
bunny.y = HEIGHT / 2;
app.stage.addChild(bunny);
function onDragStart(ev) {
var stagePoint = ev.data.getLocalPosition(app.stage);
if (bunny.getBounds().contains(stagePoint.x,stagePoint.y)) {
bunny.alpha = 0.5;
oldX = stagePoint.x;
oldY = stagePoint.y;
this.data = ev.data;
}
}
function onDragMove() {
if (this.data) {
var stagePoint = this.data.getLocalPosition(app.stage);
bunny.x += stagePoint.x - oldX;
bunny.y += stagePoint.y - oldY;
oldX = stagePoint.x;
oldY = stagePoint.y;
}
}
function onDragEnd() {
if (this.data) {
bunny.alpha = 1;
var stagePoint = this.data.getLocalPosition(app.stage);
this.data = null;
}
}
$(':button').button();
$('#scaleCheck').checkboxradio();
window.onresize = function() {
if (!$('#scaleCheck').prop('checked')) {
return;
}
var canvasRatio = $('#pixiCanvas').width() / $('#pixiCanvas').height();
if (canvasRatio > RATIO) { // if canvas is too wide
scaleX = 1 / canvasRatio;
scaleY = 1;
offsetX = 0;
offsetY = 0;
} else {
scaleX = 1;
scaleY = canvasRatio;
offsetX = 0;
offsetY = 0;
}
app.stage.scale.set(scaleX,scaleY);
app.stage.position.set(offsetX,offsetY); // how to center-align?
}
window.onresize();
});
body {
margin: 0;
padding: 0;
}
#mainDiv {
width: 100%;
height: 100vh;
background: #FFF;
display: flex;
}
#leftMenuDiv {
text-align: center;
background: #FCC;
}
#rightMenuDiv {
text-align: center;
background: #CFC;
flex-shrink: 1;
}
#canvasDiv {
flex-grow: 1;
}
#pixiCanvas {
width: 100%;
height: 100%;
background: #CCF;
box-sizing: border-box;
border: 4px red dotted;
}
<div id="mainDiv">
<div id="leftMenuDiv">
<button id="btn1">Button 1</button><br>
<button id="btn2">Button 2</button><br>
<button id="btn3">Button 3</button><br>
</div>
<div id="canvasDiv">
<canvas id="pixiCanvas"></canvas>
</div>
<div id="rightMenuDiv">
<input id="scaleCheck" type="checkbox">
<label for="scaleCheck">Fit and center Pixi stage</label><br>
<button id="btn4">Button 4</button><br>
<button id="btn5">Button 5</button><br>
<button id="btn6">Button 6</button><br>
</div>
</div>
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/pixi.js@5.3.3/dist/pixi.min.js"></script>
我与上面的代码有关的问题如下-
第一次运行我的代码时,它可以工作。但是,设置复选框并调整浏览器窗口的大小后,拖动将中断。
解决方法
我已经可以通过以下代码解决我的问题:
$(function() {
var WIDTH = 400;
var HEIGHT = 400;
var RATIO = WIDTH / HEIGHT;
var scaleX = 1,scaleY = 1,offsetX = 0,offsetY = 0;
var app = new PIXI.Application({
width: WIDTH,height: HEIGHT,view: document.getElementById('pixiCanvas'),backgroundColor: 0xFFFFFF
});
var background = new PIXI.Graphics();
for (var i = 0; i < 8; i++) {
for (var j = 0; j < 8; j++) {
if ((i + j) % 2 == 0) {
background.beginFill(0xCCCCFF);
background.drawRect(i * WIDTH / 8,j * HEIGHT / 8,WIDTH / 8,HEIGHT / 8);
background.endFill();
}
}
}
app.stage.addChild(background);
var bunny = PIXI.Sprite.from('https://pixijs.io/examples/examples/assets/bunny.png');
bunny.interactive = true;
bunny.buttonMode = true;
bunny.anchor.set(0.5);
bunny.scale.set(2);
bunny.x = WIDTH / 2;
bunny.y = HEIGHT / 2;
bunny.on('pointerdown',onDragStart)
.on('pointerup',onDragEnd)
.on('pointerupoutside',onDragEnd)
.on('pointermove',onDragMove);
app.stage.addChild(bunny);
function onDragStart(ev) {
this.data = ev.data;
this.alpha = 0.5;
}
function onDragMove() {
if (this.data) {
var newPos = this.data.getLocalPosition(this.parent);
this.x = newPos.x;
this.y = newPos.y;
}
}
function onDragEnd() {
if (this.data) {
this.alpha = 1;
this.data = null;
}
}
$(':button').button();
$('#scaleCheck').checkboxradio();
window.onresize = function() {
if (!$('#scaleCheck').prop('checked')) {
return;
}
var canvasRatio = $('#pixiCanvas').width() / $('#pixiCanvas').height();
if (canvasRatio > RATIO) { // if canvas is too wide
scaleX = RATIO / canvasRatio;
scaleY = 1;
offsetX = (1 - scaleX) * WIDTH / 2;
offsetY = 0;
} else {
scaleX = 1;
scaleY = canvasRatio / RATIO;
offsetX = 0;
offsetY = (1 - scaleY) * HEIGHT / 2;
}
app.stage.scale.set(scaleX,scaleY);
app.stage.position.set(offsetX,offsetY);
}
window.onresize();
});
body {
margin: 0;
padding: 0;
}
#mainDiv {
width: 100%;
height: 100vh;
background: #FFF;
display: flex;
}
#leftMenuDiv {
text-align: center;
background: #FCC;
}
#rightMenuDiv {
text-align: center;
background: #CFC;
flex-shrink: 1;
}
#canvasDiv {
flex-grow: 1;
}
#pixiCanvas {
width: 100%;
height: 100%;
background: #CCF;
box-sizing: border-box;
border: 4px red dotted;
}
<div id="mainDiv">
<div id="leftMenuDiv">
<button id="btn1">Button 1</button><br>
<button id="btn2">Button 2</button><br>
<button id="btn3">Button 3</button><br>
</div>
<div id="canvasDiv">
<canvas id="pixiCanvas"></canvas>
</div>
<div id="rightMenuDiv">
<input id="scaleCheck" type="checkbox" checked>
<label for="scaleCheck">Fit and center Pixi stage</label><br>
<button id="btn4">Button 4</button><br>
<button id="btn5">Button 5</button><br>
<button id="btn6">Button 6</button><br>
</div>
</div>
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/pixi.js@5.3.3/dist/pixi.min.js"></script>
对我来说,主要的变化是使可拖动的精灵具有交互性,并向其添加了拖动侦听器-而不是app.stage
。
也许app.stage
和我的原始代码一样可以是交互式的?我认为在那种情况下需要进行一些矩阵计算,这就是为什么很难弄清楚数学的原因。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。