FabricJs Cannot read property 'className' of null - fabricjs

I just upgraded fabricJs from 1.4.0 to 1.4.13 so that i can use SetSrc() of Image class and when i tried to run my application i got this error :"Cannot read property 'className' of null". Here is the line of code where the error originated from
const options = {
id: client.ProfileId,
class: 'img_wifiClient',
left: (transX + client_left) * canvasFabric.scale,
top: (transY + client_top) * canvasFabric.scale,
selectable: true,
hasBorders: false,
hasControls: false,
padding: 0,
perPixelTargetFind: true,
width: 24,
height: 24,
originX: 'center',
originY: 'center'
}
let image = new fabric.Image('');//*This is where the error originated from*
canvasFabric.add(image);
let src;
if (client.IconName === 'default.png' || client.IconName === null)
{
src = '/Icones/wifi.png';
}
else
{
src = `/Icones/${client.IconName}`;
}
image.setSrc(src, function () {
image.setCoords();
canvasFabric.renderAll();
}, options);
Any help would be appreciated!!

I added an img element with id = "myIcone" under the canvas element in the Html file and added the following lines of code and everything works.
let image_element = document.getElementById('myIcone');
let image = new fabric.Image(image_element);
canvasFabric.add(image);
The rest of the code is the same as in the question snippet

Related

Can't manipulate grouped objects in fabric.js after loading from JSON

I'm trying to implement load/save functionality in a fabric.js project (using fabric.js 5.2.1). The canvas reloads correctly, but I can no longer interact with objects in groups. Non-grouped objects are fine, but pretty much everything in my project is in a group.
<input type="button" id="loadJSON" value="Load JSON" />
<input type="button" id="colorize2" value="Background" />
<input type="button" id="colorize3" value="Square" />
<input type="button" id="colorize" value="Line" />
<canvas id="below" width="960" height="448" style="position:absolute; top:10; left:10;"></canvas>
var jsonString = '{"version":"5.2.1","objects":[{"type":"rect","version":"5.2.1","originX":"left","originY":"top","left":100,"top":100,"width":100,"height":100,"fill":"orange","stroke":null,"strokeWidth":1,"strokeDashArray":null,"strokeLineCap":"butt","strokeDashOffset":0,"strokeLineJoin":"miter","strokeUniform":false,"strokeMiterLimit":4,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"backgroundColor":"","fillRule":"nonzero","paintFirst":"fill","globalCompositeOperation":"source-over","skewX":0,"skewY":0,"id":"square","rx":0,"ry":0,"selectable":true,"perPixelTargetFind":false,"centeredScaling":false,"centeredRotation":true,"borderColor":"rgb(178,204,255)","cornerColor":"rgb(178,204,255)","cornerSize":13,"transparentCorners":true},{"type":"group","version":"5.2.1","originX":"left","originY":"top","left":477.7,"top":25.62,"width":5.25,"height":396.17,"fill":"rgb(0,0,0)","stroke":null,"strokeWidth":0,"strokeDashArray":null,"strokeLineCap":"butt","strokeDashOffset":0,"strokeLineJoin":"miter","strokeUniform":false,"strokeMiterLimit":4,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"backgroundColor":"","fillRule":"nonzero","paintFirst":"fill","globalCompositeOperation":"source-over","skewX":0,"skewY":0,"id":"ElementGroup","selectable":false,"perPixelTargetFind":false,"centeredScaling":false,"centeredRotation":true,"borderColor":"rgb(178,204,255)","cornerColor":"rgb(178,204,255)","cornerSize":13,"transparentCorners":true,"objects":[{"type":"path","version":"5.2.1","originX":"left","originY":"top","left":-2.63,"top":-198.09,"width":4.25,"height":395.17,"fill":"yellow","stroke":null,"strokeWidth":1,"strokeDashArray":null,"strokeLineCap":"butt","strokeDashOffset":0,"strokeLineJoin":"miter","strokeUniform":false,"strokeMiterLimit":4,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"backgroundColor":"","fillRule":"nonzero","paintFirst":"fill","globalCompositeOperation":"source-over","skewX":0,"skewY":0,"id":"centerLine01","selectable":false,"perPixelTargetFind":false,"centeredScaling":false,"centeredRotation":true,"borderColor":"rgb(178,204,255)","cornerColor":"rgb(178,204,255)","cornerSize":13,"transparentCorners":true,"path":[["M",478.19727,26.119141],["L",478.19727,421.29297],["L",482.45117,421.29297],["L",482.45117,26.119141],["L",478.19727,26.119141],["z"]]}]}],"background":"green","perPixelTargetFind":false,"centeredScaling":false,"centeredRotation":false,"backgroundColor":"blue"}'
var below = new fabric.Canvas('below', {
enableRetinaScaling: false,
preserveObjectStacking: true,
backgroundColor: 'green'
});
rect = new fabric.Rect({
top: 100,
left: 100,
width: 100,
height: 100,
fill: 'blue',
id: 'square'
})
centerLine01 = new fabric.Path("M 478.19727 26.119141 L 478.19727 421.29297 L 482.45117 421.29297 L 482.45117 26.119141 L 478.19727 26.119141 z", {
fill: 'red',
id: 'centerLine01',
visible: true,
selectable: false,
evented: false
});
ElementGroup = new fabric.Group([centerLine01], {
id: 'ElementGroup',
visible: true,
selectable: false,
evented: false
})
below.add(rect)
below.add(ElementGroup)
below.renderAll()
$("#loadJSON").on("click", function(e) {
below.loadFromJSON(jsonString, below.renderAll.bind(below), function(o, object) {
below.add(object)
});
below.renderAll.bind(below)
console.log("JSON loaded!")
})
$("#colorize").on("click", function(e) {
const randomColor = "#" + Math.floor(Math.random() * 16777215).toString(16)
ElementGroup.getObjects().forEach(function(o) {
if (o.id == "centerLine01") {
o.set("fill", randomColor)
below.renderAll()
}
})
})
$("#colorize2").on("click", function(e) {
const randomColor = "#" + Math.floor(Math.random() * 16777215).toString(16)
below.setBackgroundColor(randomColor, below.renderAll.bind(below))
})
$("#colorize3").on("click", function(e) {
const randomColor = "#" + Math.floor(Math.random() * 16777215).toString(16)
below.getObjects().forEach(function(o) {
if (o.id == "square") {
o.set("fill", randomColor)
below.renderAll()
}
})
})
In this sample, the Background, Square and Line buttons all work out of the gate, but as soon as you reload the canvas from JSON the Line button no longer does anything, even though the object is still getting found (a simple console.log() verifies that). Not quite sure what the issue is, though.
jsfiddle here: https://jsfiddle.net/eriqjaffe/jo25d8qs/8/

Phaser 3: Spritesheet doesn't load correctly

I tried to add a spritesheet to my Phaser game the same way I've done it a few times before, however this time it seems to not load the images correctly, causing it to display a black & green square instead and causing it to throw an error when trying to play an animation.
Can anyone tell what is causing this issue?
(Warning: Playing the Code here seems to freeze up your browser for a few seconds, alternatively view on JSFiddle: https://jsfiddle.net/cak3goru/4/ )
// Configs and Constants
const gameState = {
gameWidth: 800,
gameHeight: 800,
textStyle: {
fontFamily: "'Comic Sans MS'",
fill: "#fff",
align: "center",
boundsAlignH: "left",
boundsAlignV: "top"
},
mouseDown: false,
menu: {
options: [
"Feed", "Clean", "Play"
],
barColor: "0x123456",
items: [],
itemText: [],
itemColor: "0x654321",
}
};
function preload() {
// Clean Tools
this.load.atlas('clean', 'https://gaylie.neocities.org/game/assets/clean.png', 'https://gaylie.neocities.org/game/assets/clean.json');
}
function create () {
this.anims.create({
key: "shower_cursor",
framerate: 12,
frames: this.anims.generateFrameNumbers("clean", {
prefix: "showerhead_000",
start: 0,
end: 7}),
repeat: -1
});
gameState.shower_cursor = this.add.sprite(400,400,'shower_cursor');
console.log(gameState.shower_cursor.frame);
//gameState.shower_cursor.playAfterDelay('shower_cursor', 100);
//gameState.shower_cursor.alpha = 0;
}
var config = {
backgroundColor: "0xf0f0f0",
scale: {
width: gameState.gameWidth,
height: gameState.gameHeight,
autoCenter: Phaser.Scale.CENTER_BOTH
},
scene: {
preload, create
}
};
var game = new Phaser.Game(config);
<head>
<title>Pet Simulator</title>
<script src="//cdn.jsdelivr.net/npm/phaser#3.55.2/dist/phaser.min.js"></script>
</head>
<body style="height: 100%; width: 100%; margin: 0;">
</body>
The problem is, that you are using the wrong function, you should use this.anims.generateFrameNames, and not this.anims.generateFrameNumbers.
And set the correct key clean for the sprite.
the line should be:
gameState.shower_cursor = this.add.sprite(200, 100, 'clean');
because shower_cursor, is only the key of the animation, not the key of the sprite.
P.s.: the posted code doesn't run on jsfiddler or Stackoverflow due to CORS-Error, but if all assets are on the same server, it should not be a problem.

Pattern not applying on line object fabricjs

I am facing as issue using fabricjs as pattern is not applying on line object. It fills the object property with pattern images but is not showing pattern on line. jsfiddle ins attached.
var line = new fabric.Line([10, 25, 300, 25], {
stroke: 'red',
strokeWidth: 5,
selectable: true,
left: 0,
top: 0
});
canvas.add(line);
fabric.util.loadImage('http://fabricjs.com/assets/escheresque_ste.png', function (img) {
line.setPatternFill({
source: img,
repeat: 'repeat'
});
canvas.renderAll();
});
console.log(line);
Because Fabric js setPatternFill only apply pattern to the fill property of object.But line object not have a fill property,only have a stroke so we apply pattern differently like new fabric.Pattern
var canvas = new fabric.Canvas("c")
var line = new fabric.Line([10, 25, 300, 25], {
stroke: 'red',
fill:"red",
strokeWidth: 10,
selectable: true,
left: 0,
top: 0
});
canvas.add(line);
fabric.util.loadImage('http://fabricjs.com/assets/escheresque_ste.png', function (img) {
line.stroke = new fabric.Pattern({
source: img,
repeat: 'repeat'
});
canvas.renderAll();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.5.0/fabric.min.js"></script>
<canvas id="c"></canvas>

Fabric.js accessing to group in a function

Hello guy and thanks so much for your help.
I am a newbie in fabric.js and I have a basic question.
I create a group of 3 objects in a function.
I want to change property of an object of this group in another function.
And more generally it will be really useful if someone can explain to me how to access to another object of a group?
I don't know how to do that.
function groupit() //Works {
var circle1 = new fabric.Circle({
radius: 50,
fill: 'red',
left: 0
});
var circle2 = new fabric.Circle({
radius: 50,
fill: 'green',
left: 100
});
var circle3 = new fabric.Circle({
radius: 50,
fill: 'blue',
left: 200
});
var group = new fabric.Group([ circle1, circle2, circle3 ], {
left: 200,
top: 100
});
canvas.add(group);
}
function groupchg() //Does not work {
canvas.setActiveGroup(group);
group.add(new fabric.Rect({
left: 100,
top: 100,
originX: 'center',
originY: 'center'
}));
}
Because you call canvas.setActiveGroup(group); in your function groupchg(), and property group is probably null. Can fix if define group property out of function groupit().
Ok found solution.
To access to specific object of a group i use this code :
function groupchg() {
//console.log(canvas.getActiveGroup());
canvas.setActiveObject(canvas._objects[0]._objects[1]);
var activeObj = canvas.getActiveObject();
activeObj.setFill('red');
activeObj.set({left: 30,top:150});
canvas.renderAll();
}

Render page element with padding in Poltergeist

I would like take screenshot of element with page context, let say 10px around element.
In PhantomJs I would do it
phantom.clipRect = { top: 14, left: 3, width: 400, height: 300 };
phantom.render(output);
I did not find clipRect in Poltergeist.
Is it possible to use phantom.clipRect?
Thanks
I found workaround, to make screenshot of element with 10px around element.
I add dynamically new DOM element 'wrap' and put it around target.
Then I take screenshot of wrap. It work!
Code:
result_file = File.expand_path('../tmp/screenshot.jpg', __FILE__)
browser.execute_script %Q(
// add jQuery
(function(){
function getScript(src, callback) {
var fileref = document.createElement('script');
fileref.setAttribute("type","text/javascript");
fileref.setAttribute("src", src);
if (callback) {
fileref.setAttribute("onload", callback());
}
document.getElementsByTagName("head")[0].appendChild(fileref);
}
getScript('https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js', function(){
$(function() {
var target = $('#{screenshot_target_selector}');
var offset = target.offset();
var wrap = $('<div id="inlinemanual_screenshot_target_selector_wrap"></div>').prependTo('body');
wrap.css({
position: 'absolute',
width: target.outerWidth() + 20,
height: target.outerHeight() + 20,
top: offset.top - 10,
left: offset.left - 10
});
});
});
}())
)
browser.screenshot_element(result_file, '#inlinemanual_screenshot_target_selector_wrap')

Resources