Using AnmiateCC html5 output with Haxe - haxe

Because FLASH is Dead I have a mission to convert some games to work as html5.
Graphics and animation is made on timeline in AnimateCC.
Until now the process looks like: publish to swc/swf, FlashDevelop -> AddToLibrary and I've access to all the objects.
When publish target is HTML5 canvas I have two files:
testHaxe.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>testHaxe</title>
<script src="https://code.createjs.com/createjs-2015.11.26.min.js"></script>
<script src="testHaxe.js"></script>
<script>
var canvas, stage, exportRoot;
function init() {
canvas = document.getElementById("canvas");
images = images||{};
var loader = new createjs.LoadQueue(false);
loader.addEventListener("fileload", handleFileLoad);
loader.addEventListener("complete", handleComplete);
loader.loadManifest(lib.properties.manifest);
}
function handleFileLoad(evt) {
if (evt.item.type == "image") { images[evt.item.id] = evt.result; }
}
function handleComplete(evt) {
exportRoot = new lib.testHaxe();
stage = new createjs.Stage(canvas);
stage.addChild(exportRoot);
stage.update();
createjs.Ticker.setFPS(lib.properties.fps);
createjs.Ticker.addEventListener("tick", stage);
}
</script>
</head>
<body onload="init();" style="background-color:#D4D4D4;margin:0px;">
<canvas id="canvas" width="550" height="400" style="background-color:#FFFFFF"></canvas>
</body>
</html>
testHaxe.js
(function (lib, img, cjs, ss) {
var p; // shortcut to reference prototypes
lib.webFontTxtFilters = {};
// library properties:
lib.properties = {
width: 550,
height: 400,
fps: 24,
color: "#FFFFFF",
webfonts: {},
manifest: [
{src:"images/Bitmap1.png", id:"Bitmap1"}
]
};
lib.webfontAvailable = function(family) {
lib.properties.webfonts[family] = true;
var txtFilters = lib.webFontTxtFilters && lib.webFontTxtFilters[family] || [];
for(var f = 0; f < txtFilters.length; ++f) {
txtFilters[f].updateCache();
}
};
// symbols:
(lib.Bitmap1 = function() {
this.initialize(img.Bitmap1);
}).prototype = p = new cjs.Bitmap();
p.nominalBounds = new cjs.Rectangle(0,0,103,133);
(lib.в1 = function(mode,startPosition,loop) {
this.initialize(mode,startPosition,loop,{});
// Warstwa 1
this.instance = new lib.Bitmap1();
this.instance.setTransform(-2,-2);
this.timeline.addTween(cjs.Tween.get(this.instance).wait(1));
}).prototype = p = new cjs.MovieClip();
p.nominalBounds = new cjs.Rectangle(-2,-2,103,133);
// stage content:
(lib.testHaxe = function(mode,startPosition,loop) {
this.initialize(mode,startPosition,loop,{});
// Layer 1
this.instance = new lib.в1();
this.instance.setTransform(85,90,1,1,0,0,0,49.5,64.5);
this.timeline.addTween(cjs.Tween.get(this.instance).wait(1));
}).prototype = p = new cjs.MovieClip();
p.nominalBounds = new cjs.Rectangle(308.5,223.5,103,133);
})(lib = lib||{}, images = images||{}, createjs = createjs||{}, ss = ss||{});
var lib, images, createjs, ss;
I'm looking for a way to connect thouse files into haxe and access files on Stage or from library ex: new a1();
There are externs for createJS in haxeLib but I don't know how to use them with this output.

You can write externs for your generated lib, eg.:
package lib;
import createjs.MovieClip;
#:native("lib.B1")
extern class B1 extends MovieClip {
}
#:native("lib.testHaxe")
extern class TextHaxe extends MovieClip {
public var instance:B1;
}
Obviously that could be very tedious so I wrote a tool for it:
https://github.com/elsassph/createjs-def
And posted a complete example here: http://philippe.elsass.me/2013/05/type-annotations-for-the-createjs-toolkit/
However it's currently broken for recent versions of Animate CC because the JS output has changed - it needs to be fixed.

Related

xamarin.forms webview baseurl not working on device (iOS 10.1)

I have a xamarin.forms app that uses HybridWebView (https://developer.xamarin.com/guides/xamarin-forms/custom-renderer/hybridwebview/) to display an html document. I use baseUrl to load local css and js into the document. This code was working fine on iOS 9.x.
But, after I upgraded to iOS 10, the code works on the iOS simulator but not on the actual device. On the device, it does not load the css from local storage.
here is the test code I am using. It works on simulator but not on device.
async void Handle_TestButtonClicked (object sender, System.EventArgs e)
{
string css = #"
body {
background-color: powderblue;
}
h1 {
color: blue;
}
p {
color: red;
}
";
var folder = await AppGlobals.AppStorage.GetContentFolder ();
string filename = "styles.css";
await AppGlobals.AppStorage.WriteToFile (folder, filename, css);
string html = #"<!DOCTYPE html>
<html>
<head>
<link rel=""stylesheet"" href=""styles.css"">
</head>
<body>
<h1>This is a heading</h1>
<p>This is a paragraph.</p>
</body>
</html>";
this.DocumentView.Html = html;
}
In the HybridWebView, I am using the following code to set the baseUrl
if (Element.Html != null) {
string baseFolderPath = await AppStorage.GetInstance ().GetContentFolderPath ();
var baseUrl = new NSUrl (baseFolderPath, true);
Control.LoadHtmlString (Element.Html, baseUrl);
}
I am using PCLStorage library to read/write to local storage.
I think LoadHtmlString is broken for loading local css/js etc.
I worked around this problem by writing the HTML string to local file and then loading it using LoadFileUrl. This works as expected
if (!String.IsNullOrEmpty (Element.Uri)) {
string filePath = await GetFilePathInContentFolderFromUri (Element.Uri);
var fileUrl = new NSUrl (filePath, false);
Control.LoadFileUrl (fileUrl, fileUrl);
}
Another work-around could be to inject the required css/js into the html document itself and still use LoadHtmlString, this works.

per pixel image object detection in fabric js

I have been trying to get the per pixel drag and drop feature working using images with fabric.js like in example on their website: http://fabricjs.com/per-pixel-drag-drop/. I would like the object to be detected when a non transparent part is moused over but if I set perpixeltargetfind to true nothing is detected. I have tried for a while now and even copying the example verbatim while using my own images has not worked. Would really appreciate some help figuring out what I am doing wrong if anyone has experience using this. Thanks.
Here is a link to a js fiddle I have been using: http://jsfiddle.net/ahalbleib/bdofdbqg/
and the code:
var canvas =this.__canvas = new fabric.Canvas('c1',{hoverCursor: 'pointer',
selection: false});
var urls=['https://dl.dropboxusercontent.com/s/ix6mvv49wnx226a/Central-Richmon_clipped_rev_1.png?dl=0' ,
'https://dl.dropboxusercontent.com/s/jjp2l0kgdw8iitb/Laurel-Heights.png?dl=0',
'https://dl.dropboxusercontent.com/s/wdk02w40z1466g5/LoneMountain.png?dl=0',
'https://dl.dropboxusercontent.com/s/t6tnptndu2k22xr/OuterRichmond.png?dl=0',
'https://dl.dropboxusercontent.com/s/tv4rhwjc0nw35iz/Presidio-Heights.png?dl=0' ,
'https://dl.dropboxusercontent.com/s/ttbf390w2vdx4id/Inner-richmond.png?dl=0'];
for (var i=0; i<urls.length; i++){
fabric.Image.fromURL( urls[i], function(img){
img.perPixelTargetFind = true;
img.targetFindTolerance = 4;
img.hasControls = img.hasBorders = false;
canvas.add(img);
});
}
canvas.findTarget = (function (originalFn) {
return function () {
var target = originalFn.apply(this, arguments);
if (target) {
if (this._hoveredTarget !== target) {
canvas.fire('object:over', { target: target });
if (this._hoveredTarget) {
canvas.fire('object:out', { target: this._hoveredTarget });
}
this._hoveredTarget = target;
}
}
else if (this._hoveredTarget) {
canvas.fire('object:out', { target: this._hoveredTarget });
this._hoveredTarget = null;
}
return target;
};
})(canvas.findTarget);
};
init();
That is because you don't take images from your own server and you'll get a Security error about tainted canvas. You need to set crossOrigin: 'Anonymous' to images. I made you a jsFiddle

FabricJS double click on objects

I am trying to perform a special action whenever the user double clicks any object located inside the canvas. I have read the docs and not found any mouse:dblclick-like event in the documentation. I tried doing something like:
fabric.util.addListener(fabric.document, 'dblclick', callback);
Which does trigger the dblclick event but does not give specific information about the actual object that is being clicked on the canvas.
Any ideas of the most FabricJS-y way of doing this?
The more elegant way is to override fabric.Canvas._initEventListeners to add the dblclick support
_initEventListeners: function() {
var self = this;
self.callSuper('_initEventListeners');
addListener(self.upperCanvasEl, 'dblclick', self._onDoubleClick);
}
_onDoubleClick: function(e) {
var self = this;
var target = self.findTarget(e);
self.fire('mouse:dblclick', {
target: target,
e: e
});
if (target && !self.isDrawingMode) {
// To unify the behavior, the object's double click event does not fire on drawing mode.
target.fire('object:dblclick', {
e: e
});
}
}
I've also developed a library to implement more events missed in fabricjs : https://github.com/mazong1123/fabric.ext
This is similar to #LeoCreer's answer but actually gets access to the targeted object
fabric.util.addListener(canvas.upperCanvasEl, 'dblclick', function (e) {
var target = canvas.findTarget(e);
});
The Correct way to add custom events to Fabric.js
window.fabric.util.addListener(canvas.upperCanvasEl, 'dblclick', function (event, self) {
yourFunction(event);
});
or use fabric.ext
I'm using this workaround:
var timer = 0;
canvas.item(0).on('mouseup', function() {
var d = new Date();
timer = d.getTime();
});
canvas.item(0).on('mousedown', function() {
var d = new Date();
if ((d.getTime() - timer) < 300) {
console.log('double click')
}
});
Here is a quick and easy way to add a double click event handler to Fabric JS -
Include following code snippet to your html file. Just ensure this is loaded after the main fabric.js library
<script type="text/javascript">
fabric = (function(f) { var nativeOn = f.on; var dblClickSubscribers = []; var nativeCanvas = f.Canvas; f.Canvas = (function(domId, options) { var canvasDomElement = document.getElementById(domId); var c = new nativeCanvas(domId, options); c.dblclick = function(handler) { dblClickSubscribers.push(handler) }; canvasDomElement.nextSibling.ondblclick = function(ev){ for(var i = 0; i < dblClickSubscribers.length; i++) { console.log(ev); dblClickSubscribers[i]({ e :ev }); } }; return c; }); return f; }(fabric));
</script>
Then add this code to listen a double click event:
canvas.dblclick(function(e) {
});
To get information about the actual object that is being clicked on the canvas, use following method -
canvas.getActiveObject();
eg.
canvas.dblclick(function(e) {
activeObject = canvas.getActiveObject();
});
I am late but now fabricjs has mousedblclick event.
Listed at: http://fabricjs.com/docs/fabric.Object.html
See all events:
http://fabricjs.com/events

Using WebKit to work with the SVG DOM

I'm trying to access elements of an SVG file using WebKitGtk but I'm failing miserably. The program is in Vala, it's very simple and is just an attempt at getting data from a couple of elements:
using Gtk;
using WebKit;
public class WebKitTest : Window {
private WebView web_view;
private const string uri = "file:///tmp/test.svg";
public WebKitTest () {
set_default_size (800, 600);
web_view = new WebView ();
var scrolled_window = new ScrolledWindow (null, null);
scrolled_window.set_policy (PolicyType.AUTOMATIC, PolicyType.AUTOMATIC);
scrolled_window.add (this.web_view);
var vbox = new VBox (false, 0);
vbox.add (scrolled_window);
add (vbox);
this.destroy.connect (Gtk.main_quit);
show_all ();
this.web_view.load_uri (WebKitTest.uri);
var dom = web_view.get_dom_document ();
var el = dom.get_document_element ();
var child = el.first_element_child;
stdout.printf ("%s\n", child.tag_name);
var list = dom.get_elements_by_tag_name ("svg");
stdout.printf ("%lu\n", list.length);
assert (list == null);
var length = list.length;
assert (length == 0);
var svg = list.item (0);
var res = dom.evaluate ("//path", svg, null, 0, null);
DOMNode node;
while ((node = res.iterate_next ()) != null) {
stdout.printf ("%s\n", (node as DOMElement).tag_name);
}
}
public static void main (string[] args) {
Gtk.init (ref args);
var test = new WebKitTest ();
Gtk.main ();
return 0;
}
}
This compiles with valac --pkg webkitgtk-3.0 --pkg gtk+-3.0 webkittest.vala but if you've only got Gtk3 installed like I have you unfortunately need to do copy the webkit-1.0 .vapi and .deps files to new webkitgtk-3.0 ones and replace the occurrences of gdk-2.0 and gtk-2.0 in the .deps file to be gdk-3.0 and gtk-3.0 respectively.
I would think that using the DOM to access sub elements of an SVG would be simple, but as soon as this code gets to the print statement for child.tag_name it gives "HEAD" and nowhere in the file is that found. The file I'm loading should be pretty standard seeing as I used inkscape to make it.
Does WebKit do something funny that I'm not seeing to documents that it loads?
Thanks.
Update:
It definitely seems that WebKit loads everything into an HTML document because when I use GObject to retrieve the Type and print it for the node returned by get_elements_by_tag_name("body") I get WebKitDOMHTMLBodyElement. Be that as it may I tried to do the following XPath query on the DOMDocument
var nsres = dom.create_ns_resolver (body);
DOMXPathResult res = null;
try {
res = dom.evaluate ("//*", body, nsres, 0, null);
} catch (Error e) {
stderr.printf ("%s\n", e.message);
}
DOMNode node;
try {
while ((node = res.iterate_next ()) != null) {
stdout.printf ("%s\n", (node as DOMElement).tag_name);
}
} catch (Error e) {
stderr.printf ("%s\n", e.message);
}
and all I get for output is
HTML
HEAD
BODY
I'm lost now. The SVG file clearly loads correctly but it isn't part of the document?
I believe Webkit has a quirk where, if it doesn't know the MIME type of a document, it will wrap it in <html> tags. So I suspect the document you are trying to access has been transformed by Webkit into something like:
<html>
<head />
<body>
<svg>...etc...</svg>
</body>
</html>
That's why you are seeing a <head> tag in your code.
As a suggestion, try using Vala's equivalent of getElementsByTagName() to find your <svg> tag. From a quick look at the docs, it should be something like:
var dom = web_view.get_dom_document();
var el = dom.get_elements_by_tag_name("svg").item(0);
var child = var child = el.first_element_child;
Alternatively, if there is a way to tell WebKit/WebFrame that the MIME type of the file is "image/svg+xml", then that should also solve your problem.

Writing a javascript library

I want to write a JS library and handle it like this:
var c1 = Module.Class();
c1.init();
var c1 = Module.Class();
c2.init();
And of course, c1 and c2 can not share the same variables.
I think I know how to do this with objects, it would be:
var Module = {
Class = {
init = function(){
...
}
}
}
But the problem is I can't have multiple instances of Class if I write in this way.
So I'm trying to achieve the same with function, but I don't think I'm doing it right.
(function() {
var Module;
window.Module = Module = {};
function Class( i ) {
//How can "this" refer to Class instead of Module?
this.initial = i;
}
Class.prototype.execute = function() {
...
}
//Public
Module.Class = Class;
})();
I don't have a clue if it's even possible, but I accept suggestions of other way to create this module.
I don't know if it's relevant also, but I'm using jQuery inside this library.
Usage:
var c1 = Module.Class("c");
var c2 = Module.Class("a");
var n = c1.initial(); // equals 'c'
c1.initial("s");
n = c1.initial(); // equals 's'
Module Code:
(function(window) {
var Module = window.Module = {};
var Class = Module.Class = function(initial)
{
return new Module.Class.fn.init(initial);
};
Class.fn = Class.prototype = {
init: function(initial) {
this._initial = initial;
},
initial: function(v){
if (v !== undefined) {
this._initial = v;
return this;
}
return this._initial;
}
};
Class.fn.init.prototype = Class.fn;
})(window || this);
This is using the JavaScript "Module" Design Pattern; which is the same design pattern used by JavaScript libraries such as jQuery.
Here's a nice tutorial on the "Module" pattern:
JavaScript Module Pattern: In-Depth

Resources