Related
I have a demo here: https://codepen.io/Jsbbvk/pen/KKXNPYO
var canvas = new fabric.Canvas("canvas");
const text = new fabric.IText("sample text")
text.set({
fontFamily: "Impact",
left: (this.canvas.width - text.width) / 2,
top: (this.canvas.height - text.height) / 2,
})
canvas.add(text)
canvas.requestRenderAll()
If you visit this codepen on a mobile device, you'll see that the Impact font doesn't load. However, visiting this codepen on a desktop will work. Is there a fix to this?
Impact is not preinstalled on android devices
Actually, the term "web safe fonts" is just plain wrong! (see also: "Impact" font not working on mobile Chrome
Workaround use a async font loader to check the availability
Check if fonts are available via document.fonts.check()
If necessary: load the font via asynchronous helper function loadFonts(fontsToLoad) (based on FontFace.load() method)
You also need to init fabric.js after fonts are loaded:
JS:
async function initFabric() {
var canvas = new fabric.Canvas("canvas");
const text = new fabric.IText("sample text");
let canvasContainer = document.querySelector(".canvas-container");
//load fonts if necessary
let fontsToLoad = checkFontAvailability(fonts);
await loadFonts(fontsToLoad);
text.set({
fontFamily: "Impact",
left: (this.canvas.width - text.width) / 2,
top: (this.canvas.height - text.height) / 2
});
canvas.add(text);
canvas.requestRenderAll();
}
Working example
/**
* fonts to check
*/
let fonts = [{
'font-family': 'Arial',
'font-style': 'normal',
'font-weight': 400,
'src': 'https://fonts.gstatic.com/s/anton/v23/1Ptgg87LROyAm3Kz-C8.woff2'
},
{
'font-family': 'Times New Roman',
'font-style': 'normal',
'font-weight': 400,
'src': 'https://fonts.gstatic.com/s/anton/v23/1Ptgg87LROyAm3Kz-C8.woff2'
},
{
// Inter as replacement
'font-family': 'Helvetica',
'font-style': 'normal',
'font-weight': 400,
'src': 'https://fonts.gstatic.com/s/inter/v12/UcC73FwrK3iLTeHuS_fvQtMwCp50KnMa1ZL7.woff2'
},
{
// Anton as replacement
'font-family': 'Impact',
'font-style': 'normal',
'font-weight': 400,
'src': 'https://fonts.gstatic.com/s/anton/v23/1Ptgg87LROyAm3Kz-C8.woff2'
},
]
/**
* init fabric after font check
*/
initFabric();
async function initFabric() {
var canvas = new fabric.Canvas("canvas");
const text = new fabric.IText("sample text");
let canvasContainer = document.querySelector('.canvas-container');
//load fonts if necessary
let fontsToLoad = checkFontAvailability(fonts);
await loadFonts(fontsToLoad);
text.set({
fontFamily: "Impact",
left: (this.canvas.width - text.width) / 2,
top: (this.canvas.height - text.height) / 2,
})
canvas.add(text)
canvas.requestRenderAll()
//add buttons
fonts.forEach(function(font) {
let fontFamily = font['font-family']
let btn = document.createElement('button')
btn.setAttribute('type', 'button')
btn.classList.add('btn-font');
btn.textContent = fontFamily
canvasContainer.parentNode.insertBefore(btn, canvasContainer);
btn.addEventListener("click", () => {
text.fontFamily = fontFamily
canvas.renderAll()
})
})
}
function checkFontAvailability(fonts) {
let info = [];
let fontsToLoad = [];
if (fonts.length) {
fonts.forEach(function(font) {
let fontFamily = font['font-family'];
let fontApplied = document.fonts.check(`12px ${fontFamily}`);
if (!fontApplied) {
fontsToLoad.push(font)
}
})
}
return fontsToLoad;
}
async function loadFonts(fontsToLoad) {
if (fontsToLoad.length) {
for (let i = 0; i < fontsToLoad.length; i++) {
let fontProps = fontsToLoad[i];
let fontFamily = fontProps['font-family'];
let fontWeight = fontProps['font-weight'];
let fontStyle = fontProps['font-style'];
let fontUrl = Array.isArray(fontProps['src']) ? fontProps['src'][0][0] : fontProps[
'src'];
if (fontUrl.indexOf('url(') === -1) {
fontUrl = 'url(' + fontUrl + ')';
}
let fontFormat = fontProps['src'][0][1] ? fontProps['src'][1] : '';
const font = new FontFace(fontFamily, fontUrl);
font.weight = fontWeight;
font.style = fontStyle;
await font.load();
document.fonts.add(font);
console.log(fontFamily, 'loaded')
// apply font styles to invisible elements
let fontDOMEl = document.createElement('div');
fontDOMEl.textContent = '';
document.body.appendChild(fontDOMEl);
fontDOMEl.setAttribute(
"style",
`position:fixed; height:0; width:0; overflow:hidden; font-family:${fontFamily}; font-weight:${fontWeight}; font-style:${fontStyle}`
);
}
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/4.3.0/fabric.min.js"></script>
<canvas width="300" height="300" id="canvas"></canvas>
loadFonts() will append invisible elements to your DOM with the desired font-families applied.
This will ensure the loaded fonts are also available for canvas elements.
I am studying javascript at a very basic level, we have a school assaignment where the teacher handed out a simple game for each student. The task here is to change the game a little. I am very bad at javascript and I would like some help by someone skilled. My question is : How do I make the gates appear at random coordinates? right now it looks like this :
window.onload = function() {
class MazeToGoal extends Phaser.Scene {
constructor (config)
{
super(config);
Phaser.Scene.call(this, { key: "MazeToGoal", active: true });
this.gameOn=true;
this.score=0;
this.scoreMsg="Score: ";
this.scoreText;
this.my_buttons = [];
this.step=4;
this.counter;
this.gates=[];
}
preload() {
this.load.spritesheet('mushrooms', 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAIAAABMXPacAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAL8SURBVHhe7dHRcqMwEETR/f+fzlZtXW/jAmKITY+T3PPYIwmh/vOhURYwzAKGWcAwCxhmAcMsYJgFDLOAYRYwzAKGfY8C/pzEtu/gve7K+12Gz7yT4TvxMEO4xKiBS/D3b4bL1fU+zI++Pa7bcvn3+K3ncNYZ7HwCB13sws/wHyex+Rp84wx2XuaSD3D3A9gwhEscw55Xe/G5XPYRVr8NrnUAG17nZSdywU+x9I1x0UdY/QovOItL7WPdt8LV97HuaU8dxF32se7b4jf2se4JXz+CK+xg0Y/AL+1g0Vd9cT8f38KKH4ff28Gi807v5INbWPGj8atbWHHSuW18aoXxr8FvrzA+48QePrLC+Jfh51cYH3Z0A8ffY/aL8RD3mB1zaDUH32P26/Ec95gd8MUCGOgfHuUes0cer+O8BQZa4GkWGDzyYB2HLTDQCg+0wOBTny3imAUG2sEzLTDYZwGvxDMtMNi3u4IDFhjoUzzWAoMdRwsg1QE82Q3pju0xWxcY6ACebIHBlkMFkOowHu6GdIsFXIKHuyHdYgGX4OFuSLdszNikl+JxVyyghMddsYASHnfFAkp43BULKOFxV3YH1+FGN6QTuMENaZcFBGmXBQRplwUEaZcFBGmXBQRplwUEaZcFBGmXBQRplwUEaZcFBGmXBQRplwUEaZcFBGmXBQRplwUEaZcFBGmXBQRplwUEaZcFBGmXBQRplwUEaZcFBGmXBQRplwUEaZcFBGmXBQRplwUEaZcFBGmXBQRplwUEaZcFBGmXBQRplwUEaZcFBGmXBQRplwUEaZcFBGmXBQRplwUEaZcFBGmXBQRplwUEaZcFBGmXBQRplwUEaZcFBGmXBQRplwUEaZcFBGmXBQRplwUEaZcFBGmXBQRplwUEaZcFBGmXBQRp13wB74P7dVlAcL8uCwju12UBwf26LCC4X9fMV/WfBQyzgGEWMMwChlnAMAsYZgHDLGCYBQyzgGEWMMwChlnAMAsYZgHDLGCYBQyzgGEWMOrj4y8tsH+sT76qdwAAAABJRU5ErkJggg==', { frameWidth: 128, frameHeight: 128});
}
create ()
{
this.pen = this.make.graphics({x: 0, y: 0, add: false});
this.pen.fillStyle(0x00FF00, 1.0);
this.pen.fillRect(0, 0, 30, 30);
this.pen.generateTexture('goal', 30, 30);
this.player = this.add.image(100, 270, 'goal');
this.scoreText = this.add.text(10, 10, this.scoreMsg+this.score, { fontSize: '32px', fill: '#FFF' });
this.counter=0;
this.gates[0] = this.createGate(100);
this.cursors = this.input.keyboard.createCursorKeys();
}
update()
{
if(this.gameOn) {
this.counter++;
if(this.counter % 200 === 0) {
this.gates.push(this.createGate(100));
}
if (this.cursors.up.isDown)
{
this.player.y-=this.step;
}
else if (this.cursors.down.isDown)
{
this.player.y+=this.step;
}
if(this.player.x-5 < this.gates[0].left.x && this.gates[0].left.x < this.player.x+5) {
if(this.gates[0].left.y < this.player.y && this.player.y < this.gates[0].right.y) {
console.log("Hit");
this.gates.shift();
}
else {
this.gameOn=false;
this.add.text(25, 200,"Game Over", { fontSize: '128px', fill: '#F00' });
console.log("Boom");
}
}
}
}
createGate(StartY) {
let gate={};
gate.left = this.add.image(700,StartY, 'mushrooms', 1).setScale(0.25);
gate.right = this.add.image(700, StartY+100, 'mushrooms', 1).setScale(0.25);
gate.tween = this.tweens.add({
targets: [gate.left, gate.right] ,
x: -50,
//ease: 'Power1',
duration: 5000
});
return gate;
}
}
const config = {
type: Phaser.WEBGL,
width: 800,
height: 600,
backgroundColor: "#FFFFFF",
parent: "phaser-example",
scene: [MazeToGoal]
};
const game = new Phaser.Game(config);
}
<head>
<meta charset="utf-8" />
<title>MushroomSlalom</title>
<script src="https://cdn.jsdelivr.net/npm/phaser#3.1.1/dist/phaser.min.js"></script>
</head>
<body>
<div id="phaser-example"></div>
</body>
Thanks in advance!
In Phaser 3, you can use Phaser.Math.Between() to generate a random number.
So to make gates appear at random locations, determine what area you would want the gates to spawn in, and generate random coordinates within that space.
If you wanted them to spawn anywhere on screen, you could do something like the following.
// Update as needed. Here we have it based upon the width and height of the main camera.
let randomX = Phaser.Math.Between(0, this.cameras.main.width);
let randomY = Phaser.Math.Between(0, this.cameras.main.height);
let gate = this.add.image(randomX, randomY, 'mushrooms', 1);
This ignores that part of the image might be off-screen; you'd want to add an appropriate buffer to account for the anchor point.
I'm writing a jquery plugin the code below is not working (I mean the setTimeout is working but nothing is append)
var self = this;
for (var i=0; i<=10; i++) {
setTimeout(function() {
self.append(bubble);
}, 1000);
}
And the code below is working:
for (var i=0; i<=10; i++) {
this.append(bubble);
}
this is a jquery selection. I really don't get what's going on. It can't be scope issue .. can it be ? I don't get it. Thanks in advance for you help
Edit: bubble is a simple div (" ")
Below the whole plugin code:
(function($) {
'use strict';
$.fn.randomBubble = function(options) {
var self = this;
var settings = $.extend({
color: 'blue',
backgroundColor: 'white',
maxBubbleSize: 100
}, options);
var frame = {
height: this.height(),
width: this.width(),
}
var bubble = "<div class='randomBubble'> </div>";
this.getLeft = function(width) {
var left = Math.random() * frame.width;
if (left > (frame.width / 2)) {
left -= width;
} else {
left += width;
}
return left
}
this.getTop = function(height) {
var top = Math.random() * frame.height;
if (top > (frame.height / 2)) {
top -= height;
} else {
top += height;
}
return top
}
this.removeBubbles = function() {
var currentBubbles = this.find('.randomBubble');
if (currentBubbles.length) {
currentBubbles.remove();
}
}
window.oh = this;
for (var i = 0; i <= 10; i++) {
var timer = Math.random() * 1000;
setTimeout(function() {
window.uh = self;
self.append(bubble);
console.log("oh");
}, 1000);
}
this.randomize = function() {
//self.removeBubbles();
var allBubbles = this.find('.randomBubble');
allBubbles.each(function(i, el) {
var height = Math.random() * settings.maxBubbleSize;
var width = height;
$(el).css({
color: settings.color,
backgroundColor: settings.backgroundColor,
zIndex: 1000,
position: 'absolute',
borderRadius: '50%',
top: self.getTop(height),
left: self.getLeft(width),
height: height,
width: width
});
});
}
this.randomize();
//var run = setInterval(self.randomize, 4000);
return this.find('.randomBubble');
}
})(jQuery);
Because the bubbles are appended later due to the setTimeout(), this selector in your randomize() function comes up empty:
var allBubbles = this.find('.randomBubble');
That is why appending them in a simple for loop works fine.
If you really want to use the setTimout() to append your bubbles, one option is to style them when you add them:
setTimeout(function() {
var height = Math.random() * settings.maxBubbleSize;
var width = height;
var b = $(bubble).css({
color: settings.color,
backgroundColor: settings.backgroundColor,
zIndex: 1000,
position: 'absolute',
borderRadius: '50%',
top: self.getTop(height),
left: self.getLeft(width) ,
height: height,
width: width
});
self.append(b);
}, 1000);
Fiddle
Is it because you still call randomize() right away, even when you postpone the creation for one second?
You will also return an empty selection in that case, for the same reason.
Also, you probably want to use the timer variable in setTimeout() instead of hardcoding all to 1000 ms?
this is a javascript selection, the selector in jquery is $(this)
$.fn.randomBubble = function(options) {
var self = $(this);
};
I have a very strange behaviour of my script: only from time to time (seldom 3-4 times at one time right after each other, but more likely every 7th to 150th trial) the skript loads, but I only see a white canvas and get the error message:
Uncaught TypeError: Cannot read property 'getParent' of
undefinedKonva.Util.addMethods.add # konva.min.js:44draw #
floorplansurvey.php:950(anonymous function) #
floorplansurvey.php:985images.(anonymous function).onload #
floorplansurvey.php:390
On reload it often works again...
I just have no idea at all what is happening here, the bug can't be forced/reproduced, I thank you so much, if you have anything you can help me with. Even a strategy for a clearer analysis would be helpful, sorry for being that unspecific and the long code
edit: I've made a jsfiddle under:
https://jsfiddle.net/17548hmv/1/
run it several times, until the error occures
these are the code snippets at:
# floorplansurvey.php:390:
function loadImages(sources, draw) {
//window.location.reload(true);
var images = {};
var loadedImages = 0;
var numImages = 0;
// get num of sources
for(var src in sources) {
numImages++;
}
for(var src in sources) {
images[src] = new Image();
images[src].onload = function() {
if(++loadedImages >= numImages) {
draw(images);
}
};
images[src].src = sources[src];
}
delete (loadedImages);
delete (numImages);
};
# floorplansurvey.php:985images.(anonymous function).onload:
loadImages(sources, function(images) {
draw(images);
});
# floorplansurvey.php:950(anonymous function):
bglayer.add(plan);
# konva.min.js:44draw:
I dont understand this one myself
add:function(t)
{if(arguments.length>1)
{for(var e=0;e<arguments.length;e++)
this.add(arguments[e]);
return this}if(t.getParent())return t.moveTo(this),this;
var n=this.children;
return
Var sources is defined like:
var sources = {
Cd: './graphics/Cd.png',
Cu: './graphics/Cu.png',
Ca: './graphics/Ca.png',
Cs: './graphics/Cs.png',
Cc: './graphics/Cc.png',
Ed: './graphics/Ed.png',
Eu: './graphics/Eu.png',
Ea: './graphics/Ea.png',
Es: './graphics/Es.png',
Ec: './graphics/Ec.png',
Hd: './graphics/Hd.png',
Hu: './graphics/Hu.png',
...and so on
and this is the function draw:
function draw(images) {
for (i=0, len=showdatax.length; i<=len-1; i++)
{
//window.location.reload(true);
var gridcell = new Konva.Rect({
x: parseInt((imagesizeX - showdatax[i])*scalar-(gridcellsize/2)),
y: parseInt((imagesizeY - showdatay[i])*scalar-(gridcellsize/2)),
offset: [0, 0],
width: gridcellsize,
height: gridcellsize,
//fill: 'white',
//stroke: 'grey',
//strokeWidth: 2,
draggable: false,
id: showdatav[i]
});
gridlayer.add(gridcell);
}
//defaultsettiongs
var init = new Array();
init['x'] = new Array();
init['y'] = new Array();
init['x']['c'] = 0*scalar;
init['y']['c'] = 170*scalar;
init['x']['e'] = 0*scalar;
init['y']['e'] = 320*scalar;
init['x']['h'] = 0*scalar;
init['y']['h'] = 470*scalar;
init['x']['l'] = 0*scalar;
init['y']['l'] = 620*scalar;
init['x']['s'] = 0*scalar;
init['y']['s'] = 770*scalar;
init['x']['w'] = 0*scalar;
init['y']['w'] = 920*scalar; var step = 0;
var count = new Array (
'c','e','h','l','s','w');
count['c'] = 0;
count['e'] = 0;
count['h'] = 0;
count['l'] = 0;
count['s'] = 0;
count['w'] = 0;
var starttime = new Date();
var loghistory = '';
//drag event functions
function mouseoverbox (box,active)
{
writeMessage('Click and hold the left mouse button and pull this activity icon to the floorplan.');
box.setFillPatternImage(active);
box.shadowColor('blue');
box.moveTo(templayer);
badgelayer.draw();
templayer.draw();
}
function dragstarttouchstartbox (box,pos,kind)
{
//count[kind]++;
writeMessage('dragstart' + count[kind]);
var boxx = box.x;
box.x(pos.x-1.5*gridcellsize);
var boxy = box.y;
box.y(pos.y-1.5*gridcellsize);
var boxrshadowoffsetx = box.shadowOffset();
box.shadowOffset({x:0.25*gridcellsize,y:0.25*gridcellsize});
box.moveTo(templayer);
badgelayer.draw();
templayer.draw();
}
function dragmovebox (box,pos,kind,success,active,caution)
{
writeMessage('Your outside of the floorplan. Dropping the activity icon will reset it to its initial position.');
box.moveTo(templayer);
var boxx = box.x;
box.x(pos.x-1.5*gridcellsize);
var boxy = box.y;
box.y(pos.y-1.5*gridcellsize);
var shape = gridlayer.getIntersection(pos);
if (shape)
{
if (!badgelayer.getIntersection(pos))
{
writeMessage('Release the mouse button to place this activity icon on position (' + shape.x() + '|' + shape.y() + ')');
box.x(shape.x()-gridcellsize);
box.y(shape.y()-gridcellsize);
box.setFillPatternImage(success);
box.shadowColor('green');
badgelayer.draw();
}
else
{
writeMessage('Position (' + shape.x() + '|' + shape.y() + ') is in use!!! Can\'t allocate second activiy icon here.');
var boxx = box.x;
box.x(pos.x-1.5*gridcellsize);
var boxy = box.y;
box.y(pos.y-1.5*gridcellsize);
box.setFillPatternImage(caution);
box.shadowColor('red');
badgelayer.draw();
}
}
else
{
box.setFillPatternImage(active);
box.shadowColor('blue');
templayer.draw();
badgelayer.draw();
}
}
function dragendtouchendbox (box,pos,kind,caution,defaultimage)
{
var shape = gridlayer.getIntersection(pos);
box.moveTo(badgelayer);
templayer.draw();
if (shape && !(badgelayer.getIntersection(pos)))
{
writeMessage('Activity icon successfully placed at position (' + shape.x() + '|' + shape.y() + ').');
box.shadowOffset({x:0,y:0});
box.shadowColor('green');
}
else
{
box.shadowColor('red');
box.setFillPatternImage(caution);
badgelayer.draw();
var fromouttween = new Konva.Tween
({
node: box,
x: init['x'][kind]+imagesizeX*scalar+ gridcellsize,
y: init['y'][kind],
easing: Konva.Easings['EaseOut'],
duration: 0.3
});
if (!shape)
{
writeMessage('Please drop the activity icons inside the floorplan.');
}
else if (badgelayer.getIntersection(pos))
{
writeMessage('Please don\'t drop the activity icons onto a used place.');
}
fromouttween.play();
box.shadowColor('black');
box.setFillPatternImage(defaultimage);
box.shadowOffset({x:0,y:0});
badgelayer.draw();
pos.x=-100;
pos.y=-100;
}
count['kind']++;
step++;
writeResultToForm(pos,count,kind,step,loghistory,starttime);
badgelayer.draw();
templayer.draw();
//writeMessage('dragend');
}
function mouseoutbox (box,defaultimage)
{
box.setFillPatternImage(defaultimage);
box.moveTo(badgelayer);
box.shadowColor('black');
if (!validateForm(false))
{
writeMessage('There are still activity icons left to place.');
}
else
{
writeMessage('All activity icons are placed successfully. You can click "continue" now or change your placements.');
}
badgelayer.draw();
templayer.draw();
}
function alertbox (box,caution)
{
box.setFillPatternImage(caution);
box.shadowcolor('red');
badgelayer.draw;
}
//cbox and text
var textc = new Konva.Text({
x: init['x']['c']+imagesizeX*scalar+gridcellsize*5,
y: init['y']['c']+gridcellsize,
text: 'Cooking',
align: 'left',
width: badgetextwidth
});
var boxc = new Konva.Rect({
x: init['x']['c']+imagesizeX*scalar+gridcellsize,
y: init['y']['c'],
offset: [0, 0],
width: 3*gridcellsize,
height: 3*gridcellsize,
fillPatternImage: images.Cd,
fillPatternScaleX: scalar,
fillPatternScaleY: scalar,
stroke: 'black',
strokeWidth: 4,
draggable: true,
cornerRadius: gridcellsize/2,
shadowColor: 'black',
shadowBlur: 10,
shadowOffset: {x : 0, y : 0},
shadowOpacity: 0.5
});
var boxcd = new Konva.Rect({
x: init['x']['c']+imagesizeX*scalar+gridcellsize,
y: init['y']['c'],
offset: [0, 0],
width: 3*gridcellsize,
height: 3*gridcellsize,
fillPatternImage: images.Cu,
fillPatternScaleX: scalar,
fillPatternScaleY: scalar,
stroke: 'grey',
strokeWidth: 2,
draggable: false,
cornerRadius: gridcellsize/2,
});
boxc.on('mouseover ', function() {
mouseoverbox (this,images.Ca);
});
boxc.on('dragstart', function() {
var pos = stage.getPointerPosition();
dragstarttouchstartbox (this,pos,'c');
});
boxc.on('dragmove', function () {
var pos = stage.getPointerPosition();
dragmovebox(this,pos,'c',images.Cs,images.Ca,images.Cc);
});
boxc.on('dragend', function() {
var pos = stage.getPointerPosition();
dragendtouchendbox (this,pos,'c',images.Cc,images.Cd);
});
boxc.on('mouseout ', function() {
mouseoutbox (this,images.Cd)
});
boxc.on('foo', function() {
alertbox (this,images.Cd)
});
//ebox and text
var texte = new Konva.Text({
x: init['x']['e']+imagesizeX*scalar+gridcellsize*5,
...and so on for all the boxes addes here (5 times as long):
defaultlayer.add(boxcd);
badgelayer.add(boxc);
defaultlayer.add(textc);
defaultlayer.add(boxed);
badgelayer.add(boxe);
defaultlayer.add(texte);
defaultlayer.add(boxhd);
badgelayer.add(boxh);
defaultlayer.add(texth);
defaultlayer.add(boxld);
badgelayer.add(boxl);
defaultlayer.add(textl);
defaultlayer.add(boxsd);
badgelayer.add(boxs);
defaultlayer.add(texts);
defaultlayer.add(boxwd);
badgelayer.add(boxw);
defaultlayer.add(textw);
stage.add(bglayer);
stage.add(gridlayer);
stage.add(defaultlayer);
stage.add(badgelayer);
stage.add(templayer);
}
OK, sorry that it took me so long:
the solution wasn't that easy to find. I found that the script was loaded asynchronously and the png wasn't yet available by using chromes timeline analysis. so i went to my code and had to distinguish between the things, that really should be in the draw function and which not. i added the plan to the array of images (sources) that is loaded (src= ...) before executing draw() and then added
sources.onload= loadImages(sources, function(images) {
draw(images);
});
at the end of my file... no it works without any problem. konva.js had nothing to do with it and is up to now (I'm almost ready) like designed for my project
thanks for the tip #lavrton, it took me on the right way
and you can just put like this:
var imageObj = new Image();
imageObj.src = 'http://localhost:8000/plugins/kamiyar/logo.png';
imageObj.onload = function() {
var img = new Konva.Image({
image: imageObj,
x: stage.getWidth() / 2 - 200 / 2,
y: stage.getHeight() / 2 - 137 / 2,
width: 200,
height: 137,
draggable: true,
stroke: 'blue',
strokeWidth: 1,
dash: [1,5],
strokeEnabled: false
});
layer.add(img);
layer.draw();
};
sorry for my bad English ;)
If anyone has used Phaser, perhaps you can help me with my code. I am trying to create a Flappy Bird clone, and so far it is working pretty well. However, whenever I open the game the first time, the sprites of the pipes don't seem to show up. I've preloaded both the bird and the pipe sprites, and only the bird sprite loads on the first attempt. As soon as the game restarts (when the bird dies), the pipes load normally. I am using WAMP to host a local server.
Here is my code:
var game = new Phaser.Game(400, 490, Phaser.AUTO, 'game_div');
var main_state = {
preload: function() {
this.game.stage.backgroundColor = '#66CCFF';
this.game.load.image('pipe', 'assets/pipe.png');
this.game.load.image('bird', 'assets/bird.png');
this.pipes = game.add.group();
this.pipes.createMultiple(20, 'pipe');
},
add_one_pipe: function(x, y) {
var pipe = this.pipes.getFirstDead();
pipe.reset(x, y);
pipe.body.velocity.x = -200
pipe.outOfBoundsKill = true;
},
add_row_of_pipes: function() {
var hole = Math.floor(Math.random()*5) + 1;
for (var i = 0; i < 8; i++) {
if (i != hole && i != hole + 1) {
this.add_one_pipe(400, i * 60 + 10);
}
}
this.score += 1;
this.label_score.content = this.score;
},
create: function() {
this.bird = this.game.add.sprite(100, 245, 'bird');
this.bird.body.gravity.y = 1000;
var space_key = this.game.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR);
space_key.onDown.add(this.jump, this);
this.timer = this.game.time.events.loop(1500, this.add_row_of_pipes, this);
this.score = 0;
var style = { font: "30px Arial", fill: "#ffffff" };
this.label_score = this.game.add.text(20, 20, "0", style);
},
update: function() {
if (this.bird.inWorld == false) {
this.restart_game();
}
this.game.physics.overlap(this.bird, this.pipes, this.restart_game, null, this);
},
jump: function() {
this.bird.body.velocity.y = -350;
},
restart_game: function() {
this.game.time.events.remove(this.timer);
this.game.state.start('main');
},
};
// Add and start the 'main' state to start the game
game.state.add('main', main_state);
game.state.start('main');
As in the tutorial, try to put the creation of the group in the create function:
create: function() {
this.bird = this.game.add.sprite(100, 245, 'bird');
this.bird.body.gravity.y = 1000;
var space_key = this.game.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR);
space_key.onDown.add(this.jump, this);
this.pipes = game.add.group();
this.pipes.createMultiple(20, 'pipe');
this.timer = this.game.time.events.loop(1500, this.add_row_of_pipes, this);
this.score = 0;
var style = { font: "30px Arial", fill: "#ffffff" };
this.label_score = this.game.add.text(20, 20, "0", style);
},