Fabric.js canvas not catching mouse events on Google Chrome - google-chrome

Googled this a lot and didn't get any useful hint/solution.
I have this simple html page including some CSS styles, jQuery, jQuery-ui and obviously Fabric.js; on document.ready I launch an ajax call and render something on the canvas. Until now everything seems fine but when a I need to catch some mouse events I get nothing. This behaviour is shown only on Chrome (current version 25.0.1364.97); everything works fine on Firefox or Internet Explorer (v. 9).
Here's some of the js code:
$(document).ready(function() {
//setup canvas etc.
eCanvas = new fabric.Canvas('EViewport', {
backgroundColor: 'rgba(255, 50, 50, .3)',
selection: true,
selectionColor: 'blue',
selectionLineWidth: 2
});
EViewport = $("#CanvasContainer");
viewW = EViewport.width();
viewH = EViewport.height();
eCanvas.setWidth(viewW);
eCanvas.setHeight(viewH);
eCanvas.observe('object:selected', function(options) {
if (options.target) {
console.log('an object was selected! ', options.target.type);
}
});
eCanvas.observe('mouse:down', function() {
console.log('mouse click! ');
});
eCanvas.on('mouse:down', function() {
console.log('mouse click! ');
});
eCanvas.on('mousedown', function() {
console.log('mouse click! ');
});
//... render some rectangles and stuff...
});
And here's the html structure (notice that Eviewport.js file contains previously pasted code):
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="baseCss/jquery-ui.css" type="text/css">
<script type="text/javascript" src="baseJs/jquery.js"></script>
<script type="text/javascript" src="baseJs/jquery-ui.js"></script>
<script type="text/javascript" src="Eviewport.js"></script>
<link type="text/css" rel="stylesheet" href="Eviewport.css">
<script type="text/javascript" src="baseJs/Fabric.js"></script>
</head>
<body>
<div id="MainContainer">
<div id="CanvasContainer">
<canvas id="EViewport">
Canvas is not supported
</canvas>
</div>
</div>
</body>
</html>
Selection features don't work with chrome either while they work on IE and Firefox.
I tried many things (as you can see I tried changing canvas.observe with canvas.on), changed jQuery and jQueryui versions but nothing changed.
Using developer tools on Google Chrome doesn't show much.
There's no z-index on html elements given by CSS, and I tried disabling different js and CSS but that didn't solve the problem.
I noticed that the problem shows also shows on the demo page of Fabric.js (just tried http://fabricjs.com/stickman/); render works, effects also but no mouse events or selection working.
Is this a bug?

Ok, finally found what's not working.
I have a Wacom device attached and looks like latest Chrome version sets a flag about "touch enabled device" and that's breaking my code.
A simple solution can be changing chrome flags (chrome://flags/)
Related posts:
https://github.com/kangax/fabric.js/issues/450

Related

htm5 audio is not working on safari when I use jquery's timeout

I can play a song right after 5 seconds in my chrome browser but it doesn't work in safari. when I click on button text directly, it plays fine in safari too.
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
function playAudio(){
var a=new Audio("on.mp3");
a.load();
a.play();
}
$(document).ready(function(){
setTimeout(function() {
playAudio();
}, 5000);
});
</script>
</head>
<body>
Audio will start playing after 5 second
<p id="playButton" onclick="playAudio()">button</p>
</body>
</html>
That's normal because of Safari auto-play policy that require a user gesture to play media : https://webkit.org/blog/7734/auto-play-policy-changes-for-macos

Checking the internet connection and reading the files on/off line [duplicate]

I am linking to the jQuery Mobile stylesheet on a CDN and would like to fall back to my local version of the stylesheet if the CDN fails. For scripts the solution is well known:
<!-- Load jQuery and jQuery mobile with fall back to local server -->
<script src="http://code.jquery.com/jquery-1.6.3.min.js"></script>
<script type="text/javascript">
if (typeof jQuery == 'undefined') {
document.write(unescape("%3Cscript src='jquery-1.6.3.min.js'%3E"));
}
</script>
I would like to do something similar for a style sheet:
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.0b3/jquery.mobile-1.0b3.min.css" />
I am not sure if a similar approach can be achieved because I am not sure whether the browser blocks in the same way when linking a script as it does when loading a script (maybe it is possible to load a stylesheet in a script tag and then inject it into the page) ?
So my question is: How do I ensure a stylesheet is loaded locally if a CDN fails ?
One could use onerror for that:
<link rel="stylesheet" href="cdn.css" onerror="this.onerror=null;this.href='local.css';" />
The this.onerror=null; is to avoid endless loops in case the fallback it self is not available. But it could also be used to have multiple fallbacks.
However, this currently only works in Firefox and Chrome.
Update: Meanwhile, this seems to be supported by all common browsers.
Not cross-browser tested but I think this will work. Will have to be after you load jquery though, or you'll have to rewrite it in plain Javascript.
<script type="text/javascript">
$.each(document.styleSheets, function(i,sheet){
if(sheet.href=='http://code.jquery.com/mobile/1.0b3/jquery.mobile-1.0b3.min.css') {
var rules = sheet.rules ? sheet.rules : sheet.cssRules;
if (rules.length == 0) {
$('<link rel="stylesheet" type="text/css" href="path/to/local/jquery.mobile-1.0b3.min.css" />').appendTo('head');
}
}
})
</script>
Assuming you are using the same CDN for css and jQuery, why not just do one test and catch it all??
<link href="//ajax.googleapis.com/ajax/libs/jqueryui/1/themes/start/jquery-ui.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jqueryui/1/jquery-ui.min.js"></script>
<script type="text/javascript">
if (typeof jQuery == 'undefined') {
document.write(unescape('%3Clink rel="stylesheet" type="text/css" href="../../Content/jquery-ui-1.8.16.custom.css" /%3E'));
document.write(unescape('%3Cscript type="text/javascript" src="/jQuery/jquery-1.6.4.min.js" %3E%3C/script%3E'));
document.write(unescape('%3Cscript type="text/javascript" src="/jQuery/jquery-ui-1.8.16.custom.min.js" %3E%3C/script%3E'));
}
</script>
I guess the question is to detect whether a stylesheet is loaded or not. One possible approach is as follows:
1) Add a special rule to the end of your CSS file, like:
#foo { display: none !important; }
2) Add the corresponding div in your HTML:
<div id="foo"></div>
3) On document ready, check whether #foo is visible or not. If the stylesheet was loaded, it will not be visible.
Demo here -- loads jquery-ui smoothness theme; no rule is added to stylesheet.
this article suggests some solutions for the bootstrap css
http://eddmann.com/posts/providing-local-js-and-css-resources-for-cdn-fallbacks/
alternatively this works for fontawesome
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet">
<script>
(function($){
var $span = $('<span class="fa" style="display:none"></span>').appendTo('body');
if ($span.css('fontFamily') !== 'FontAwesome' ) {
// Fallback Link
$('head').append('<link href="/css/font-awesome.min.css" rel="stylesheet">');
}
$span.remove();
})(jQuery);
</script>
You might be able to test for the existence of the stylesheet in document.styleSheets.
var rules = [];
if (document.styleSheets[1].cssRules)
rules = document.styleSheets[i].cssRules
else if (document.styleSheets[i].rules)
rule= document.styleSheets[i].rules
Test for something specific to the CSS file you're using.
Here's an extension to katy lavallee's answer. I've wrapped everything in self-executing function syntax to prevent variable collisions. I've also made the script non-specific to a single link. I.E., now any stylesheet link with a "data-fallback" url attribute will automatically be parsed. You don't have to hard-code the urls into this script like before. Note that this should be run at the end of the <head> element rather than at the end of the <body> element, otherwise it could cause FOUC.
http://jsfiddle.net/skibulk/jnfgyrLt/
<link rel="stylesheet" type="text/css" href="broken-link.css" data-fallback="broken-link2.css">
.
(function($){
var links = {};
$( "link[data-fallback]" ).each( function( index, link ) {
links[link.href] = link;
});
$.each( document.styleSheets, function(index, sheet) {
if(links[sheet.href]) {
var rules = sheet.rules ? sheet.rules : sheet.cssRules;
if (rules.length == 0) {
link = $(links[sheet.href]);
link.attr( 'href', link.attr("data-fallback") );
}
}
});
})(jQuery);
Do you really want to go down this javascript route to load CSS in case a CDN fails?
I haven't thought all the performance implications through but you're going to lose control of when the CSS is loaded and in general for page load performance, CSS is the first thing you want to download after the HTML.
Why not handle this at the infrastructure level - map your own domain name to the CDN, give it a short TTL, monitor the files on the CDN (e.g. using Watchmouse or something else), if CDN fails, change the DNS to backup site.
Other options that might help are "cache forever" on static content but there's no guarantee the browser will keep them of course or using the app-cache.
In reality as someone said at the top, if your CDN is unreliable get a new one
Andy
Look at these functions:
$.ajax({
url:'CSS URL HERE',
type:'HEAD',
error: function()
{
AddLocalCss();
},
success: function()
{
//file exists
}
});
And here is vanilla JavaScript version:
function UrlExists(url)
{
var http = new XMLHttpRequest();
http.open('HEAD', url, false);
http.send();
return http.status!=404;
}
if (!UrlExists('CSS URL HERE') {
AddLocalCss();
}
Now the actual function:
function AddLocalCss(){
document.write('<link rel="stylesheet" type="text/css" href=" LOCAL CSS URL HERE">')
}
Just make sure AddLocalCss is called in the head.
You might also consider using one of the following ways explained in this answer:
Load using AJAX
$.get(myStylesLocation, function(css)
{
$('<style type="text/css"></style>')
.html(css)
.appendTo("head");
});
Load using dynamically-created
$('<link rel="stylesheet" type="text/css" href="'+myStylesLocation+'" >')
.appendTo("head");
Load using dynamically-created <style>
$('<style type="text/css"></style>')
.html('#import url("' + myStylesLocation + '")')
.appendTo("head");
or
$('<style type="text/css">#import url("' + myStylesLocation + '")</style>')
.appendTo("head");
I'd probably use something like yepnope.js
yepnope([{
load: 'http:/­/ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js',
complete: function () {
if (!window.jQuery) {
yepnope('local/jquery.min.js');
}
}
}]);
Taken from the readme.
//(load your cdn lib here first)
<script>window.jQuery || document.write("<script src='//me.com/path/jquery-1.x.min.js'>\x3C/script>")</script>

CSS - How to autonavigate to a color on the page when page loads

I have a page that I work on daily and I need to look through the page for text that has HTML of:
<tr style="background-color:#33FF00">
How can I use CSS to auto navigate to that color or HTML code when the page loads?
Is there a way?
I cannot edit the html as it's not hosted locally and I don't have access to write access, only read.
I am currently using Stylebot to modify the css for my own display purposes and want to know if I can do the same to auto navigate to that colored section.
If there is a way similar to using style bot but for HTML like userscripts etc, I am not familiar enough so if you have a workaround any tutorial would be great to show me how to implement it.
Thanks!
UPDATED
Copy and paste the code below into a text file and save it as an html file. Then open it in a browser.
This code loads the target page from the host into the 'result' element, then uses some post-load javascript to navigate to the colored tr elements. If the page requires scripts on external stylesheets, etc., these need to be loaded explicitly.
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script>
$.ajaxPrefilter( function (options) {
if (options.crossDomain && jQuery.support.cors) {
var http = (window.location.protocol === 'http:' ? 'http:' : 'https:');
options.url = http + '//cors-anywhere.herokuapp.com/' + options.url;
//options.url = "http://cors.corsproxy.io/url=" + options.url;
}
});
$(document).ready(function(){
var sourceUrl='https://en.wikipedia.org/wiki/Main_Page';
var sourceScript='https://en.wikipedia.org/wiki/Main_Page';
$( "#result" ).load(sourceUrl, function() {
$.getScript(sourceScript, function(){
alert("Script loaded and executed.");
});
$('html, body').animate({
scrollTop: $('tr').filter(function(){
var color = $(this).css("background-color").toLowerCase() || $(this).css("background").toLowerCase() ;
return color === "#33ff00";
}).position().top
}, 100);
});
});
</script>
</head>
<body>
<div id="result"></div>
</body>
</html>
from jQuery scroll to element
and JQuery Find Elements By Background-Color
UPDATE 2
Or, in an iFrame (but only works if you are on the same domain as the target page)
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script>
function onLoadHandler(){
var $iframe = $("#result").contents();
var trs=$iframe.find('tr');
$iframe.find('html,body').animate({
scrollTop: trs.filter(function(){
var color = $(this).css("background-color").toLowerCase() || $(this).css("background").toLowerCase() ;
return color === "#33ff00";
}).position().top
}, 100);
};
</script>
</head>
<body>
<iframe id="result" src="FRAMESOURCE" style="top:0;left:0;width:100%;height:700px" onload="onLoadHandler();"> </iframe>
</body>
</html>
UPDATE 3
If none of these work, try: 1) load your page in a browser, 2) open Developer Tools, 3) go to the Page Inspector or Elements tab, 3) Ctrl-F and search for your color string ('#ddcef2'), 4) right-click the first highlighted element in your search results and select "Scroll into view"
Try and see if that does the trick:
* {
display: none
}
[style*=background-color:#33FF00] {
display: table-row
}

CreateJs Canvas's shape losses its co-ordinates on Windows Phone

am making a Createjs and html5 project in which I am drawing a shape(Red circle), when I click over the circle it gives alert. It works fine on all desktops and android phones. Except when I open this in a windows phone it works fine on the normal screen but when I zoom the screen it loses it working, an alert is shown when I click anywhere on the screen(maybe where the co-ordinates of the shape resides) but not when I click over the shape(Circle),,
Your help is appreciated
my demo.html
<!DOCTYPE html>
<html>
<head><title></title>
<script type="text/javascript" src="createjs-2013.12.12.min.js"></script>
<script type="text/javascript" src="jquery-1.11.0.min.js"></script>
<script type="text/javascript">
function init() {
var stage = new createjs.Stage("demoCanvas");
var circle = new createjs.Shape();
createjs.Touch.enable(stage);
circle.graphics.beginFill("red").drawCircle(0, 0, 50);
circle.x = 100;
circle.y = 100;
circle.addEventListener("click", function(evt) { /*$("span#log").text(circle.x);*/ alert('clicked'); });
stage.addChild(circle);
stage.update();
}
</script>
</head>
<body onLoad="init();">
<span id="log"></span>
<br>
<canvas id="demoCanvas" width="500" height="300">
alternate content
</canvas>
</body>
</html>..
Here's the project
Not sure if this is relevant as haven't looked at sample code, but I think createjs.Touch.enable works on Stage instances rather than DisplayObjects
See here
I do alot of Research over this topic, and at the end i came to this point that this the
BUG in IE11 . Hope Microsoft helps to solve this.

Javascript KineticJS Firefox Issue

Im trying to do a composite operation on layers using KineticJS.
Everything works fine in Chrome, but nothing shows for firefox, or IE10
The code runs through without any errors.
You can see the issue here:
http://clients.lilodesign.com/Lilo/Kinetic/
Chrome you should see a circle with a partial bit of the standard MS Blue Trees image showing through. In Firefox and IE10 you just get a blank screen.
You can view the code by viewing the source. Its all in-line and a very simple example to show the issue.
If you remove the following line:
ctx.globalCompositeOperation = "destination-atop";
Then you see the blue trees image with the ellipse on top of it as expected in all three browsers, so the code does "work".
Has anyone else experienced this and found a workaround?
I have searched and tried a couple of suggested solutions such as:
shape intersection with KineticJS
But all these still only seem to work in Chrome.
Any help or pointers would be appreciated.
Thanks
Tyrone.
We used to be able to cheat by grabbing the context of a layer, but now it’s unreliable (as you’ve discovered).
You can still get verrrrry hacky and do it like this: : http://jsfiddle.net/m1erickson/6fTQU/
But don’t ! (Even this hack doesn’t actually work on images with transparent pixels).
Instead, do it the official way by creating a Kinetic custom Shape Object.
Kinetic Shape gives you an official canvas and context to work with.
As a result, the globalCompositeOperation works fine (reliably!).
Here is code and a Fiddle: http://jsfiddle.net/m1erickson/LtxEe/
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Prototype</title>
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.5.1.min.js"></script>
<style>
body{ background-color: ivory; }
#container{
border:solid 1px #ccc;
margin-top: 10px;
width:300px;
height:300px;
}
</style>
<script>
$(function(){
var stage = new Kinetic.Stage({
container: 'container',
width: 300,
height: 300
});
var layer = new Kinetic.Layer();
stage.add(layer);
var img=new Image();
img.onload=function(){
buildLayer(img);
}
img.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/KoolAidMan.png";
function buildLayer(img){
var myShape=new Kinetic.Shape({
drawFunc:function(canvas){
var ctx=canvas.getContext();
ctx.beginPath();
ctx.drawImage(img,0,0);
ctx.globalCompositeOperation="destination-atop";
ctx.arc(150,150,60,0,Math.PI*2,false);
ctx.closePath();
ctx.fill();
canvas.fillStroke(this);
},
x:0,
y:0,
width:img.width,
height:img.height
});
layer.add(myShape);
layer.draw();
}
}); // end $(function(){});
</script>
</head>
<body>
<div id="container"></div>
</body>
</html>