fabric on nodeJS, No images rendering at all - node.js

The issue is on Ubuntu 14.04:
NodeJS: 0.10.32
Canvas: 1.3.6
Fabric: 1.6.0-rc.1
Example JSON:
{
"objects": [{
"id": 0,
"name": "1452525510_death_star.svg",
"type": "image",
"originX": "left",
"originY": "top",
"left": 78,
"top": 21,
"width": 512,
"height": 512,
"fill": "rgb(0,0,0)",
"stroke": null,
"strokeWidth": 1,
"strokeDashArray": null,
"strokeLineCap": "butt",
"strokeLineJoin": "miter",
"strokeMiterLimit": 10,
"scaleX": 0.46,
"scaleY": 0.46,
"angle": 0,
"flipX": false,
"flipY": false,
"opacity": 1,
"shadow": null,
"visible": true,
"clipTo": null,
"backgroundColor": "",
"fillRule": "nonzero",
"globalCompositeOperation": "source-over",
"transformMatrix": null,
"_controlsVisibility": {
"tl": false,
"tr": true,
"br": true,
"bl": false,
"ml": true,
"mt": false,
"mr": false,
"mb": true,
"mtr": true
},
"src": "http://somedomain.com/media/patterns/users/1fb158157a882d6a4c983ddc401101d1.svg",
"filters": [{
"type": "Tint",
"color": "#c485c4",
"opacity": 1
}],
"crossOrigin": "",
"alignX": "none",
"alignY": "none",
"meetOrSlice": "meet"
}, {
"id": 1,
"name": "Baby inside",
"type": "image",
"originX": "left",
"originY": "top",
"left": 102,
"top": 290,
"width": 470,
"height": 427,
"fill": "rgb(0,0,0)",
"stroke": null,
"strokeWidth": 1,
"strokeDashArray": null,
"strokeLineCap": "butt",
"strokeLineJoin": "miter",
"strokeMiterLimit": 10,
"scaleX": 0.5,
"scaleY": 0.5,
"angle": 0,
"flipX": false,
"flipY": false,
"opacity": 1,
"shadow": null,
"visible": true,
"clipTo": null,
"backgroundColor": "",
"fillRule": "nonzero",
"globalCompositeOperation": "source-over",
"transformMatrix": null,
"_controlsVisibility": {
"tl": false,
"tr": true,
"br": true,
"bl": false,
"ml": true,
"mt": false,
"mr": false,
"mb": true,
"mtr": true
},
"src": "http://somedomain.com/media/patterns/12.png",
"filters": [{
"type": "Tint",
"color": "#FFFFFF",
"opacity": 1
}],
"crossOrigin": "",
"alignX": "none",
"alignY": "none",
"meetOrSlice": "meet"
}],
"background": "#b0b0b0",
"backgroundImage": {
"id": 0,
"name": "",
"type": "image",
"originX": "left",
"originY": "top",
"left": 0,
"top": 0,
"width": 470,
"height": 574,
"fill": "rgb(0,0,0)",
"stroke": null,
"strokeWidth": 1,
"strokeDashArray": null,
"strokeLineCap": "butt",
"strokeLineJoin": "miter",
"strokeMiterLimit": 10,
"scaleX": 1,
"scaleY": 1,
"angle": 0,
"flipX": false,
"flipY": false,
"opacity": 1,
"shadow": null,
"visible": true,
"clipTo": null,
"backgroundColor": "",
"fillRule": "nonzero",
"globalCompositeOperation": "source-over",
"transformMatrix": null,
"_controlsVisibility": null,
"src": "http://somedomain.com/media/products/121_37_2.jpg",
"filters": [],
"crossOrigin": "",
"alignX": "none",
"alignY": "none",
"meetOrSlice": "meet"
}
Note that this JSON exported with toJSON() has some custom fields: [name, id].
This is from my Node script:
function savetoFile() {
var jsonData = JSONfromAbove;
var out = fs.createWriteStream(filepath);
canvas = fabric.createCanvasForNode(470, 574);
canvas.loadFromJSON(jsonData, function () {
CanvasZoom(parseInt(zoom), function(){
console.log('after zooom');
console.log(canvas.getObjects());
var stream = canvas.createPNGStream();
stream.on('data', function (chunk) {
out.write(chunk);
});
stream.on('end', function () {
out.end();
});
});
});
}
function CanvasZoom(z, callback) {
width = canvas.width;
height = canvas.height;
canvas.setWidth(width*z);
canvas.setHeight(height*z);
canvas.setZoom(z);
canvas.renderAll.bind(canvas);
callback();
}
Facts:
No matter what types of objects I add ('image', 'path',
'path-group') they are not rendering at all, except text and
maybe (I did not tested it) PATHS not from URL's.
In JSON above
there is background img - it doesn't rendering too.
There is no errors at all, however:
The same identical script on OSX works fine BUT:
When I'm trying to add "large" SVG file it gives me:
"image given has not completed loading"
Works fine with HUGE numbers of normal PNG's.
The time to "render" final PNG is proportional to number of objects and their image sizes which might tell that they are loading some kind of well.
I have installed all dependent libs.
Tried to add one object like that ending with the same problem:
fabric.Image.fromURL('http://somedomain.com/media/patterns/12.png', function(oImg, e) {...});
I bet for node-canvas someway failing with URL's.
I spend almost 2 days trying to fix this devilish problem ];>

he issue is that on www.somedomain.com was httpasswd, so it just can't download files but did not throw any errors.
When switched 1.6.0-rc1 to 1.5.X an error occur: "Segmentation Fault".

Related

I am trying to get Values from JSON in Node.JS

I am trying to get values from a json in node.
Here is the code:
https.get('https://www.reddit.com/r/cute/random.json', (resp) => {
let data = '';
resp.on('data', (chunk) => {
data += chunk;
});
const obj = JSON.parse(data);
resp.on('end', () => {
console.log(obj.url);
});
}).on("error", (err) => {
console.log("Error: " + err.message);
});
First I get the json file from Reddit, then the code should parse the data, get the url value and print.
Here is a response from reddit:
[{"kind": "Listing", "data": {"modhash": "k08cakl21qf62e475cdf685ff8f62982c15997278420b30b86", "dist": 1, "children": [{"kind": "t3", "data": {"approved_at_utc": null, "subreddit": "cute", "selftext": "", "user_reports": [], "saved": false, "mod_reason_title": null, "gilded": 0, "clicked": false, "title": "Took this picture at my local zoo", "link_flair_richtext": [], "subreddit_name_prefixed": "r/cute", "hidden": false, "pwls": 6, "link_flair_css_class": null, "downs": 0, "thumbnail_height": 140, "top_awarded_type": null, "parent_whitelist_status": "all_ads", "hide_score": false, "name": "t3_np1ulg", "quarantine": false, "link_flair_text_color": "dark", "upvote_ratio": 1.0, "author_flair_background_color": null, "subreddit_type": "public", "ups": 13, "total_awards_received": 0, "media_embed": {}, "thumbnail_width": 140, "author_flair_template_id": null, "is_original_content": false, "author_fullname": "t2_6oq8e4ri", "secure_media": null, "is_reddit_media_domain": true, "is_meta": false, "category": null, "secure_media_embed": {}, "link_flair_text": null, "can_mod_post": false, "score": 13, "approved_by": null, "is_created_from_ads_ui": false, "author_premium": false, "thumbnail": "https://b.thumbs.redditmedia.com/rcVqy9jgOCmApJ36YpAN9CCDQ2lRC0hSsAqBpt0zBxw.jpg", "edited": false, "author_flair_css_class": null, "author_flair_richtext": [], "gildings": {}, "post_hint": "image", "content_categories": null, "is_self": false, "mod_note": null, "created": 1622491454.0, "link_flair_type": "text", "wls": 6, "removed_by_category": null, "banned_by": null, "author_flair_type": "text", "domain": "i.redd.it", "allow_live_comments": false, "selftext_html": null, "likes": null, "suggested_sort": null, "banned_at_utc": null, "url_overridden_by_dest": "https://i.redd.it/h9b00p6y4g271.jpg", "view_count": null, "archived": false, "no_follow": false, "is_crosspostable": true, "pinned": false, "over_18": false, "preview": {"images": [{"source": {"url": "https://preview.redd.it/h9b00p6y4g271.jpg?auto=webp&s=9962d8aa05efc905e39b67bff7a3385576ef4267", "width": 2448, "height": 3264}, "resolutions": [{"url": "https://preview.redd.it/h9b00p6y4g271.jpg?width=108&crop=smart&auto=webp&s=a30f747ccc3a51648498dbe90ffc92f114f438e5", "width": 108, "height": 144}, {"url": "https://preview.redd.it/h9b00p6y4g271.jpg?width=216&crop=smart&auto=webp&s=4bade02391aff8db706eeb74c3354aace0195048", "width": 216, "height": 288}, {"url": "https://preview.redd.it/h9b00p6y4g271.jpg?width=320&crop=smart&auto=webp&s=76bec250dec57f8ee75c379188c2d209eaa21646", "width": 320, "height": 426}, {"url": "https://preview.redd.it/h9b00p6y4g271.jpg?width=640&crop=smart&auto=webp&s=520ab610461f06a6d64f3a183ef25e33cdee4625", "width": 640, "height": 853}, {"url": "https://preview.redd.it/h9b00p6y4g271.jpg?width=960&crop=smart&auto=webp&s=961c512920a728777b9b13185d53f9afe4f6aaea", "width": 960, "height": 1280}, {"url": "https://preview.redd.it/h9b00p6y4g271.jpg?width=1080&crop=smart&auto=webp&s=6f943fbd5d53b892dd15b28052f12c929e5887b9", "width": 1080, "height": 1440}], "variants": {}, "id": "W08V856IQ3icquk8jx2Q0UiWHZnlDFcsSY7Cdu8J-S4"}], "enabled": true}, "all_awardings": [], "awarders": [], "media_only": false, "can_gild": true, "spoiler": false, "locked": false, "author_flair_text": null, "treatment_tags": [], "visited": false, "removed_by": null, "num_reports": null, "distinguished": null, "subreddit_id": "t5_2qh5l", "mod_reason_by": null, "removal_reason": null, "link_flair_background_color": "", "id": "np1ulg", "is_robot_indexable": true, "num_duplicates": 0, "report_reasons": null, "author": "ForMotherRussia3", "discussion_type": null, "num_comments": 1, "send_replies": true, "media": null, "contest_mode": false, "author_patreon_flair": false, "author_flair_text_color": null, "permalink": "/r/cute/comments/np1ulg/took_this_picture_at_my_local_zoo/", "whitelist_status": "all_ads", "stickied": false, "url": "https://i.redd.it/h9b00p6y4g271.jpg", "subreddit_subscribers": 96358, "created_utc": 1622462654.0, "num_crossposts": 0, "mod_reports": [], "is_video": false}}], "after": null, "before": null}}, {"kind": "Listing", "data": {"modhash": "k08cakl21qf62e475cdf685ff8f62982c15997278420b30b86", "dist": null, "children": [{"kind": "t1", "data": {"total_awards_received": 0, "approved_at_utc": null, "comment_type": null, "awarders": [], "mod_reason_by": null, "banned_by": null, "ups": 1, "author_flair_type": "text", "removal_reason": null, "link_id": "t3_np1ulg", "author_flair_template_id": null, "likes": null, "replies": "", "user_reports": [], "saved": false, "id": "h02og3g", "banned_at_utc": null, "mod_reason_title": null, "gilded": 0, "archived": false, "no_follow": true, "author": "AutoModerator", "can_mod_post": false, "send_replies": false, "parent_id": "t3_np1ulg", "score": 1, "author_fullname": "t2_6l4z3", "report_reasons": null, "approved_by": null, "all_awardings": [], "subreddit_id": "t5_2qh5l", "body": "This is the perfect post for r/cute!\n\n*I am a bot, and this action was performed automatically. Please [contact the moderators of this subreddit](/message/compose/?to=/r/cute) if you have any questions or concerns.*", "edited": false, "downs": 0, "author_flair_css_class": null, "is_submitter": false, "collapsed": false, "author_flair_richtext": [], "author_patreon_flair": false, "body_html": "<div class=\"md\"><p>This is the perfect post for <a href=\"/r/cute\">r/cute</a>!</p>\n\n<p><em>I am a bot, and this action was performed automatically. Please <a href=\"/message/compose/?to=/r/cute\">contact the moderators of this subreddit</a> if you have any questions or concerns.</em></p>\n</div>", "gildings": {}, "collapsed_reason": null, "associated_award": null, "stickied": false, "author_premium": true, "subreddit_type": "public", "can_gild": true, "top_awarded_type": null, "author_flair_text_color": null, "score_hidden": false, "permalink": "/r/cute/comments/np1ulg/took_this_picture_at_my_local_zoo/h02og3g/", "num_reports": null, "locked": false, "name": "t1_h02og3g", "created": 1622491455.0, "subreddit": "cute", "author_flair_text": null, "treatment_tags": [], "created_utc": 1622462655.0, "subreddit_name_prefixed": "r/cute", "controversiality": 0, "depth": 0, "author_flair_background_color": null, "collapsed_because_crowd_control": null, "mod_reports": [], "mod_note": null, "distinguished": "moderator"}}], "after": null, "before": null}}]
When I run the code (Includes are present but not shown in the code snippet I have imported https) I get this error:
SyntaxError: Unexpected end of JSON input
at JSON.parse (<anonymous>)
at ClientRequest.<anonymous> (C:\Users\cameron\Desktop\cjp\bot.js:22:20)
at Object.onceWrapper (node:events:485:26)
at ClientRequest.emit (node:events:378:20)
at HTTPParser.parserOnIncomingClient [as onIncoming] (node:_http_client:636:27)
at HTTPParser.parserOnHeadersComplete (node:_http_common:129:17)
at TLSSocket.socketOnData (node:_http_client:502:22)
at TLSSocket.emit (node:events:378:20)
at addChunk (node:internal/streams/readable:313:12)
at readableAddChunk (node:internal/streams/readable:288:9)
Thanks in advance for any help!
Updated code here:
const fetch = require("node-fetch");
const main = async () => {
const json = await fetch("https://www.reddit.com/r/cute/random.json").then(
res => res.json()
);
console.log(
json
.map(entry => entry.data.children.map(child => child.data.url))
.flat()
.filter(Boolean)
);
};
main();
I am iterating it through the data and getting the output of the listing, I guess only one URL gets populated of k3 kind. So you get this as an output here:
Run #1
[ 'https://i.redd.it/pjom447yp8271.jpg' ]
Run #2
[ 'https://i.redd.it/h9b00p6y4g271.jpg' ]
Run #3
[ 'https://v.redd.it/lcejh8z6zp271' ]
Previous Answer for your reference:
In simple way, you can use something like node-fetch:
const fetch = require("node-fetch");
const main = async () => {
const json = await fetch("https://www.reddit.com/r/cute/random.json").then(
res => res.json()
);
console.log(json);
};
main();
You'll get the contents in the console.log(). When I run it with Node JS, I get the output so.js:
$ node so
[
{
kind: 'Listing',
data: {
modhash: '',
dist: 1,
children: [Array],
after: null,
before: null
}
},
{
kind: 'Listing',
data: {
modhash: '',
dist: null,
children: [Array],
after: null,
before: null
}
}
]

Python: requests doesn't get the whole content of a URL

Here is the URL that I am looking at:
url = https://i.instagram.com/api/v1/users/8538441802/info/
If I copy this url on the navigation bar of a web-browser I see this content:
{"user": {"pk": 8538441802, "username": "bobby_ww4", "full_name": "\ud83c\udf78 B O B B Y \ud83c\udf78", "is_private": false, "profile_pic_url": "https://scontent-sjc3-1.cdninstagram.com/vp/8a743eb7285d9cec268248e7fe6b018e/5D0470C8/t51.2885-19/s150x150/50103965_250281542552654_8842589758333911040_n.jpg?_nc_ht=scontent-sjc3-1.cdninstagram.com", "profile_pic_id": "1963771869542832625_8538441802", "is_verified": false, "has_anonymous_profile_picture": false, "media_count": 42, "follower_count": 2132, "following_count": 2881, "following_tag_count": 0, "biography": "Cake murder 9may\nLUNATIC \ud83d\udc40\nFashionholic \ud83d\udc54\n Attrangi \nUncontrolled rage \ud83d\ude44\nKDM LOVER \u2620\nHold the sea in my embrance", "external_url": "", "total_igtv_videos": 0, "total_ar_effects": 0, "reel_auto_archive": "on", "usertags_count": 44, "is_favorite": false, "is_interest_account": false, "hd_profile_pic_versions": [{"width": 320, "height": 320, "url": "https://scontent-sjc3-1.cdninstagram.com/vp/e6dc6596c0fed678fe6e520e020a1cbc/5D1C6238/t51.2885-19/s320x320/50103965_250281542552654_8842589758333911040_n.jpg?_nc_ht=scontent-sjc3-1.cdninstagram.com"}, {"width": 640, "height": 640, "url": "https://scontent-sjc3-1.cdninstagram.com/vp/4dd3319b1972445ce27eed7c827afbc4/5D033F57/t51.2885-19/s640x640/50103965_250281542552654_8842589758333911040_n.jpg?_nc_ht=scontent-sjc3-1.cdninstagram.com"}], "hd_profile_pic_url_info": {"url": "https://scontent-sjc3-1.cdninstagram.com/vp/30ff98f96900aee2a5604b7d833e0e85/5D130A32/t51.2885-19/50103965_250281542552654_8842589758333911040_n.jpg?_nc_ht=scontent-sjc3-1.cdninstagram.com", "width": 1080, "height": 1080}, "mutual_followers_count": 0, "has_highlight_reels": true, "can_be_reported_as_fraud": false, "direct_messaging": "UNKNOWN", "fb_page_call_to_action_id": "", "address_street": "", "business_contact_method": "CALL", "category": "Fashion Model", "city_id": 106313309406070, "city_name": "Ludhiana, Punjab, India", "contact_phone_number": "+919914934996", "is_call_to_action_enabled": false, "latitude": 30.9, "longitude": 75.85, "public_email": "bobbyvaid1137#gmail.com", "public_phone_country_code": "91", "public_phone_number": "9914934996", "zip": "", "instagram_location_id": "", "is_business": true, "account_type": 2, "can_hide_category": false, "can_hide_public_contacts": false, "should_show_category": true, "should_show_public_contacts": true, "include_direct_blacklist_status": true, "is_potential_business": false, "is_bestie": false, "has_unseen_besties_media": false, "show_account_transparency_details": false, "auto_expand_chaining": false, "highlight_reshare_disabled": false}, "status": "ok"}
NOTE: you must be logged in Instagram to see the above content.
Here is the line that I use requests to read this page:
page = requests.get(url, headers={"User-Agent": "Mozilla"})
If I look at the page.text this is what I see:
{"user": {"pk": 8538441802, "username": "bobby_ww4", "full_name": "\ud83c\udf78 B O B B Y \ud83c\udf78", "is_private": false, "profile_pic_url": "https://scontent-sjc3-1.cdninstagram.com/vp/8a743eb7285d9cec268248e7fe6b018e/5D0470C8/t51.2885-19/s150x150/50103965_250281542552654_8842589758333911040_n.jpg?_nc_ht=scontent-sjc3-1.cdninstagram.com", "profile_pic_id": "1963771869542832625_8538441802", "is_verified": false, "has_anonymous_profile_picture": false, "media_count": 42, "follower_count": 2132, "following_count": 2881, "following_tag_count": 0, "biography": "Cake murder 9may\nLUNATIC \ud83d\udc40\nFashionholic \ud83d\udc54\n Attrangi \nUncontrolled rage \ud83d\ude44\nKDM LOVER \u2620\nHold the sea in my embrance", "external_url": "", "total_igtv_videos": 0, "total_ar_effects": 0, "reel_auto_archive": "on", "usertags_count": 44, "is_interest_account": false, "hd_profile_pic_versions": [{"width": 320, "height": 320, "url": "https://scontent-sjc3-1.cdninstagram.com/vp/e6dc6596c0fed678fe6e520e020a1cbc/5D1C6238/t51.2885-19/s320x320/50103965_250281542552654_8842589758333911040_n.jpg?_nc_ht=scontent-sjc3-1.cdninstagram.com"}, {"width": 640, "height": 640, "url": "https://scontent-sjc3-1.cdninstagram.com/vp/4dd3319b1972445ce27eed7c827afbc4/5D033F57/t51.2885-19/s640x640/50103965_250281542552654_8842589758333911040_n.jpg?_nc_ht=scontent-sjc3-1.cdninstagram.com"}], "hd_profile_pic_url_info": {"url": "https://scontent-sjc3-1.cdninstagram.com/vp/30ff98f96900aee2a5604b7d833e0e85/5D130A32/t51.2885-19/50103965_250281542552654_8842589758333911040_n.jpg?_nc_ht=scontent-sjc3-1.cdninstagram.com", "width": 1080, "height": 1080}, "has_highlight_reels": true, "can_be_reported_as_fraud": false, "is_potential_business": false, "auto_expand_chaining": false, "highlight_reshare_disabled": false}, "status": "ok"}
As it can be seen on the web-browser we can see some information, like contact_phone_number that cannot be seen in the page.txt.
Why is that and how can I use requests or any othr Python functions to read exactly what I can see on a web-browser?

character width calculation wrong with some font which can make auto indent

i create a normal textbox and type some "i"s inside,the font i use is Lobster1.3,as you can see,i just selection one character,but the result is not correctly
and this is the last character position while in selection.
it looks that some font like Lobster1.3 which can make auto indent can make some character width calculation wrong
You have to ensure the font is properly loaded on the canvas before creating a fabricObject that uses it, if not fabricjs creates a cache of characters width that you have to manually delete to get the good one.
var jsondata = {
"objects": [{
"type": "textbox",
"originX": "left",
"originY": "top",
"left": 50,
"top": 50,
"fill": "rgb(0,0,0)",
"stroke": null,
"strokeWidth": 0,
"strokeDashArray": null,
"strokeLineCap": "butt",
"strokeLineJoin": "miter",
"strokeMiterLimit": 10,
"scaleX": 1.7870722433460076,
"scaleY": 1.7870722433460076,
"angle": 0,
"flipX": false,
"flipY": false,
"opacity": 1,
"shadow": null,
"visible": true,
"clipTo": null,
"backgroundColor": "",
"fillRule": "nonzero",
"globalCompositeOperation": "source-over",
"transformMatrix": null,
"skewX": 0,
"skewY": 0,
"stretchMode": "any",
"lockScalingX": false,
"lockUniScaling": false,
"lockScalingY": true,
"text": "iiiiiiiii",
"fontSize": "42",
"fontWeight": "normal",
"fontFamily": "Lobster",
"fontStyle": "",
"textDecoration": "",
"textAlign": "left",
"letterSpacing": 20,
"lineHeight": 1.16,
"textBackgroundColor": "",
"charSpacing": 20,
"styles": {
"0": {
"0": {
"fill": "#000",
"stroke": "#000",
"fontFamily": "Lobster"
},
"1": {
"fill": "#000",
"stroke": "#000",
"fontFamily": "Lobster"
},
"2": {
"fill": "#000",
"stroke": "#000",
"fontFamily": "Lobster"
},
"3": {
"fill": "#000",
"stroke": "#000",
"fontFamily": "Lobster"
},
"4": {
"fill": "#000",
"stroke": "#000",
"fontFamily": "Lobster"
},
"5": {
"fill": "#000",
"stroke": "#000",
"fontFamily": "Lobster"
},
"6": {
"fill": "#000",
"stroke": "#000",
"fontFamily": "Lobster"
},
"7": {
"fill": "#000",
"stroke": "#000",
"fontFamily": "Lobster"
},
"8": {
"fill": "#000",
"stroke": "#000",
"fontFamily": "Lobster"
}
}
},
"minWidth": 20,
"lastCachedStyleObject": {
"fill": "#000",
"stroke": "#000",
"fontFamily": "Lobster"
}
}],
"backgroundData": "#ffffff",
"width": 1023,
"height": 637
}
var canvas = new fabric.Canvas("myCanvas");
canvas.controlsAboveOverlay = true;
canvas.backgroundColor = '#FFFFFF';
WebFont.load({
google: {
families: ['Lobster']
},
active: function() {
canvas.loadFromJSON(jsondata, canvas.renderAll.bind(canvas));
}
});
<script src="https://rawgit.com/kangax/fabric.js/master/dist/fabric.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/webfont/1.6.16/webfont.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<canvas id='myCanvas' width='800' height='600'></canvas>
Fabric has a method that clears the font cache to ensure you don't get the wrong measurements for your bounding box when loading in and applying fonts to textbox objects.
clearFabricFontCache(fontFamilyopt)
From their documentation
http://fabricjs.com/docs/fabric.util.html
Clear char widths cache for the given font family or all the cache if no fontFamily is specified. Use it if you know you are loading fonts in a lazy way and you are not waiting for custom fonts to load properly when adding text objects to the canvas. If a text object is added when its own font is not loaded yet, you will get wrong measurement and so wrong bounding boxes. After the font cache is cleared, either change the textObject text content or call initDimensions() to trigger a recalculation
So in this case you could write:
canvas.loadFromJSON(jsonData, () => {
//clear character cache to ensure bounding boxes for fonts are correct
fabric.util.clearFabricFontCache();
canvas.renderAll()
});

Crosshair-x won't display on line chart

I am having an issue with a line chart on my site. Everything works fine about it except no matter what I try, I cannot get the crosshair-x value/scale to show up. http://gyazo.com/42a34d0fed9c2912bf7ed40eb0c55144 Both are set to "visible": true. My JSON code is as follows:
var myChart = {
"type": "line",
"background-color": "transparent",
"utc": true,
"title": {
"y": "0px",
"text": '#myClasses.STARTDATETIME.ToString("MM/d/yyyy (h:mm tt)")',
"background-color": "transparent",
"font-size": "16px",
"font-color": "#666",
"font-weight": "bold",
"letter-spacing": "0.1225em",
"height": "25px"
},
"plotarea": {
"margin":"10% 8% 14% 12%",
"background-color":"#666"
},
"legend": {
"visible": false,
},
"scale-x": {
"min-value": myEpoch,
"shadow": 0,
"step": #ViewBag.TotalTime,
"line-color": "#fff",
"tick": {
"line-color": "#f6f7f8"
},
"guide": {
"line-color": "#f6f7f8",
"visible": true
},
"item": {
"font-color": "#666"
},
"transform": {
"type": "date",
"all": "%D,%d %M<br />%h:%i %A",
"item": {
"visible": false
}
},
"label": {
"visible": false,
"font-color": "#666"
},
"minor-ticks": 0
},
"scale-y": {
"values": "25:200:25",
"line-color": "#fff",
"shadow": 0,
"tick": {
"line-color": "#f6f7f8"
},
"guide": {
"visible": false
},
"item": {
"font-color": "#666"
},
"label": {
"text": "Heart Rate (BPM)",
"font-color": "#666"
},
"minor-ticks": 0,
"thousands-separator": ",",
"markers": [
{
"type": "area",
"range": [25, 60],
"backgroundColor": "#585857",
"alpha": 1
},
{
"type": "area",
"range": [60, 95],
"backgroundColor": "#6FCBDC",
"alpha": 1
},
{
"type": "area",
"range": [95, 130],
"backgroundColor": "#8BC540",
"alpha": 1
},
{
"type": "area",
"range": [130, 165],
"backgroundColor": "#F38220",
"alpha": 1
},
{
"type": "area",
"range": [165, 200],
"backgroundColor": "#EB2026",
"alpha": 1
}
]
},
"tooltip": {
"font-color": "#666",
"visible": false
},
"chart": {
"marginRight": 30,
"marginLeft": 70
},
"plot": {
"tooltip-text": "%t bpm: %v",
"shadow": 0,
"line-width": "3px",
"marker": {
"type": "circle",
"size": 2
},
"hover-marker": {
"type": "circle",
"size": 4,
"border-width": "1px"
}
},
"series": [
{
"values": [88,96,93,88,88,86,89,120,144,153,156,132,113,145,138,152,135,155,164,165,147,143,152,140,153,138,116,125,131,132,134,124,111,136,167,171,165,168,139,129,138,130,140,141],
"text": "",
"line-color": "#ffffff",
"marker": {
"background-color": "#ffffff",
"border-width": 1,
"shadow": 0,
"border-color": "#ffffff",
"visible": true
},
"palette": 0
}
],
"crosshair-x": {
"line-color": "#f6f7f8",
"value-label": {
"border-radius": "5px",
"border-width": "1px",
"border-color": "#f6f7f8",
"padding": "0px 10px 0px 5px",
"font-weight": "bold",
"font-color": "#fff",
"background-color": "#666",
"visible": true
},
"scale-label": {
"font-color": "#fff",
"background-color": "#666",
"border-radius": "5px",
"border-width": "1px",
"border-color": "#f6f7f8",
"padding": "0px 10px 0px 5px",
"visible": true
}
}
};
Is there anything obvious that I'm missing that may be overruling those being set to visible?
Thanks in advance for your help!
Which version of ZingChart are you using? Does this occur in all browsers? Are you getting any console errors? I've taken your code and put it into our demo tool, and the crosshair seems to work. Take a look here.
You can try adding the following to the <head> element of your application:
<style title="zingchart"></style>
This forces ZingChart to inject its CSS into that element, preventing certain types of conflicts that can occur from time to time, but I'm not 100% sure that this is the issue.
I'm on the ZingChart support team, so I'd love to help, but I can't reproduce the issue on my end.

Adding options in "group" type object in fabricjs canvas

I am trying to load object (group of objects) in canvas, there is no problem with that. But if I want to add some options to loaded object such as scaleX, scaleY, lockScalingX etc. with set method I get an error "Uncaught TypeError: Object Group has no method 'set'". I cannot understand why, I have tried several ways. My code is below -
var json = {
"objects": [{
"type": "group",
"originX": "center",
"originY": "center",
"left": 268,
"top": 203,
"width": 428,
"height": 274,
"fill": "rgb(0,0,0)",
"overlayFill": null,
"stroke": null,
"strokeWidth": 1,
"strokeDashArray": null,
"scaleX": 1,
"scaleY": 1,
"angle": 0,
"flipX": false,
"flipY": false,
"opacity": 1,
"selectable": true,
"hasControls": true,
"hasBorders": true,
"hasRotatingPoint": true,
"transparentCorners": true,
"perPixelTargetFind": false,
"shadow": null,
"visible": true,
"objects": [{
"type": "rect",
"originX": "center",
"originY": "center",
"left": 11,
"top": 37,
"width": 200,
"height": 200,
"fill": "rgba(179,179,179,0.5)",
"overlayFill": null,
"stroke": "#FF0000",
"strokeWidth": 0.1,
"strokeDashArray": null,
"scaleX": 1,
"scaleY": 1,
"angle": 0,
"flipX": false,
"flipY": false,
"opacity": 1,
"selectable": true,
"hasControls": false,
"hasBorders": true,
"hasRotatingPoint": true,
"transparentCorners": true,
"perPixelTargetFind": false,
"shadow": null,
"visible": true,
"rx": 0,
"ry": 0
}, {
"type": "triangle",
"originX": "center",
"originY": "center",
"left": 114,
"top": -37,
"width": 200,
"height": 200,
"fill": "rgba(179,179,179,0.5)",
"overlayFill": null,
"stroke": "#FF0000",
"strokeWidth": 0.1,
"strokeDashArray": null,
"scaleX": 1,
"scaleY": 1,
"angle": 0,
"flipX": false,
"flipY": false,
"opacity": 1,
"selectable": true,
"hasControls": false,
"hasBorders": true,
"hasRotatingPoint": true,
"transparentCorners": true,
"perPixelTargetFind": false,
"shadow": null,
"visible": true
}, {
"type": "circle",
"originX": "center",
"originY": "center",
"left": -114,
"top": 29,
"width": 200,
"height": 200,
"fill": "rgba(179,179,179,0.5)",
"overlayFill": null,
"stroke": "#FF0000",
"strokeWidth": 0.1,
"strokeDashArray": null,
"scaleX": 1,
"scaleY": 1,
"angle": 0,
"flipX": false,
"flipY": false,
"opacity": 1,
"selectable": true,
"hasControls": false,
"hasBorders": true,
"hasRotatingPoint": true,
"transparentCorners": true,
"perPixelTarge,,tFind": false,
"shadow": null,
"visible": true,
"radius": 100
}]
}],
"background": ""
},
objects = json.objects,
canvas = new fabric.Canvas('canvas');
for (var i = 0; i < objects.length; i++) {
var type = fabric.util.string.camelize(fabric.util.string.capitalize(objects[i].type));
type.set({
scaleX: 1.2,
scaleY: 1.2,
lockScalingX: true,
lockScalingY: true
});
type.setCoords();
if (fabric[type].async) {
fabric[type].fromObject(objects[i], function (img) {
canvas.add(img);
});
} else {
canvas.add(fabric[type].fromObject(objects[i]));
}
}
Anyone can help me please?
This exception happens cause the var "type" gets string value which is "Group"
var type = fabric.util.string.camelize(fabric.util.string.capitalize(objects[i].type));
so there is no "set" method in "Group" string as you used:
.set({
scaleX: 1.2,
scaleY: 1.2,})//this is wrong
you can use this :
objects[i].scaleX = 1.2;
objects[i].scaleY = 1.2;
objects[i].lockScalingX = 1.2;
objects[i].lockScalingY = 1.2;
and here the JSfiddle

Resources