AnimateCC Basic TweenJS Tipp Graphics Tipp Shortcuts Canvas Video Download Beispiel Dateien
siehe auch: Flash CS6, CreateJS -:|:-Actionscript 2-:|:- Actionscript 3 -:|: - easelJS Api -:|:- Adobe Help
Schauen Sie sich auch die Canvas Videos Tipps an
Vielleicht möchten Sie sich erkenntlich zeigen und etwas dafür zurückgeben?
Nutzen Sie das sichere PayPal-System, um etwas Geld zu spenden (Papal Button oben rechts). Sie ermutigen mich damit, mit meiner Arbeit fortzufahren. Die Höhe des Betrages ist nicht von Bedeutung, auf die Geste kommt es an.
Achtung ab Version AnimateCC 2019 gibt es die in den Document Settings (Modifizieren / Dokument) die Standard- Einstellung: Erweiterte Ebenen verwenden. Dieser Modus sollte deaktiviert werden, um meine Beispiele zu nutzen und die Instanzen so anzusprechen, wie es in früheren Versionen üblich war. Siehe dazu https://helpx.adobe.com/animate/using/timeline-layers.html#advanced-layers
Siehe eventuell auch meine Forumpostings.
Movieclip does not play in single Frame
AnimateCC 2019 does not work in AnimateCC 2018
Wenn man hauptsächlich programmiert ist es einfacher "Erweiterte Ebenen" zu deaktivieren.
Wenn man Erweiterte Ebenen aktiviert, muss auch die virtuelle Kamera auf der Bühne sein. Logischerweise müssen die Ebene und das Symbol vorhanden sein, die man ansprechen will.
Folgendes Beispiel: In einer Ebene in der Hauptzeitleiste mit dem Namen F1 befindet sich ein Symbol mit dem Instanznamen symbol1.
Folgendermaßen kann man die X Position des Symbols auf 0 setzen.
var Layer = this.getChildByName("L1"); var green = Layer.getChildByName("symbol1"); green.x = 0;
Oder auch mit Punktsyntax
this.yourLayer, this.yourLayer.yourInstance, this.yourInstance
Weitere neue Funktionen in AnimateCC
Das Framework ZIM baut auf CreateJS auf und lässt sich sogar direkt in AnimateCC einbinden. Es bietet viele weitere Möglichkeiten der Programmierung und macht vieles einfacher.
siehe auch folgende Einführungen und Hilfen
Adobe AnimateCC / Canvas Dokumente
Animate CC Benutzerhandbuch // Tutorials
EaselJS Module / Animate CC Help // Canvas Komponenten
Mit Animate CC gibt es die Möglichkeit mit dem Flash-Programm erstellte Animationen und Javascript-Programmierungen als HTML5/ Canvas/ Javascript Inhalt zu veröffentlichen. Dazu startet man mit einem neuen Canvas Dokument oder eine vorhandene AS3-fla Datei wird in eine Canvas fla Datei konvertiert. Hier gibt es 2 Möglichkeiten: Erstens, man kopiert sämtliche Bilder einer fla Datei in ein neu erstelltes Canvas Dokument, oder man öffnet eine fla Datei und wählt im Menü: Befehle / HTML5 Canvas aus AS3 Dokumentformaten konvertieren Außerdem muss Actionscript durch Javascript ersetzt werden. Das kann man nicht über einen Menübefehl in einem Rutsch erledigen, sondern muss neu programmiert werden. Unter Fenster, Codefragmente gibt es einige hilfreiche Codebeispiele für den Einstieg.
Es gibt mit "HTML5, Canvas" einige Einschränkungen, die hier aufgelistet werden, doch es wird ständig verbessert.
Nach dem Veröffentlichen entsteht eine HTML-Datei und eine eingebundene Javascript-Dateien. Sounds und Bitmaps werden in Ordnern abgespeichert, die man unter Datei / Einstellungen für Veröffentlichung definieren kann. Außerdem werden einige Javascript-Dateien von externen Servern eingebunden. Diese kann man auch herunterladen und lokal einbinden. https://code.createjs.com/
Veröffentlicht man eine so erstellte Datei entsteht eine HTML-Datei mit Javascript im Head-Bereich, eingebundenen externen Javascript-Dateien, einer eingebundenen Javascript-Dateien gleichen Namens. Ein Canvas-Element im Body Bereich der HTML-Datei und einer onLoad Anweisung im body-Tag der HTML-Seite. Außerdem entstehen Ordner für Bilder und Sound Dateien sofern diese benötigt werden.
Wenn man eine Datei testet mit Strg Enter wird an den Dateinamen eine Variable angehängt. Man sollte so eine Datei nicht auf den Server laden, sondern am Schluss die Dateien erstellen indem man Datei / Veröffentlichen wählt.
Hat man eine Datei mit allen Bildern und Animationen fertig gestellt und eventuell in der HTML-Datei noch einige Änderungen vorgenommen, würde durch erneutes Veröffentlichen die HTML überschrieben. Damit das nicht passiert deaktiviert man diese Option unter Datei / Einstellungen für Veröffentlichen
Gleiches gilt für Bilder und Sounds. Damit keine neue Bilder oder Sounds generiert werden deaktiviert man die Optionen.
Ab Version AnimateCC 2019 gibt es in den "Einstellungen für die Veröffentlichung" den Karteireiter "Bildeinstellungen" Hier hat man die Möglichkeit alle Vektorgrafiken in ein Bitmap umwandeln zu lassen.
Dokument als Textur exportieren Der Vorteil ist eine bessere Performance, da die Vektorgrafiken nicht zur Laufzeit berechnet werden.
Hat man die Option deaktiviert, kann man die Bilder die als Pixelbilder integriert sind als Spritesheet zu exportieren.
Bei den Bildern hat man die Möglichkeit einzelne Bilder abzuspeichern oder alle Bilder zusammen zu einem sogenannten Spritesheet zusammenzufassen. Es entsteht nur ein Bild und eine dazugehörige JSON Datei, welche die Bildteile definiert. Ich habe festgestellt, dass es bei Firefox und Safari Probleme geben kann, wenn die Bilder zu einem großen Spritesheet zusammengefasst werden. Wenn man das PNG Bild in Photoshop erneut als png 24 mit Transparenz speichert, funktioniert es. Ich würde jedoch anraten, die Spritesheet Funktion zu deaktivieren.
Wenn man die Bilder als separate Bilder veröffentlicht, sollte man folgende Zeile im Scriptblock der HTML-Seite hinzufügen, um den Ladevorgang zu beschleunigen.
var loader = new createjs.LoadQueue(false); loader.setMaxConnections(6); // diese Zeile hinzufügen
Standardmäßig wird das Canvas-Element mit der CSS Eigenschaft position:absolute;
veröffentlicht. Das führt dazu, dass Text oder andere Elemente, welche man nachträglich unter dem Canvas-Element einfügt, hinter dem Canavas Element verschwinden. Suchen Sie die Zeile position:absolute;
im CCS-Quelltext der veröffentlichten HTML-Seite und ändern Sie diese durch position: static, oder eine andere passende CSS Eigenschaft.
Siehe Adobe Hilfe Canvas veröffentlichen
Mit Animate CC kann man in den Einstellungen für Veröffentlichungen, einige Optionen einstellen, um die Ausrichtung und Größe des Canvas-Elements an das Browserfenster anzupassen.
Siehe alle Einstellungen für eine Responsive Darstellung mit den Einstellungen für eine Responsive Darstellung des Canvas Elements.
canvas{width:100%; height:auto;}
Die Größenangabe im Canvas-Element entspricht der Einstellung der Bühne in Flash.
Die Größe des Browserfensters kann man folgendermaßen ermitteln
var stageBreite = window.innerWidth;
var stageHoehe = window.innerHeight;
Hier ein Link zu einem Tipp, wie man das Canvas-Element per Javascript an die Fenstergröße anpasst.
function onResize() { //OPTION 1: //Proportionale Vergrößerung // browser viewport size var w = window.innerWidth; var h = window.innerHeight; // Dimensionen der stage / canvas var ow = 550; // your stage width var oh = 400; // your stage height // Größenverhältnis beibehalten var scale = Math.min(w / ow, h / oh); var newHeight = ow * scale; var newWidth = oh * scale; // stage.scaleX = scale; stage.scaleY = scale; // canvas Größe einstellen stage.canvas.width = newHeight; stage.canvas.height = newWidth; //set width and height variables again //var page_canvas = document.getElementsByTagName("canvas")[0]; //stageWidth = page_canvas.width; //stageHeight = page_canvas.height; // // update the stage stage.update() } // window.onresize = function() { onResize(); }
In CMS oder Blogs wie Wordpress kann es hilfreich sein, die von AnimateCC erstellte HTML-Seite in einem iframe zu veröffentlichen. Hierbei sollte der iframe das gleiche Seitenverhältnis haben wie das Canvas-Element. Ich habe dazu 2 Lösungen erstellt, die man sich in den Download Dateien im Ordner "publish" anschauen kann.
Die einfachste Lösung hat den Nachteil, dass es einen kleinen Rand an der linken Seite gibt. Man erstellt einen Iframe auf welches man CSS anwendet. Um die Höhe anzupassen errechnet man sich die Höhe in Prozent und verwendet die CSS Eigenschaft vw für Breite und Höhe des Iframes. Nehmen wir an, das Canvas Element oder die Bühnengröße sei Breite: 600, Höhe: 100.
Das ergibt 1/6 = 0.1666
entspricht 16.6 Prozent. Das CSS für den Iframe definiert man folgendermaßen:
iframe{width: 100vw; height: 17vw;}
In der zweiten Lösung wird mittels Javascript die Größe des Iframes bestimmt. Funktioniert gut, erfordert das Einbinden einer Javascript-Datei. In dieser Javascript-Datei muss auch die Höhe und Breite eingegeben werden, um das Seitenverhältnis zu errechnen. var whRatio = 100/600;
Diese von mir bevorzugte Lösung wird schon lange genutzt, um Youtube oder Vimeo Videos responsive einzubinden. Hier benötigt man ein paar CSS Anweisungen und einen iframe
welcher in ein div
eingebettet ist. In dem iframe
ist die Seite eingebettet, die von AnimateCC durch Datei/ Veröffentlichen erzeugt wird. In den Veröffentlichungseinstellungen sollte die Seite responsive, mittig, eingebunden werden.
<style> #iframe-container { position: relative; padding-bottom: 17%;//Bühnenhöhe in Prozent overflow: hidden; } #iframe-container iframe { position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: none; } </style>
Das folgende wird an gewünschter Stelle im body-Gültigkeitsbereich eingefügt. Er kann auch innerhalb eines Blockelements eingefügt werden um beispielsweise eine maximale Breite nicht zu überschreiten.
<div id="iframe-container"> <iframe src="lok.html"></iframe> </div>
In allen Beispielen benötigt man das Seitenverhältnis von Breite und Höhe. Die Breite wird auf 100 Prozent gesetzt und dazu muss die Höhe in Prozent eingegeben werden. Diese muss man sich zuvor errechnen.
In diesen Beispielen ist Bühnenbreite 600 Pixel und die Höhe 100 Pixel. Die aufgerundete Höhe beträgt 17 Prozent.
Rechenbeispiel: (Höhe / Breite) * 100
Sollte das Canvas Element nicht im Querformat sein bietet sich folgende Lösung an. Das folgende Beispiel bezieht sich auf ein quadratisches Seitenformat.
CSS
#iframe-container {
display: flex;
justify-content: center;
}
#iframe-container iframe {
height: 90vh;
width: 90vw;
border: none;
}
HTML
<div id="iframe-container">
<iframe src="canvas.html"></iframe>
</div>
Wenn Sie eine Datei erstellen, deren Größe, Hintergrundfarbe, Bildlaufrate oder auch Ebenen samt Inhalt und Zeitleiste öfter eingesetzt werden sollen, wählen Sie Datei, als Vorlage speichern und füllen Sie die Felder aus. Diese Vorlage können Sie über Datei , neu, Vorlage laden
Hier geht es darum eine HTML Vorlage zu erstellen, in welche die SWF Datei oder das Canvas-Element eingebettet ist. Diese HTML-Datei richtet man ein unter Datei, Einstellungen für Veröffentlichung Unter dem Karteireiter Erweitert kann man eine Vorlage erstellen oder laden.
siehe diesen Video Tipp
Nehmen wir an Sie wollen mehrere Seiten erstellen, welche eine bestimmte Javascriptbibliothek benötigt, die mittels Script- Tag in HTML eingebunden wird. (Man kann Scripte aber auch über das Action-Fenster, / siehe links oben, "Global" einfügen)
Gehen Sie folgendermaßen vor:
EaselJS ist eine Javascript Bibliothek, welche das Arbeiten mit HTML5 und dem Canvas-Element für alle Flasher vereinfacht, denn die Klassen, Eigenschaften und Methoden sind denen von Actionscript3 so ähnlich wie möglich. Das englische Wort Easel bedeutet Staffelei, welches einen Bezug zum HTML5 Canvas-Element herstellt. Außerdem steckt darin noch das Wort ease (deut: vereinfachen) und genau das ist der Sinn von EaselJS, es vereinfacht den Umstieg von Flash auf HTML5, da viele Objekte und Methoden auch in Actionscript vorkommen. Unter dem Namen CreateJS hat Adobe einige Frameworks zusammengestellt, die es Flashern ermöglichen sich schnell in Html5/ Javascript einzufinden.
Der EaselJS Download Button unten auf der Seite bietet viele nützliche Beispiele und einige Tutorials, die jedoch stellenweise etwas veraltet sind.
Bei Github gibt es einige Beispiele neueren Datums. CreateJS Github
Flash wurde durch Animate CC ersetzt und mit einigen neuen Funktionen erweitert. Siehe dazu meine Videotipps. neue Pinsel, neue Skaliermöglichkeiten der Bühne inklusive Inhalt, verknüpfte Farbfelder und Typekit Schriften, Creative Cloud Library, SVG Import, Export, Projektor wurde wieder eingeführt, neue Video Export Funktionen, sowie einige weitere Neuerungen
Es ist auch möglich das Flashprogramm dazu zu nutzen Movieclips, Grafiken und Animationen zu erstellen und die Programmierung dann auf der HTML-Seite vorzunehmen.
Auch mit Flash CS6 war es möglich mittels der Erweiterung CreateJS diese Veröffentlichung vorzunehmen, siehe dazu meine ersten Tipps. In Flash CS6 wird eine ältere Version von CreateJS benutzt. Hier gibt es ein paar Unterschiede.
Wie schon oben erwähnt bietet Flash CC über das Fenster "Codefragmente" die Möglichkeit einige Befehle zu nutzen. Wählt man einen der Befehle aus, wird eine Ebene "Actions" erstellt, darin ein Schlüsselbild mit den entsprechenden Javascriptbefehlen.
Generell gibt es 2 Möglichkeiten Javascript- Befehle einzufügen.
Viele Beispiele, die man im Netz findet wurden auf die zweite Art erstellt. Meine Beispiele auf dieser Seite wurden in erster Linie in AnimateCC eingefügt.
Fügt man den Code im AnimateCC Programm ein, so wird dieser Code im Action- Fenster angezeigt und kann dort eingefügt werden. Hier gibt es 3 Möglichkeiten
Den Code direkt im Action-Fenster einfügen. Hierbei gibt es 2 Möglichkeiten
Fügt man den Code in einem Schlüsselbild ein, erscheint links ein Hinweis, wo der Code eingefügt wurde. Jeder so eingefügte Code in irgendeinem Schlüsselbild kann so schnell erreicht werden. Der Code wird ausgeführt wenn das Schlüsselbild aufgerufen wird.
Unter Globaler Code kann man Code einfügen, der von überall erreichbar sein soll.
Wähle im Actionfenster Global / Script und schreibe den Code.
Also eine gute Stelle, um globale Variablen zu definieren. Siehe dazu meine Download- Beispiele im Ordner Variable. 4, 5, 6 . Auch Funktionsdeklarationen sollte man als Globalen Code einfügen, anstatt in einem Keyframe, damit diese Funktionen nicht erneut deklariert werden, wenn der Keyframe erneut aufgerufen wird.
Will man komplette Javascriptdateien einschließen, wähle Global / einschließen. Klicke auf das Pluszeichen oben rechts und wähle URL oder Bibliothek aus. Beim Veröffentlichen befindet sich dieses Script standardmäßig im Ordner libs. Siehe Datei/ Einstellungen für Veröffentlichung
Codefragmente sind fertige Codebausteine, die man nutzen kann. Achte darauf, dass der Abspielcursor in der Zeitleiste an der Stelle ist, wo der Code eingefügt werden soll. Wähle den Code aus und klicke ihn doppelt an. Der Code wird in eine Ebene eingefügt die den Namen "Actions" hat. Sollte so eine Ebene nicht vorhanden sein, wird eine erzeugt. Auch ein nicht vorhandenes Schlüsselbild wird an der Stelle erzeugt, wo sich der Abspielcursor befindet.
Es gibt Code der mit "Klicken...." beginnt. Hier wählt man eine Instanz eines Buttons oder Movieclips auf der Bühne aus und klickt dann doppelt auf den Codebaustein. Auch hier muss man darauf achten wo der Abspielcursor ist, denn dort wird der Code in einem Schlüsselbild eingefügt.
Wähle oben rechts im Action-Fenster Asset. Es öffnet sich ein Fenster anstatt der Codeeingabe. Schritt für Schritt kann man sich den Code zusammenstellen. Unten rechts kann man auf Abbrechen klicken um das Assets- Fenster zu schließen. Sollte man diese Assets mehrmals nutzen sollte man die Variable var _this = this; einmal löschen, diese Zeile darf nur einmal vorkommen.
Nachdem man die Seite veröffentlicht hat kann man auf der HTML Seite Code einfügen. Siehe dazu oben auf der HTML Seite die Stelle <!-- write your code here --> ca. Zeile 80
Im folgenden Beispiel habe den Befehl eingefügt die Hauptzeitleiste in Bild 10 zu stoppen. Mehr zu exportRoot
exportRoot.gotoAndStop(10);
}
</script>
<!-- write your code here -->
Hat man globalen Code integriert und nicht in einer externen Datei ausgelagert, befindet sich ungefähr in Zeile 19 die Stelle den Code zu verändern.
Hat man globales Script in einer Datei ausgelagert, befindet sich dieses Script standardmäßig im Ordner libs. Siehe Datei/ Einstellungen für Veröffentlichung
Javascript hat eine lose Typisierung, das heißt der Datentyp einer Variable kann sich ändern und muss beim Deklarieren nicht angegeben werden.
var myVar = 5;
Eine Variable, die in weiteren Frames der Zeitleiste aufgerufen werden soll, sollte man folgendermaßen deklarieren.
this.myVar = 5;
Globale Variablen, die überall Gültigkeit haben, sollte man im Actions-Fenster unter Global / Script einfügen. Hier kann man auch eine externe Script Datei einbinden. Siehe dazu meine Download Beispiele im Ordner var.
Grundlagen zum Thema Variablen und Datentypensiehe auch w3schools Function Definitions
Siehe auch Function in meinen Javascript Tipps
In den Dateien zum Download siehe Ordner: javascript/function
Eine Funktion kann in Javascript auch eine Konstruktorfunktion sein, daher gibt es einige Unterschiede zu AS3. Ich habe hier 15 Beispiele erstellt, die Sie der Reihe nach studieren können. Die Infos erhalten Sie in den Kommentaren.
Die Zeitleistenbefehle in EaselJS sind:
play();
stop();
gotoAndStop(2);
gotoAndPlay(2);
Die Bildnummern beginnen bei 0 nicht bei 1. Das heißt das erste Bild hat die Bildnummer 0. Man kann stattdessen einen Bildnamen (label) eingeben, der muss in Anführungzeichen eingegeben werden und einem Keyframe zugewiesen werden (Eigenschaftenfenster).
gotoAndPlay("meinBildname");
Die Actionscript MovieClip Methode nextFrame gibt es in EaselJs nicht. Da es die Eigenschaften currentFrame
und totalFrames
gibt, kann man es auf andere Weise programmieren. Dazu folgendes Beispiel.
In der Hauptzeitleiste befindet sich im ersten Frame ein händisch auf die Bühne gezogener Button mit Instanznamen goNext_btn. Mittels click soll der nächste Frame der Hauptzeitleiste aufgerufen werden. Nach dem letzten Frame soll beim nächsten Click der erste Frame erscheinen.
Die Funktion für den Buttonclick wird als globales Script angelegt. Gehe dazu im Action Fenster im linken Bereich auf: Global / Script und gebe folgende Funktion ein.
Globales Script
function goNext() { if (exportRoot.currentFrame < exportRoot.totalFrames -1) { exportRoot.gotoAndStop(exportRoot.currentFrame + 1); } else { exportRoot.gotoAndStop(1); } console.log(exportRoot.currentFrame); }
Die Hauptzeitleiste wird mit exportRoot angesprochen.
Script im ersten Frame
this.stop(); exportRoot.go_btn.addEventListener("click", goNext);
Diese Eigenschaften des Movieclips liefern Informationen der Zeitleiste.
currentFrame
gibt oder setzt den aktuellen Frame. Der erste Frame ist 0.
totalFrames
ist die Anzahl der Frames. Da der erste Frame 0 ist, ist der letzte Frame totalFrames-1
currentLabel
liefert den letzten Frame mit einer Bezeichnung. Man klickt in ein Schlüsselbild und gibt die Bezeichnung im Eigenschaftenfenster im Feld Name ein. Seit Animate CC 2019, kann man nachdem man einen Namen eingegeben hat, unter Typ folgende Optionen wählen: Name, Kommentar, Anker . Für die Bildbezeichnung sollt die Standardeinstellung Name gewählt sein. Diesen Frame kann folgendermaßen ansteuern.
this.gotoAndStop("mein Bildname");
Siehe dazu folgendes Beispiel aus dem Ordner diverse/ currentFrame.fla
Siehe auch diesen Forumsbeitrag
Achtung ab Version Animate CC 2019 gibt es beim Zugriff auf Movieclips einen Unterschied sofern man "erweiterte Ebenen" aktiviert hat. Es ist standardmäßig aktiviert. Siehe dazu diese Adobe Info. In meinen folgenden Beispielen sollte die Option "erweiterte Ebenen" deaktiviert sein. Modifizieren / Dokument / erweiterte Ebenen.
Movieclips, die händisch aus der Bibliothek auf die Bühne gezogen wurden und im Eigenschafteninspektor einen Instanznamen bekommen haben, spricht man aus der gleichen Zeitleiste folgendermaßen an, beispielsweise um die X-Position zu ändern:
this.myMc.x = 20;
Oder wenn der MC in der Hauptzeitleiste liegt.
exportRoot.myMc.x = 20;
Andere Möglichkeit: getCildByName("String")
.Die Methode erwartet wird einen Instanzname als String.
exportRoot.getChildByName("myMc");
Der Array Zugriffsoperator bietet die Möglichkeit einen Namen aus einem String und einem numerischen Wert zusammenzusetzen. Im folgenden Beispiel lautet der Instanzname "myMc1". Weiter unten ist ein Beispiel mit einer for-Schleife. Achten Sie auf die Schreibweise, es erfolgt kein Punkt hinter this.
this["myMc"+ 1].x = 20;
Ein komplexer Movielip, den man händisch auf die Bühne gezogen hat, sollte erst angesprochen werden, wenn er geladen ist. Eine Möglichkeit ist, das Script erst im nächsten Frame einzufügen oder man kann den Event added
nutzen. siehe easelJS Doku
this.mc.addEventListener("added", init); function init(evt) { evt.currentTarget.gotoAndStop(2); }
Hat man einen Movieclip per EaselJS- Script auf die Bühne gebracht, lässt man das this weg, denn man hat dann eine Variable deklariert, auf die man auch innerhalb von Funkionen zugreifen kann.
var myMc = new lib.Verknuepfungsname();
this.addChild(myMc);
myMc.x = 20;
Im Script-Block auf der veröffentlichen HTML-Seite bringt man ein Bibliothekselement so auf die Bühne:
var appel = new lib.Apfel();
stage.addChild(appel);
Verschachtelte Movieclips spricht man mit Punktsyntax an. Im folgenden Beispiel befindet sich myMc2 innerhalb von myMc. Also ist myMc das Elternelement von myMc2.
this.myMc.myMc2.x = 20;
Hat man mehrere Movieclips mit einer Durchnummerierung im Instanznamen, welche man im Eigenschaftenfenster vergeben hat, kann man diese folgendermaßen ändern. Im folgenden Beispiel heißen die Movieclips mc1, mc2, mc3 und werden mit 10 Pixel Abstand nebeneinander gelegt.
this["mc"+1].x = 10;
this["mc"+2].x = 20;
this["mc"+3].x = 30;
In einer for-Schleife:
for(i=1; i < 4; i++){ this["mc"+i].x = 10 * i; }
Des Weiteren kann man jedem Objekt eine Eigenschaft anhängen. So kann ich beispielsweise einem Button oder einem Movieclip eine Variable anhängen, auf die man in einer Event-Funktion zugreift. Nehmen wir an, wir haben Buttons, die Bilder in der Hauptzeitleiste aufrufen sollen. b0 soll zu frame 0 gehen, b1 zu 1 etc.. Dann wäre es doch schön, wenn der Button diese Bildnummer gleich mitbringt. So könnte man eine Event-Funktion auf alle Buttons registrieren.
this.b0.bild = 0;
this.b1.bild = 1;
this.b2.bild = 2;
this.b0.addEventListener("click", goFrame.bind(this));
this.b1.addEventListener("click", goFrame.bind(this));
this.b2.addEventListener("click", goFrame.bind(this));
function goFrame(){
this.gotoAndStop(evt.currentTarget.bild);
}
Das geht selbstverständlich auch alles in einer for-Schleife
for(i=0; i < 4; i++){ this["b"+i].bild = i;
this["b"+i].addEventListener("click", goFrame.bind(this)); }
In den Dateien zum Download gibt es 4 Step by Step Beispiele einer Bildergalerie mit Übergangseffekt.
hier das letzte Beispiel.
in der HTML Seite Code ändern siehe hier
Mit EaselJS hat man die Möglichkeit aus einer Instanz auf die Hauptzeitleiste oder die stage zuzugreifen. siehe dazu diesen Beitrag
Innerhalb eines MC kann man auf Funktionen oder Variablen zugreifen, die in einem Frame der Hauptzeitleiste eingefügt sind. Folgende Zeile in einem Movieclip setzt die Hauptzeitleiste auf Frame 5;
exportRoot.gotoAndStop(5);
Siehe dazu auch Zeitleiste nächsten Frame aufrufen
Instanzen der Display-List in EaselJS können die Bühne aufrufen mittels getStage(). Hierbei ist jedoch die Hauptbühne auch bekannt als root
(AS3 Schreibweise) oder _root
(AS2 Schreibweise) ein child Element von getStage(). Wenn man kein anderes Element der stage hinzugefügt hat, ist "root" das first child. Wenn man auf der Hauptbühne eine Funktion wie diese erzeugt hat:
this.doSomething = function(){ alert("Something"); }
So kann man aus jeder Zeitleiste eines Symbols diese Funktion folgendermaßen aufrufen:
this.getStage().getChildAt(0).doSomething();
eine schnelle Möglichkeit ist:
exportRoot.doSomething();
Im obigen Beispiel gibt es in der Hauptzeitleiste ein klassisches Tween, bei dem sich ein Dreieckspfeil um den Mittelpunkt der Bühne dreht. Im ersten Bild der Hauptzeitleiste befindet sich folgendes Javascript.
this.stop();
this.a = 0;
Außerdem gibt es einen Movieclip in der Mitte mit einem Formtween. Er hat folgendes Javascript im ersten Frame:
exportRoot.a ++;
exportRoot.gotoAndStop(exportRoot.a);
Dadurch zeigt die Hauptzeitleiste das nächste Bild an und der Pfeil dreht sich ein bisschen nach jeder Runde des Movieclips.
Im letzten Bild der Hauptzeitleiste wird a wieder auf 0 gesetzt, damit der Hauptfilm wieder im ersten Frame landet.
this.a = 0;
Siehe auch Movieclip aus der Bibliothek per Script hinzufügen
Hier wird ein neuer Movieclip rein programmatisch erzeugt. Es wird sogar eine Grafik eingefügt und eine Zeitleistenanimation. In AnimateCC macht es nicht wirklich Sinn, aber man kann EaselJS auch ohne AnimateCC nutzen und da ist diese Technik von Vorteil.
Ich habe 2 Beispiele erstellt, ein einfaches und ein objektorientiertes mit prototype.
Einfaches Beispiel addChild/movieClip_1.html
Prototype Beispiel prototype/movieClip.html
Weitere Infos befinden sich in den Beispielen
var mode = createjs.MovieClip.INDEPENDENT; var startPos = 0; var loop = true; var labels = {start:0, mitte:30, ende:60}; var mc = new createjs.MovieClip(mode, startPos, loop, labels); this.addChild(mc); var kreis = new createjs.Shape(); kreis.graphics.beginFill("red").drawCircle(0, 0, 50); kreis.x = 50; kreis.y = 150; mc.timeline.addTween(createjs.Tween.get(kreis).to({x:300},30).to({x:10},100));
In diesem praxisorientierten Beispiel gibt es ein Tweening, das wie ein Vorhang der runter und rauf läuft. Das Tweening ist in einem Movieclip. Jedes mal wenn der Vorhang unten ist und das Bild verdeckt, wird auf der Hauptzeitleiste das nächste Bild (frame) aufgerufen.
In den Dateien zum Download sind weitere Beispiele, die Schritt für Schritt zum folgendem Beispiel führen.
Hier geht es darum abzufragen ob ein Objekt ein Movieclip ist. Das kann man für Spiele gebrauchen. Siehe auch das Thema getObjectsUndPoint
Jedes Container Objekt besitzt die Methode addChild(). So ist beispielsweise die stage (Bühne) ein Container, oder auch ein MovieClip, oder SimpleButton. Wenn man ein Objekt als child in ein anderes Objekt einfügt, wird es relativ zum Elternobjekt positioniert. Außerdem wird es neu in der Hierarchie von Objekten zugeordnet. Ein Objekt kann immer nur einmal in einem Elternobjekt (parent) liegen. Wenn ein Object einem anderen Elternobjekt zugewiesen wird, wird es aus dem vorigen Elternobjekt entfernt.
Erstelle ein Symbol (Movieclip, Schaltfläche, Grafik, importiertes Bitmap). Suche das Symbol in der Bibliothek und klicke neben dem Namen doppelt auf das Feld "Verknüpfung". Vergebe dort einen Verknüpfungsnamen (Regeln für Namensvergabe beachten). Im folgendem Beispiel ist der Name: "Ball"
Es wird eine neue Instanz erzeugt, new lib.Ball()
Die x und y Position wird gesetzt balla.x, balla.y
Das Element wird der Displayliste hinzugefügt.
addChild(balla)
var balla = new lib.Ball();
balla.x = 500;
balla.y = 50;
this.addChild(balla);
Die Displaylisten Befehle wie addChild, setChildIndex etc funktionieren im Prinzip genauso wie in Actionscript3, siehe dazu diese Tipps.
Wenn man mehrere Objekte mit addChild() einem Elternobjekt hinzufügt, so liegt das zuletzt hinzugefügte Objekt in der Stapelreihenfolge über den anderen child Objekten. So kann man addChild() auch dazu nutzen, um ein Objekt in der Stapelreihenfolge nach oben zu setzen.
Allerdings gibt es ein Problem wenn man die Displayobjekte aus der Bibliothek händisch auf die Bühne zieht.
Hat man einen MC aus der Bibliothek händisch auf die Bühne gezogen und diesem im Eigenschaftenfenster einen Instanznamen zugewiesen, kann man den Befehl addChild() nicht nutzen, um es einem anderen Elternobjekt zuzuweisen. Eine Möglichkeit, ist ein Duplikat zu erzeugen und das ursprüngliche Objekt unsichtbar zu machen.
Siehe dazu dieses Beispiel
var anzahl = 30;
var abstand = 15;
var ball = new Object();
for(i = 0; i < anzahl; i++)
{
ball[i] = new lib.Ball();
ball[i].x = ball[i-1].x - abstand;
ball[i].y = 50;
ball[i].scaleX = 1 - i / anzahl;
ball[i].scaleY = 1 - i / anzahl;
ball[i].gotoAndPlay(i);
stage.addChild(ball[i]);
}
Mit der EaselJS Ticker Klasse bestimmt man einen Event der zeitgesteuert ist. Ähnlich wie der AS3 ENTER_FRAME Event. Man hat mit der Ticker Klasse verschiedene Möglichkeiten die Wiederholungsrate zu definieren. Es gibt weitere Eigenschaften pause und man kann Zeiten abfragen. Die Zeit seit Aufruf des Tickers, Die Zeit zwischen den einzelnen Tick-Events. Die Zeit wo der Ticker nicht pausiert wurde. Damit hat man viele Möglichkeiten zeitgesteuerte Anweisungen zu definieren.
Siehe hier die älteren Ticker Tipps holperig ins Deutsche übersetzt von mir.
Die folgenden Beispiele sind kommentiert. Sie befinden sich in den Dateien zum Download, Ordner tick
Beispiel 1 Die Eigenschaften des Ticker Events
Beispiel 2 paused und seine Bedeutung
Beispiel 3 Animation wird mit Paused gestoppt
Beispiel 3b Zeitabfrage für Spiele, Start, Pause, Beenden, Neustart
Beispiel 4 zeitbasierte Animation unabhängig von der Framerate oder dem tick
Beispiel 5 Die Framerate wird per Numeric Stepper geändert
Beispiel 6 Bewegung mit Gravitation
Beispiel 7 requestAnimationFrame / Performance Verbesserung
Das Tick-Ereignis unterstützt sowohl die Timeout- als auch die requestAnimationFrame-Methode. Gerade wenn viele Ereignisse zu leicht unterschiedlichen Zeiten eintreten, kann es zu Verzögerungen kommen. Mittels requestAnimationFrame wird das Intervall, wann die Bühne neu gerendert wird, vom Browser bestimmt. So hat man eine möglichst effiziente und performante Darstellung. Mit folgender Zeile wird das Tick-Ereignis auf requestAnimationFrame gesetzt. Sollte das Gerät requestAnimationFrame nicht unterstützen wird automatisch Timeout genutzt.
createjs.Ticker.setFPS(30); createjs.Ticker.useRAF = true;
Hier sollte man die Framerate auf einen Divisor von 60 setzen (z.B.: 15, 20, 30, 60), um ein möglichst gleichmäßiges Ergebnis zu erzielen.
Damit auf Tabletts und Smartphones Mouse Events als Touch Events umgewandelt werden, muss man man folgenden Befehl im ersten Frame der Hauptzeitleiste einfügen.
createjs.Touch.enable(stage);
Alternativ kann man es auch in der HTML-Datei einfügen. Der Befehl sollte hinter der Initialisierung der Variablen stage eingefügt werden. Diese Initialisierung findet man in der HTML-Datei, welche durch die Veröffentlichung entsteht.
stage = new createjs.Stage(canvas);
createjs.Touch.enable(stage);
Für Tablets gibt es unter anderem die Befehle touchstart
und touchend
mit denen man den Berührungsbeginn und das Berührungsende auf einem Objekt abfragen kann. Es hat eine gewisse Ähnlichkeit mit dem mousedown
und mouseup
In der Regel ist es sehr komfortabel, wenn ein Objekt auf Touch und auch auf Mouse reagiert.
Setze dazu folgende Befehle ein:
mousedown
und click
Im folgenden Beispiel befindet sich ein Movieclip auf der Bühne mit Instanznamen left_mc
createjs.Touch.enable(stage); var _this = this; this.left_mc.addEventListener("mousedown", handleStart, false); this.left_mc.addEventListener("click", handleStop, false); function handleStart() { _this.left_mc.alpha = 0.3; } function handleStop() { _this.left_mc.alpha = 1; }
Über den boolschen Event Parameter isTouch
kann man abfragen, ob es sich um ein Touch Event handelt oder ein MouseEvent.
function checkTouch(evt){
console.log(evt.isTouch);
}
Für mouseover gibt es einen Befehl
stage.enableMouseOver(10);
Oder direkt in AnimateCC in einem Frame / Actionscriptfenster:
this.stage
.enableMouseOver(10);
Der Wert 10 bezieht sich auf eine Frequenz pro Sekunde, welcher definiert, wie oft eine Mausberührung oder Bewegung abgefragt wird. 50 ist der höchste Wert. Beim niedrigsten Wert 0 wird die Überprüfung aufgehoben.
Setze enableMouseOver, wie oben beschrieben und weise einer Instanz die Eigenschaft Cursor zu. Die möglichen Werte entsprechen den CSS Werten.
this.stage.enableMouseOver(20);
this.myMc.cursor = "pointer";
siehe das Thema HitArea
In den folgenden Beispielen werden verschiedene Möglichkeiten mit Events vorgestellt. Siehe auch das Thema Event.
ACHTUNG !
In Google Chrome gibt es Probleme wenn man Bitmaps im Canvas-Element offline benutzt. Siehe diesen Forumsbeitrag
ACHTUNG !
Siehe auch diesen Forumsbeitrag zum Thema stage.stageX
In älteren Dokumentationen wird empfohlen auf folgende Arten innerhalb einer Event-Funktion auf die horizontale Mausposition zuzugreifen.
Da es sich hierbei um einen Wert handelt den der Browser liefert, gibt es Probleme, sofern sich die Ansichtsgröße des Browsers oder die Größe und Position des Canvas-Elements ändert.
Daher sollte man sich über das Elternelement (das Browserfenster) die x und y Position im Canvas ausgeben lassen, und sie mit globalToLocal auf das lokale Koordinatensystem umrechnen lassen. siehe folgende Beispiele.
var p = this.globalToLocal(this.stage.mouseX, this.stage.mouseY);
Zu diesem Thema habe ich 5 Beispiele erstellt, welche verdeutlichen wie man mit stageX und stageY arbeiten kann.
Des weiteren sollte man folgenden Befehl innerhalb der HTML-Seite einfügen.<
createjs.Touch.enable(stage);
siehe TouchEvent
Im Headbereich der HTML-Seite sollte das Zoomen auf Mobilgeräten verhindert werden. Siehe auch diesen Beitrag
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
Hier ein Beispiel
this.ball_mc.on("pressmove", function (evt) {
var p = this.parent.globalToLocal(evt.stageX, evt.stageY);
evt.currentTarget.x = p.x;
evt.currentTarget.y = p.y;
});
this.ball_mc.on("pressup", function (evt) {
console.log("up");
})
this.my_mc.addEventListener("pressmove", dragMe.bind(this)); function dragMe(evt) { var p = this.globalToLocal(evt.stageX, evt.stageY); evt.currentTarget.x = p.x; evt.currentTarget.y = p.y; }
Oder wenn man eine namenlose Funktion benutzt bei einem Movieclip im Hauptfilm
this.parent.globalToLocal
Beispiel:
this.my_mc.on("pressmove", function (evt) { var p = this.parent.globalToLocal(evt.stageX, evt.stageY); evt.currentTarget.x = p.x; evt.currentTarget.y = p.y; });
Wenn ein Movieclip im Hauptfilm eingebettet ist, ist auch diese Variante möglich
this.my_mc.addEventListener("tick", moveMc.bind(this)); function moveMc(evt){ var p = this.globalToLocal(this.stage.mouseX, this.stage.mouseY) evt.currentTarget.x = p.x; evt.currentTarget.y = p.y; }
this.ball.addEventListener("tick", mouseMove.bind(this)); function mouseMove(evt) { var p = this.globalToLocal(this.stage.mouseX, this.stage.mouseY); evt.currentTarget.x = p.x; evt.currentTarget.y = p.y; }
this.ball.addEventListener("tick", mouseMove.bind(this)); function mouseMove(evt) { var p = this.globalToLocal(this.stage.mouseX, this.stage.mouseY); evt.currentTarget.x += (p.x - evt.currentTarget.x)/10; evt.currentTarget.y += (p.y - evt.currentTarget.y)/10; }
In den letzten beiden Zeilen, wird der Abstand zur Maus errechnet, durch 10 dividiert und der aktuellen Position hinzuaddiert. Je größer der Divisor desto langsamer die Bewegung auf die Maus. Der MC bewegt sich erst schnell und dann immer langsamer auf die Maus zu, weil der Abstand immer kleiner wird.
Die x und y Position eines händisch auf die Bühne gezogenen Movieclips ist nicht unbedingt der Registrierpunkt wie in AS3, sondern der weiße Punkt, den man mit dem Frei transformieren- Werkzeug verschieben kann. mehr dazu hier
Das vorige Beispiel in abgewandelter Form. Wir haben hier 2 Movieclips mit den Instanznamen rot und gruen auf der Hauptbühne. Das Actionscript wird im Schlüsselbild eingefügt.
this.rot.addEventListener("pressmove", dragMe.bind(this)); this.gruen.addEventListener("pressmove", dragMe.bind(this)); function dragMe(evt) { var p = this.globalToLocal(evt.stageX, evt.stageY); evt.currentTarget.x = p.x; evt.currentTarget.y = p.y; }
Hier noch ein Beispiel mit einer prototype Funktion näheres siehe unter OOP
createjs.MovieClip.prototype.dragDrop = function () { this.on("pressmove", function (evt) { var p = this.parent.globalToLocal(evt.stageX, evt.stageY); this.x = p.x; this.y = p.y; }); this.on("mousedown", function (evt) { this.stage.addChild(this); }); } //myMc ist ein händisch auf die Bühne gezogener Movieclip- Instanzname: myMc this.myMc.dragDrop();
In AS3 gibt es bei Drag and Drop den ersten Parameter der bestimmt, ob das Zentrum des Objekts direkt unter der Maus liegt. Das kann man in Javascript auch regeln indem man regX und regY bestimmt.
Der Punkt, der als horizontaler und vertikaler Nullpunkt angesehen wird ist in AS3 Programmierung immer der Registrierpunkt (das kleine Kreuz im Movieclip) Um diesen Punkt wird eine MC-Instanz mit AS3 skaliert oder gedreht. Bei einer händischen Drehung oder einem Tweening verhält es sich anders, da kann man mit dem Transformieren Werkzeug den kleinen weißen Punkt an eine andere Position setzen. Man verschiebt also den Dreh-, Positions- oder Skalierpunkt vom Registrierpunkt weg.
In Canvas mit Javascript, ist dieser kleine verschobene Punkt auch für die EaselJS Programmierung entscheidend. Außerdem besteht die Möglichkeit per EaselJS diesen Punkt zu bestimmen oder abzufragen. myMc.regX, myMc.regY liefert den Abstand zum eigentlichen Registrierpunkt.
mehr dazu in diesem Beispiel 1 und Beispiel 2
Hier geht es darum, dass beim Verschieben eines MC der Registrierpunkt nicht unter den Cursor rutscht, sondern dass man den MC da verschieben kann, wo die Maus gerade liegt. Das ist besonders bei großen Objekten von Wichtigkeit.
Man setzt auf mousepress den regX und regY Punkt neu, so dass er direkt unter dem Cursor liegt. Hier kommt es wieder drauf an, wie man das macht, Stichwort globalToLocal
this.actor_mc.addEventListener("pressmove", dragMc.bind(this)); this.actor_mc.addEventListener("mousedown", setRegPoint.bind(this)); function setRegPoint(evt) { var reg = evt.currentTarget.globalToLocal(evt.stageX, evt.stageY); var p = this.parent.globalToLocal(evt.stageX, evt.stageY); evt.currentTarget.regX = reg.x; evt.currentTarget.regY = reg.y; evt.currentTarget.x = p.x; evt.currentTarget.y = p.y; } function dragMc(evt) { var p = this.parent.globalToLocal(evt.stageX, evt.stageY); evt.currentTarget.x = p.x; evt.currentTarget.y = p.y; }
Mittels drag and Drop lässt sich auch auf einfache Weise ein Schieberegler erstellen. Dazu braucht man lediglich einen Button in einem Movieclip, den man horizontal verschiebt. Mit der Position des Buttons wird der Wert des Sliders generiert. Alles weitere im
Beispiel dragDrop/ slider/slider.fla
Im folgenden Beispiel wird eine Zeitleiste per stop und play Button abgespielt und außerdem kann man mit einem Slider die Bilder der Zeitleiste aufrufen.
Beispiel dragDrop/ slider / slider1.fla
Hier wird ein MC auf der Bühne mit einem Slider skaliert.
Beispiel Slider Skalierung
In meinen Beispiel zum Download befindet sich der Ordner dragDropTween mit einigen Schritt für Schritt Beispielen, die zu dem folgenden Beispiel führen. Es ist fast schon ein fertiges Spiel. Ein Objekt fliegt in die Bühne man kann es anklicken und verschieben. Wenn man es loslässt fällt es nach unten.
Wenn man irgendeine Funktion mittels eines Events aufrufen will, beispielsweise über einen Click auf ein DisplayObjekt (Button, Movieclip etc.) ist es das einfachste, die Codefragmente aufzurufen. (Html5 Canvas/ Ereignisprozeduren / MouseClick). Es wird ein EventListener zugewiesen Siehe dazu auch meine Tipps in AS3 das ist sehr ähnlich. Ab AnimateCC 2019 gibt es alternativ auch die Assets im Actionsfenster.
Ein EventListener hat mindestens 2 Parameter
1) Das Ereignis z.B. "click"
2) Eine Referenz auf eine Funktion oder eine anonyme Funktion
Referenz auf eine Funktion. Hier werden keine Klammern angegeben.
this.myMc.addEventListener("click", warnung); function warnung(){ alert("Achtung Achtung"); }
Das gleiche Beispiel mit einer anonymen Funktion mehr dazu
this.myMc.addEventListener("click", function (){ alert("Achtung Achtung"); });
Vergleiche beide Beispiele, warnung wurde durch die anonyme Funktion ersetzt
Der Event hat ein Event-Objekt, welches Eigenschaften des Events liefert. Eigenschaften sind beispielsweise, der Eventtyp ("click", "mouseover") oder auf welches Objekt der Event registriert ist (currentTarget).
this.mcLila.on("click", moveMe ); this.mcBlue.on("click", moveMe ); function moveMe(evt){ evt.currentTarget.x += 10; console.log(evt); }
Beachte, dass die Funktion moveMe einen Parameter bekommen hat. Es ist ein frei vergebener Bezeichner, aber er hat in einer Event-Funktion eine ganz bestimmte Bedeutung, denn es ist ein Verweis auf das EventObjekt, über welches man bestimmte Eigenschaften des Events abfragen kann. Über console.log(evt) bekommt man diese Eigenschaften angezeigt, drücke im Browser F12.
Die Eigenschaft currentTarget
liefert das Objekt, welches angeklickt wurde. mehr dazu
Stattdessen könnte man hier auch mit this
auf das Objekt zugreifen, welches den Funktionsaufruf macht. Bei einem addEventListener ist currentTarget
nützlicher.
Ein weiterer Unterschied zu AS3 ist das angehängte bind(this)
wenn man aus den Codefragmenten einen Eventlistener zuweist. . mehr dazu unter bind
Siehe einige Event Beispiele
Bedenke, dass MouseEvents nur dann richtig funktionieren, wenn eine Maus vorhanden ist. Bei Smartphones ist das nicht der Fall, so werden mouseover und mouseout wie Click- Events behandelt. Mousemove-Events und Touch-Events benötigen die Zuweisung bestimmter Parameter siehe TouchEvent
Der Event added
wirkt ähnlich wie ein loader Event. Er greift wenn ein Objekt geladen ist, beispielsweise um einem Objekt schon beim Start eine Eigenschaft zuzuweisen.
this.r1.on("added", function () {document.getElementById("r1").checked = true; });
Wenn man einen Movieclip händisch auf die Bühne zieht und möchte, dass dieser sofort ein bestimmtes Bild seiner Zeitleiste ansteuert, so sollte man den Befehl nicht im ersten Frame einfügen sondern frühestens im zweiten, da man dann sicher sein kann, dass alle Frames des Movieclips geladen sind.
this.myMc.on("click", function() { this.x = 20;} );
In diesem Beispiel bezieht sich this
auf this.myMc, also das Objekt, welches die click Funktion aufgerufen hat. der zweite Parameter kann auch ein Verweis auf eine Funktion sein. Siehe dazu das Thema Javascript this
this.myMc.on("click", move); function move(){ this.x = 20;};
Siehe auch diesen Artikel im Netz. oder die EaselJS Dokumentation
Hier wird ein Event Listner auf ball_mc registriert. In der Eventfunktion "movetoMouse" kann man nicht mit dem Schlüsselwort this
auf this.ball_mc zugreifen, denn this
bezieht sich sich innerhalb einer globalen Funktion auf das globale Objekt und nicht auf die Bühne. Mittels bind()
kann man jedoch bestimmen, was innerhalb der Funktion als this angesehen wird. Siehe bind(this)
Nun folgt das Beispiel
this.ball_mc.addEventListener("tick", movetoMouse.bind(this));
function movetoMouse(){
var p = this.globalToLocal(this.stage.mouseX, this.stage.mouseY);
this.ball_mc.x += (p.x - this.ball_mc.x)/10;
this.ball_mc.y += (p.y - this.ball_mc.y)/10;
}
Irgendwo auf ein Element klicken, welches auf der Bühne liegt.
stage.addEventListener("click", myFunction);
Event Display Object anklicken, welches den Bezeichner myInstance hat.
this.myInstance.addEventListener("click", myFunction);
Mit currentTarget
, kann man auf das Objekt zugreifen, auf den der Event-Listener registriert ist. Beachte, dass man den Bezeichner event in der EventFunktion angeben muss.
function turnMc(event){....}
Hierbei ist event nur ein Bezeichner, der auch anders lauten kann.
function turnMc(evt){.....}
Beispiel 1 event/currentTarget1
this.a_mc.addEventListener("click", turnMc.bind(this));
this.b_mc.addEventListener("click", turnMc.bind(this));
this.c_mc.addEventListener("click", turnMc.bind(this));
function turnMc(event)
{
event.currentTarget.rotation += 20;
}
Im folgenden Beispiel wird an alle Objekte jeweils eine Variable angehängt. Diese kann man dann über currentTarget.meineVar in der Event-Funktion aufrufen. Mit diesem kleinen Trick spart man sich viel Schreibarbeit, denn diese Variable kann für alles mögliche eingesetzt werden.
Beispiel 2 event/currentTarget2
Sobald es mehrere Buttons oder Movieclips werden bietet sich an, eine For-Schleife einzusetzen.
Beispiel 3 event/currentTarget3
Im folgendem Beispiel liegen Movieclip- Instanzen auf der Bühne, darin sind Formgrafiken. Gleichfarbige Formen auf der gleichen Ebene werden als ein Objekt angesehen. Linien werden als ein Objekt angesehen.
Jede gruppierte Grafik kann man als target ansprechen. Das kann man anhand der Original-Fla gut ausprobieren. Ordner event/evt.target.fla
this.a_mc.addEventListener("click", showPara.bind(this));
function showPara(evt) {
this.anzeige.text = "evt.stageX " + evt.stageX + "\nevt.target.x " + evt.target.x;
evt.target.x += 10;
evt.currentTarget.y += 2;
}
evt.stageX, evt.rawX, evt.target, evt.currentTarget, evt.type
Überprüfe mit console.log(evt) was es für Eigenschaften des Event-Objekt es gibt
this.myMc.on("click", showMe ); function showMe(evt){ console.log(evt); }
myBtn.addEventListener("click", function(evt) {
//irgendwelche Anweisungen...
evt.remove(); // entfernt den listener.
});
oder man entfernt den Eventlistener auf gleiche Art wie man ihn erstellt hat. Am besten man ersetzt die Buchstaben add
durch remove
displayObject.addEventListener("click", handleClick);
displayObject.removeEventListener("click", handleClick);
Achtung! removeEventListener mit bind() kann man so nicht entfernen siehe nächstes Thema:
Im folgenden Beispiel wird der mouseout Befehl bei jedem mouseover Befehl verdoppelt. So ein Beispiel in einem Ticker würde Millionen von Events erzeugen. Achte auf console.log()
Achtung folgendes Beispiel nicht nachmachen!
stage.enableMouseOver(10); but.on("mouseover", function () { this.scaleX = 2; but.on("mouseout", function () { this.scaleX = 1; console.log("mouseout added"); }); });Im nächsten Beispiel werden Lösungen vorgestellt.
Setzt man den dritten Parameter eines Events auf true, wird der Event nach einmaligen Aufruf entfernt.
but.on("click", function(){ this.x += 20; }, null, true);
Wenn man einen Event einer Variablen zuweist kann man diesen mittels off
entferenen.
var clickButtonEvent = but.on("click", function(){ this.x += 20; but.off("click", clickButtonEvent); });
Mittels bind(this)
kann man bestimmen, was innerhalb der Funktion als this
angesehen wird.
Siehe dazu den Javascript Tipp this.
Schreibt man den Code in einen Frame außerhalb einer Funktion bedeutet this
die Zeitleiste in der man sich befindet. Das kann die Hauptbühne sein, oder ein Movieclip. Es hängt also immer davon ab, wo sich das Schlüsselbild befindet, in den man den Code einfügt.
Hat man einen Movieclip händisch aus der Bibliothek auf die Bühne gezogen, kann man ihn mit this.meinMc
ansprechen, sofern meinMc der Instanzname ist. Innerhalb einer globalen Funktion bezieht sich this immer auf das globale Objekt. Näheres dazu in meinem Javascript Tipp. Um auch innerhalb einer Funktion auf die Elemente der Bühne zuzugreifen, kann man bind(this)
an die Referenz einer Funktion anhängen. Das Argument in Klammern bestimmt, was innerhalb der Funktion als this
angesehen wird.
this.a_mc.addEventListener("click", turnMc.bind(this.a_mc));
this.b_mc.addEventListener("click", turnMc.bind(this.b_mc));
this.c_mc.addEventListener("click", turnMc.bind(this.c_mc));
function turnMc()
{
this.rotation += 20;
}
Siehe auch die Beispiele 10 bis 15, Thema Funktionen
Man kann einen Bound-Event-Listener jedoch nicht auf die Art entfernen, weil .bind eine neue Instanz zurück gibt, jedes mal wenn es aufgerufen wird. Möchte man den Event-Listener entfernen, muss man auf bind()
verzichten. In der folgenden Lösung wird die Variable _this = this;
außerhalb der Event-Funktion erzeugt, so kann man innerhalb der Funktion _this verwenden und erhält so Zugriff auf this
Dieser EventListener kann normal entfernt werden.
var _this = this; this.a_mc.addEventListener("click", turnMc); function turnMc() { _this.a_mc.rotation += 20; _this.a_mc.removeEventListener("click", turnMc); }
Eine andere Möglichkeit ist, mit evt.currentTarget
auf die aufrufende Instanz zuzugreifen. Auch das ist eine Möglichkeit, um auf bind(this)
zu verzichten, sofern man keinen Zugriff auf andere Elemente der Zeitleiste/ Bühne benötigt.
this.myBut.addEventListener("click", fl_MouseClickHandler); function fl_MouseClickHandler(evt) { alert("Mausklick erfolgt"); evt.currentTarget.removeEventListener("click", fl_MouseClickHandler); }
Wie oben erwähnt benötigt ein EventListener eine Referenz auf eine Funktion. Wie kann man eine Funktion nutzen die Parameter enthält. Hier gibt es verschiedene Möglichkeiten.
Wie schon oben erläutert kann man bind() nutzen um den Kontext für this zu bestimmen. Man kann an bind noch weitere Argumente anfügen, die werden an die Funktion weitergereicht.
this.go_btn.addEventListener("click", pushMe.bind(this, 50, 60); function pushMe(xPos, yPos){ this.go_btn.x += xPos; this.go_btn.y += yPos; }
Was in diesem Beispiel nicht funktioniert ist, dass man über den ersten Parameter von pushMe auf Ereignis-Infos zugreift, wie currentTarget, etc. xPos.currentTarget.x = xPos funktioniert nicht.
In einem Event-Listener eine Funktion mit Parametern aufrufen mittels einer Callback- Funktion ist jedoch ein bisschen kompliziert.
Um das zu verstehen studiere unbedingt zuerst das Thema Callback in meinen Javascript Tipps.
Dort wird erläutert, dass es doch möglich ist ein Funktion mit einem oder mehreren Parametern zuzuweisen wenn die Funktion eine anonyme Funktion zurückgibt.
Achtung Die hier vorgestellte Vorgehensweise kann Speicherlöcher erzeugen, wenn sie zu oft aufgerufen wird. Der Arbeitsspeicher, wird überlastet, weil die Variablen innerhalb der Funktion immer wieder neu erzeugt werden und nicht gelöscht werden können. In einem Tick-Event sollte man das nicht machen,
Dieser Sachverhalt soll nun mit einigen Beispielen untermauert werden. Sie befinden sich im Ordner Event
Beispiel call_1
this.myMc.addEventListener("click", function(evt){evt.currentTarget.x = 20;});
Hier wird anstatt einer Funktionsreferenz eine anonyme Funktion eingefügt.
Beispiel call_2
this.myMc.addEventListener("click", positionMe()); function positionMe(){ return function(evt){evt.currentTarget.x = 20;} }
Wie ich in meinen Javascript Tipp Callback Funktion erklärt habe, kann man einen Funktionsaufruf mit Klammern eingeben, sofern es eine Callback-Funktion ist, das heißt, sofern die aufgerufene
Funktion eine anonyme Funktion zurückgibt
Beispiel call_3
this.myMc.addEventListener("click", positionMe(200)); function positionMe(xPos){ return function(evt){evt.currentTarget.x = xPos;} }
Besonders praktisch ist die Tatsache, dass man auf diese Weise auch Parameter einfügen kann, die von der äußeren Funktion auf die anonyme Funktion übergeben werden
Beispiel call_4
this.lila.addEventListener("click", positionMe(140, 40)); this.blue.addEventListener("click", positionMe(40, 120)); function positionMe(xPos, yPos) { return function (evt) { evt.currentTarget.x = xPos; evt.currentTarget.y = yPos; } }
Seit Animate CC gibt es neue Textmöglichkeiten. Ein statischer Text wird beim Veröffentlichen in eine Grafik umgewandelt. Man kann ihn jedoch innerhalb der Arbeitsumgebung als normales statisches Textfeld nutzen.
Ein dynamischer Text lässt sich mit Schriftarten von Adobe Typekit oder Googlefonts einbetten.
Dazu muss man sich bei Adobe Typekit anmelden, als Nutzer der Creative Cloud entstehen keine weiteren Kosten. Google Fonts kann man auch ohne Anmeldung kostenlos nutzen.
Des weiteren klickt man bei ausgewählten Textfeld unter Schriftart im Eigenschaftenfenster auf das Globus Symbol und wählt dort eine oder mehere Typekit oder Google Schriftarten aus und klickt unten auf fertig.
Nun schließt man das Auswahlfenster. Nun muss man dem ausgewählten Textfeld die Schriftart im Eigenschaftenfenster noch zuweisen. Die ausgewählten Google- oder Typekit-Schriftarten erscheinen ganz oben in der Auswahlliste der Schriften.
Bei Typekit gibt man unter Einstellungen für Veröffentlichung unter "Webschriften" die Domain an, auf der die Seite veröffentlicht wird. Sollte eine Subdomain wie beispielsweise www nicht funktionieren, setze stattdessen ein Sternchen
*.on-design.de anstatt www.on-design.de
Man findet unter EaselJS einige Beispiele, darunter auch dieses hier, wobei ein Text mit einem Hintergrund versehen wird. Man erstellt ein Textobjekt. Man ermittelt mit getBounds das umgebende Rechteck. Dieses verwendet man für ein graphics Rechteck, welches einem Shape Object zugewiesen wird.
Siehe Beispiel / download
Siehe Beispiel Text mit Verlauf und Rand
Siehe auch das Thema Graphics / Füllung und Rand
Siehe auch Verlaufsfüllung
Javascript ist eine prototypenbasierte Sprache. Im Gegensatz zu Actionscript 3 welches objektorientiert ist. Javascript gleicht also mehr Actionscript 2 als Actionscript 3. In meinen Actionscript2-Tipps habe ich unter dem Thema OOP ein paar Möglichkeiten aufgezeigt, wie man einer Klasse Eigenschaften und Methoden mittels prototype anhängen kann. Siehe dazu auch meinen Javascript Tipp. Man kann mit Javascript keine eigenen Klassen erzeugen. Man kann einer Klasse jedoch Eigenschaften und Methoden anhängen.
Ich zeige hier Möglichkeiten, wie man einem Movieclip oder DisplayObject eine Prototype-Funktion hinzufügt, so dass alle Instanzen die Möglichkeit haben diese Methode aufzurufen. Damit schafft man Ordnung wenn die Programmierung etwas komplexer wird.
Im folgenden Beispiel befindet sich ein Movieclip in der Bibliothek mit dem Klassennamen Ball. Vergebe diesen Namen in der Bibliothek unter Verknüpfung, (doppelt anklicken), nicht zu verwechseln mit Name.
Erzeuge eine Instanz per Actionscript. (Es wäre auch möglich eine Instanz händisch auf die Bühne zu ziehen, und diese später mit this.Instanzname anzusprechen).
Ein Movieclip ist ein createjs.MovieClip. Diesem Object wird eine prototype Funktion angehängt. Dann kann jede Instanz von MovieObject diese Methode aufrufen.
balla = new lib.Ball(); this.addChild(balla); createjs.MovieClip.prototype.setPosition = function (x, y){ this.x = x; this.y = y; } balla.setPosition(150, 200);
Im folgenden zeige ich eine Navigation, die auf 2 Arten programmiert ist. Durch den Vergleich erkennt man sehr gut den Vorteil von prototype. Das Beispiel stammt ursprünglich aus meinen Actionscript 2 Tipps. Ein paar weitere Beispiele zeigen weitere Möglichkeiten auf.
Beispiel 1 / Beispiel 2 / Beispiel 3 / Beispiel 4
Im folgenden Beispiel wird eine Animation hinzugefügt.
balla = new lib.Ball(); this.addChild(balla); balla.y= 100; createjs.MovieClip.prototype.rolle = function (speed){ this.on("tick", function(){this.x +=speed;}); } balla.rolle(4);
Hier wird ein anderer Weg verfolgt. Die Klasse Rollschuh wird als Unterklasse des MovieClips Roller() erzeugt. Dann werden werden weitere Attribute und Methoden im Konstruktor der Rollschuhklasse erstellt. Siehe dazu meinen Flash 2 Tipp OOP oder meinen Javascript Tipp.
In der Bibliothek muss sich ein Movieclip befinden mit dem Verknüpfungsnamen Roller.
Rollschuh.prototype = new lib.Roller(); function Rollschuh(x, y, speed) { this.x = x; this.y = y; this.on("tick", function(){ if(this.x < 500){ this.x += speed; }else{ this.x = -50; } }); } rolli1 = new Rollschuh(100, 150, 5); this.addChild(rolli1); rolli2 = new Rollschuh(200, 50, 10); this.addChild(rolli2); rolli3 = new Rollschuh(40, 200, 2); this.addChild(rolli3);
Im folgenden Beispiel gibt es einen Movieclip in der Bibliothek mit dem Verknüpfungsnamen Snowflake. In dem Movieclip befinden sich mehrere Schlüsselbilder, in den sich verschiedene Grafiken von Schneekristallen befinden.
Dieses Beispiel funktioniert nur mit der call Funktion. Die erbende Klasse ruft mit call() die Konstruktorfunktion der Elternklasse auf. Siehe dazu meinen Javascript Tipp. In AS3 wird das mittels super() gemacht. Man braucht es, wenn man Argumente der Konstruktorfunktion der Elternklasse in der erbenden Klasse benötigt. siehe auch AS3 Tipp.
Das vorige Beispiel funktioniert auch ohne call. Die call Funktion wird vor allen Dingen dann benötigt, wenn man auf spezifischere Eigenschaften des Elternelemets zugreifen will, wie beispielsweise die Anzahl der Frames, die in diesem speziellen Bibliothekssymbol einen bestimmten Wert haben. Beim Initiieren wird ein zufälliges Bild dieser Zeitleiste aufgerufen.
Durch die call(this)
Funktion zeigt der Konstruktor-Pointer auf die Elternklasse also Snowflake. Das ist in diesem Falle egal, aber könnte in anderen Fällen zu ungewollten Effekten führen. Es lässt sich folgendermaßen ändern.
Snow.prototype.constructor = Snow;
So wird der Pointer auf das erbende Objekt gesetzt.
Snow.prototype = new lib.Snowflake();
Snow.prototype.constructor = Snow; function Snow(speed) { lib.Snowflake.call(this); this.x = Math.random() * 500; this.y = Math.random() * 300; this.gotoAndStop(Math.floor(Math.random() * this.totalFrames)); this.on("tick", function () { if (this.y < 400) { this.y += speed; } else { this.y = -50; this.x = Math.random() * 500 + 30; } }); } for (i = 0; i < 20; i++) { var star = new Snow(Math.random() * 5 + 3); this.addChild(star); }
Es gibt verschiedene Möglichkeiten eine programmierte Animation zu erzeugen.
Wähle einen Movieclip auf der Bühne aus und wähle dann im Codefragmente Fenster unter HTML5 Canvas, Animation, beispielsweise horizontal Animieren. Vergebe einen Instanznamen und schaue dir anschließend das Actionscript an, welches in einem Keyframe auf der Ebene Actions hinterlegt ist. Näheres dazu siehe unter dem Tipp Schlangenbewegung oder in meinen Flashtipps zum Thema programmierte Bewegung.
Es ist außerdem möglich über ein onTick Ereignis eine Animation zu erstellen oder irgendeine Anweisung in Schleife auszuführen. Siehe dazu folgendes Beispiel. Benötigt wird ein Movieclip auf der Bühne. Wähle diesen aus und vergebe im Eigenschaftenfenster ganz oben einen Instanznamen (Namensreglen beachten: keine Sonderzeichen außer Unterstrich nicht mit einer Zahl beginnen). In diesem Beispiel lautet der Instanzname myMc. Innerhalb der geschweiften Klammer sind weitere Anweisungen möglich, die durch Semikolon und neue Zeilen getrennt werden.
this.myMc.on("tick", function(){this.x +=5;});
Es gibt einen Movieclip "SnakeHead" und einen "Ball". Letzter ist ein Körperelement mit einer Animation.
var anzahl = 30;
var abstand = 15;
var ball = new Object();
ball[0] = new lib.SnakeHead();
ball[0].x = 500;
ball[0].y = 50;
this.addChild(ball[0]);
for(i = 1; i < anzahl; i++)
{
ball[i] = new lib.Ball();
ball[i].x = ball[i-1].x - abstand;
ball[i].y = 50;
ball[i].scaleX = 1 - i / anzahl;
ball[i].scaleY = 1 - i / anzahl;
ball[i].gotoAndPlay(i);
this.addChild(ball[i]);
}
//die zweite Schleife dient dazu die Stapelreihenfolge umzukehren
for(i = anzahl; i >= 0; i--)
{
this.addChild(ball[i]);
}
this.addEventListener("tick",mover.bind(this));
function mover()
{
var p = this.globalToLocal(this.getStage().mouseX, this.getStage().mouseY);
ball[0].x += (p.x - ball[0].x) / 10;
ball[0].y += (p.y - ball[0].y) / 10;
for (i = 1; i < anzahl; i++)
{
//horizontaler Abstand zum vorigen Element,
distX = ball[i - 1].x - ball[i].x;
//vertikaler Abstand zum vorigen Element
distY = ball[i - 1].y - ball[i].y;
//Abstand zum vorigen Element (Satz des Pythagoras a² * b² = c²)
dist = Math.sqrt(distX * distX + distY * distY);
//Verhältnis horizontaler Abstand zum wirklichen Abstand
cx = distX / dist;
cy = distY / dist;
//der gewünschte Abstand ist "abstand", der momentane Abstand ist "dist"
//Das Verhältnis horizontaler Abstand zu momenten Abstand ist "cx"
//Nun kann man anhand des Verhältnis cx den gewünschten X-Abstand ausrechnen
distX_new = cx * (abstand/(i*0.7)+5);
//auf gleiche Weise wird auch der gewünschte Y-Abstand errechnet
distY_new = cy * (abstand / ( i* 0.7)+5);
//Die neue Position wird gesetzt, der errechnete Abstand wird von der Position
//des vorigen Elementes abgezogen
ball[i].x = ball[i - 1].x - distX_new;
ball[i].y = ball[i - 1].y - distY_new;
}
}
Der Movieclip myMc vollzieht eine Kreisbewegung. Beispiel
siehe auch die Alternative mit Tweenjs Spiralbewegung
var xPos = 200; var yPos = 100; var radius = 50; var i = 0; var p2 = new createjs.Point(0, 0); this.addEventListener("tick", progRotate.bind(this)); function progRotate() { i += 0.09; p2.y = Math.cos(i) * radius + yPos; p2.x = Math.sin(i) * radius + xPos; this.myMc.x = p2.x; this.myMc.y = p2.y; }
Mittels Math.sin() erhält man einen Wert der zwischen -1 und +1 liegt. Damit lässt sich eine Sinuskurve oder eine Bewegung entlang einer Sinuskurve berechnen:
var i = 0; this.addEventListener("tick", moveZiel.bind(this)); function moveZiel() { this.ziel.x+=5; this.ziel.y = Math.sin(i += 0.09)*100+100; if(this.ziel.x > 1000){ this.ziel.x = - 50; } }
In diesem Beispiel dreht sich ein Movieclip wie eine Kompassnadel auf die Mausposition.
Siehe MDN Math.atan2.
Beispiel Trigonometrie / tg6
createjs.Touch.enable(stage); this.addEventListener("tick", progRotate.bind(this)); function progRotate() { //mp Mausposition var mp = this.globalToLocal(this.stage.mouseX, this.stage.mouseY); //horizonatler Abstand zur Maus var b = this.zeiger.x - mp.x; //vertikaler Abstand zur Maus var a = this.zeiger.y - mp.y; //var vTan = a / b; var arkusTanB = Math.atan2(a,b); //bogenmaß in Winkel var alpha = (arkusTanB / Math.PI) * 180; this.zeiger.rotation = alpha; }
Man kann mit Canvas eine Maskenebene erzeugen, die jedoch nicht soviel Möglichkeiten bietet wie in AS3.
Siehe Beispiel
Man kann auch eine Maske mit halbtransparenten Bereichen erzeugen siehe dazu Filter.
Im diesem einfachen Beispiel wird eine programmierte Maske erzeugt. Es ist kein Movieclip, der als Maske dient sondern ein Shape Objekt. Dieses Shape Objekt sollte nicht mit addChild() der Display Liste hinzugefügt werden. Der Movieclip ist dort sichtbar, wo der Bereichs der Maske ihn überschneidet. siehe Shape und Circle
var s = new createjs.Shape(); s.graphics.beginFill("#ffff00").drawCircle(100, 100, 100); this.myMc.mask = s;
Wenn die Maske mit der Maus verschiebbar sein soll, kann man folgenden Code verwenden. Auf der Bühne befindet sich ein MC myMc.
var s = new createjs.Shape(); s.graphics.beginFill("#ffff00").drawCircle(0, 0, 100); s.x = 200; s.y = 200; this.myMc.mask = s; this.myMc.addEventListener("pressmove", dragMe.bind(this)); function dragMe(evt) { var p = this.globalToLocal(evt.stageX, evt.stageY); s.x = p.x; s.y = p.y; }
Im folgenden Beispiel folgt ein MC Instanzname einem Pfad per Tweening. Der Pfad verläuft entlang einer Swirl-Grafik. Währenddessen werden per Programmierung Kreise gezeichnet und auf dem aktuellen Standpunkt des getweenten MCs positioniert.
var i = 1;
//siehe shape und graphics
var s = new createjs.Shape();
//die Methode mask ermöglicht es eine Maske zuzuweisen
this.floral_mc.mask = s;
this.addEventListener("tick", makeMask.bind(this));
function makeMask() {
i++;
//es befinden sich 101 Bilder in der Zeitleiste
if (this.currentFrame < 100) {
var circle_radius = 10;
//circ_mc ein unsichtbarer MovieClip tweent entlang dem Pfad
var xLoc = this.circ_mc.x;
var yLoc = this.circ_mc.y;
//es werden neue kreise gezeichnet mit x-y Position auf circ_mc
s.graphics.beginFill("#ffff00").drawCircle(xLoc, yLoc, 20);
} else {
this.removeEventListener('tick', makeMask.bind(this))
}
}
Ein Rectangle Objekt ist ein Rechteck, welches in vielen Situationen gebraucht wird. Man kann abfragen ob sich 2 Rechtecke überschneiden. Mittels getBounds kann man die Grenzen eines Objekts ermitteln. Siehe dazu diesen Beitrag im Netz.
Sowie diese Beispiele von mir:
Mit hitTest() kann man überprüfen, ob ein Display Objekt einen Punkt berührt. Siehe Dokumentation
In neueren AnimateCC-Versionen, wo das Canvas-Element in einer responsive Größe veröffentlicht werden kann, kommt es darauf an, die x und y Positionen richtig zu bestimmen.
Animate CC 2017 siehe diesen Forumsbeitrag
Siehe auch Touch Event
hitTest/hitTestPoint/hitTest1.fla
In diesem Beispiel wurde ein Movieclip händisch auf die Bühne gezogen und der Instanzname myMc zugewiesen. Im der Funktion checkHit() wird abgefragt, ob der MC den Punkt x: 300 und y:300 berührt. siehe auch localToLocal
Dieses Beispiel funktioniert auch dann, wenn bei einer responsive Veröffentlichung das canvas Element vergrößert wird.
var _this = this; this.addEventListener("tick", checkHit); function checkHit(event) { evt.preventDefault(); var pt = this.stage.localToLocal(300, 300, _this.myMc); if (_this.myMc.hitTest(pt.x, pt.y)) { _this.myMc.alpha = 0.2; } }
Im Download Ordner hitTest/hitTestPoint befinden sich weitere Beispiele nach dieser Vorlage. Dabei geht es darum, dass abgefragt wird, ob ein MC einen von mehreren Punkten berührt.
var _this = this; var punkt = []; punkt[0] = new createjs.Point(300, 300); punkt[1] = new createjs.Point(70, 140); punkt[2] = new createjs.Point(440, 160); this.myMc.addEventListener("pressmove", checkHit); function checkHit(evt) { //Verschiebung var p = _this.globalToLocal(evt.stageX, evt.stageY); evt.currentTarget.x = p.x; evt.currentTarget.y = p.y; for (var i = 0; i < punkt.length; i++) { if (hitPoint(punkt[i], evt.currentTarget)) { evt.currentTarget.alpha = 0.2; break; } else { evt.currentTarget.alpha = 1; } } } function hitPoint(p, mc) { var pt = this.stage.localToLocal(p.x, p.y, mc); if (mc.hitTest(pt.x, pt.y)) { return true; } else { return false } }
var shape = new createjs.Shape(new createjs.Graphics().beginFill("#ff0000").drawCircle(100, 100, 100));
this.addChild(shape);
this.addEventListener("tick", hitCheck.bind(this));
function hitCheck() {
var p = this.globalToLocal(this.stage.mouseX, this.stage.mouseY);
if (shape.hitTest(p.x, p.y)) {
shape.alpha = 1;
} else {
shape.alpha = 0.3;
}
}
In diesem Beispiel wurde eine MC Instanz händisch auf die Bühne gezogen und ihr der Instanzname laby_mc zugewiesen. In dem Mc befindet sich eine Formgrafik eines Labyrinths, die transparent wird, wenn man sie mit der Maus berührt. Achte auch auf die zweite Bedingung stage.mouseInBounds
. Hier wird überprüft ob sich die Maus innerhalb des Canvas Bereichs befindet.
this.laby_mc.addEventListener("tick", hitCheck.bind(this)); function hitCheck(evt) { var p = evt.currentTarget.globalToLocal(stage.mouseX, stage.mouseY); if (evt.currentTarget.hitTest(p.x, p.y) && stage.mouseInBounds) { evt.currentTarget.alpha = 0.3; } else { evt.currentTarget.alpha = 1; } }
Im folgendem Beispiel gibt es einen Movieclip auf der Hauptbühne, Instanzname holder. In diesem MC befinden sich lauter Kreisgrafiken. Es können einzelne Formgrafiken, oder Zeichnungsobjekte oder gruppierte Grafiken sein. Diese werden mittels getChildAt()
in einer For-Schleife angesprochen und auf hitTest Mausposition abgefragt. Damit das funktioniert kommt noch globalToLocal
ins Spiel. mouseInBounds
ermittelt, ob sich die Maus innerhalb des canvas Bereichs befindet.
Das Actionscript befindet sich im Schlüsselbild auf der Hauptbühne.
this.stage.enableMouseOver(50); createjs.Touch.enable(stage); this.addEventListener("tick", fl_hittest.bind(this)); function fl_hittest() { this.holder.rotation += 3; var l = this.holder.getNumChildren(); for (var i = 0; i < l; i++) { var child = this.holder.getChildAt(i); child.alpha = 0.3; var pt = child.globalToLocal(stage.mouseX, stage.mouseY); if (stage.mouseInBounds && child.hitTest(pt.x, pt.y)) { child.alpha = 1; } } }
Wie in Actionscript so gibt es auch in EaselJS die Methoden localToGlobal und globalToLocal, um Punkte von einem Koordinatensystem in ein anderes zu übertragen. In EaselJS gibt es außerdem localToLocal. Damit hat man die Möglichkeit aus 2 MCs Instanzen, die Koordinaten zu übertragen. Das vereinfacht das Ganze. Folgende Beispiele zeigen worum es geht.
Wenn man die Veröffentlichung responsive vornimmt, so dass die Bühne sich an die Größe des Browserfenster anpasst, funktioniert localToGlobal nicht mehr so wie erwartet. Nehmen wir an wir hätten einen Movieclip namens parentMc und darin befindet sich ein Movieclip childMc. Nehmen wir an parentMc wurde händisch auf die Bühne gezogen. Es geht darum die Position von childMc aus der Sicht oder aus dem Koordinatensystem der Bühne zu ermitteln. Dazu benutzte man dieses Codefragment. Die Parameter sind x und y Wert vom Registrierpunkt des Objekts.
this.parentMc.childMc.localToGlobal(0, 0);
Das Problem ist, dass die Werte, die man von localToGlobal bekommt von der Skalierung der Bühne beeinflusst werden, aber die Position der Objekte nicht. Mit folgender Funktion von RandomlyFish ist das Problem gelöst.
// Die Funktion function LocalToGlobal(_symbol) { var point = _symbol.localToGlobal(0, 0); //Die x und y Werte werden nicht von der responsive Vergrößerung beeinflusst //beziehungweise entsprechend der Bühnengröße umgerechnet point.x /= stage.scaleX; point.y /= stage.scaleY; return point; }
Beispiel
Im folgenden Beispiel gibt es den parentMc, darin liegt childMc. Außerdem gibt es den MC zeiger
parentMc und zeiger wurden händisch auf die Bühne gezogen. zeiger soll die Position von childMc einnehmen. Die Funktion LocalToGlobal bewirkt, dass x und y Werte nicht von einer responsiven Vergrößerung beeinflusst werden.
function LocalToGlobal(_symbol) { var point = _symbol.localToGlobal(0, 0); point.x /= stage.scaleX; point.y /= stage.scaleY; return point; } var globalPosition = LocalToGlobal(this.mcParent.mcChild); this.zeiger.x = globalPosition.x; this.zeiger.y = globalPosition.y;
Siehe auch Spiralbewegung Beispiele in Tween JS
In diesem Beispiel werden mehrere Instanzen der Klasse Elefant aus der Bibliothek auf die Bühne gebracht und einem Array zugewiesen. Neben den vorhandenen Eigenschaften x und y Position und Größe, habe ich einige weitere Eigenschaften oder Variablen mit Punktsyntax angehängt. speedX, speedY und eine boolsche Variable namens hit, die anzeigt, ob der Movieclip getroffen ist, oder nicht.
In der Funktion fl_hittest werden alle Elefant-Instanzen in einer for Schleife angesprochen. Mittels hitTest wird die Mausposition überprüft. Hier kommt globalToLocal ins Spiel. Die Variable hit wird auf true gesetzt und die Zeitleiste des Elefanten spielt ab.
In einer weiteren if Struktur wird die Variable hit abgefragt und entsprechende Anweisungen gegeben.
var ele = new Array(); for (var e = 0; e < 5; e++) { ele[e] = new lib.Elefant(); ele[e].gotoAndStop(0); //grösse und Geschwingkeit und Stapelreihenfolge simulieren Perspektive ele[e].speedX = 6 + 2 * e; ele[e].size = 1 + (e + 1) / 5; ele[e].scaleX = ele[e].scaleY = ele[e].size; ele[e].speedY = 1; ele[e].hit = false; ele[e].x = Math.random() * 1500; ele[e].y = Math.random() * 300 + 50; this.addChild(ele[e]); } this.addEventListener("tick", fl_hittest.bind(this)); function fl_hittest() { for (var i = 0; i < 5; i++) { var child = ele[i]; var pt = child.globalToLocal(this.bullet.x, this.bullet.y); if (stage.mouseInBounds && child.hitTest(pt.x, pt.y)) { child.play(); child.hit = true; this.bullet.y = -40; } if (child.x < 1800 && child.y > -50) { child.x += child.speedX; } else { child.x = Math.random() * -150 - 50; child.y = Math.random() * 300 + 50; child.gotoAndStop(0); child.hit = false; child.speedY = 1; child.scaleX = child.scaleY = child.size; } if (child.hit) { child.speedY *= 1.2; child.y -= 7 + child.speedY; child.scaleX = child.scaleY -= 0.02; } } /*bullet Bewegung*/ if (this.bullet.y > -30) { this.bullet.y -= 30; } /*insekt Bewegung*/ this.insekt.x = this.insekt.x + (stage.mouseX - this.insekt.x) * 0.2; abstand = Math.abs(this.stage.mouseX - this.insekt.x); if (abstand < 5) { this.insekt.stop(); } else { this.insekt.play(); } } //Ende von fl_hittest Funktion //insekt var hit = new createjs.Shape(); hit.graphics.beginFill("#000").drawRect(-400, -350, 800, 500); this.insekt.hitArea = hit; this.insekt.addEventListener("click", trigger.bind(this)); function trigger(evt) { this.bullet.x = this.insekt.x; this.bullet.y = 640; this.insekt.wurfarm.play(); }
Das folgende Beispiel bietet schon die Grundfunktion für ein kleines Spiel.
Ich habe auch eine einfache Variante erstellt. Beispiel 3a
Es gibt 3 Movieclips:
Wie unter Beispiel 3 werden einige Instanzen von Elefant erzeugt und einem Array zugewiesen. Diesen wird eine Bewegung zugewiesen und per hitTest wird abgefragt ob sie die Instanz bullet berühren. Der Elefant hat eine Bewegung in seinen Frames die abgespielt wird wenn er getroffen wurde.
Die Spinne nimmt die x Position der Maus ein in einer dynamischen Bewegung. Wenn man auf die Spinne klickt, wird die Kugel auf Position gebracht. Die Spinne hat außerdem noch ein hitArea. Dadurch vergrößert sich der anklickbare Bereich. Die Spinne hat eine Laufbewegung in ihren Frames. Wenn der Abstand der Spinne zur Maus kleiner ist als 5 Pixel, stoppt die Zeitleiste mit der Laufbewegung.
Die Kugel wird gestartet sobald man die Spinne anklickt. Sie bekommt eine Startposition anhand der Position der Spinne. Ansonsten fliegt die Kugel nach oben. sofern sie im unteren Bereich ist.
In der hitTest Funktion wird die Kugel aus dem Sichtbereich nach oben gesetzt.
var ele = new Array(); for (var e = 0; e < 5; e++) { ele[e] = new lib.Elefant(); ele[e].gotoAndStop(0); ele[e].speedX = Math.random() * 10 + 5; ele[e].speedY = 1; ele[e].hit = false; ele[e].x = Math.random() * 1500; ele[e].y = Math.random() * 400 + 50; ele[e].scaleX = ele[e].scaleY = 2 - e / 5 this.addChild(ele[e]); } this.addEventListener("tick", fl_hittest.bind(this)); function fl_hittest() { for (var i = 0; i < 5; i++) { var child = ele[i]; var pt = child.localToLocal(0,0, this.bullet); if (stage.mouseInBounds && child.hitTest(pt.x, pt.y)) { child.play(); child.hit = true; child.speedX = Math.random() * 20 - 10; this.bullet.y = -40; } if (child.x < 1800 && child.y > -50) { child.x += child.speedX; } else { child.x = Math.random() * -150 - 50; child.y = Math.random() * 400 + 50; child.gotoAndStop(0); child.speedX = Math.random() * 10 + 5; child.hit = false; child.speedY = 1; child.scaleX = child.scaleY = 2 - Math.random() * 1.2; } if (child.hit) { child.speedY *= 1.2; child.y -= 7 + child.speedY; child.scaleX = child.scaleY -= 0.02; } } /*bullet Bewegung*/ if (this.bullet.y > -30) { this.bullet.y -= 30; } /*spinne Bewegung*/ this.spinne.x = this.spinne.x + (stage.mouseX - this.spinne.x) * 0.14; abstand = Math.abs(this.stage.mouseX - this.spinne.x); if (abstand < 5) { this.spinne.stop(); } else { this.spinne.play(); } } //Ende von fl_hittest Funktion //Spinne var hit = new createjs.Shape(); hit.graphics.beginFill("#000").drawRect(-300, -350, 600, 500); this.spinne.hitArea = hit; this.spinne.addEventListener("click", trigger.bind(this)); function trigger(evt) { this.bullet.x = this.spinne.x; this.bullet.y = 536; this.spinne.waffe.gotoAndStop(0); } this.spinne.addEventListener("mousedown", abzug.bind(this)); function abzug(evt) { this.spinne.waffe.gotoAndStop(1); }
In den Beispielen zum Download befinden sich mehrere Dateien die eine Spielfigur-Steuerung für Jump And Run Spiele aufbauen. Zuerst wird eine Bewegung per Pfeiltasten ermöglicht. Dann kommt das Thema hitTest ins Spiel. Damit wird eine einfache Collision Detection ermöglicht, damit Hindernisse erkannt werden.
hitArea ist eine Eigenschaft des DisplayObjects. Damit lässt sich ein anklickbarer (sensitiver) Bereich erstellen. Dieser anklickbare Bereich entspricht nicht den Grafiken des DisplayObjekts sondern funktioniert genauso wie die Grafik im vierten Bild eines Button.
In einem Button wird im vierten Bild "Aktiv" eine Grafik händisch positioniert. Mit hitArea wird so eine Grafik per Javascript erzeugt. Dieses Graphic Object wird nicht der DisplayListe hinzugefügt, sondern der hitArea Eigenschaft eines DisplayObjects. Diese Graphik zeigt dann im lokalen Koordinatensystem des DisplayObjects seine Wirkung.
Man kann eine Graphic den hitArea Eigenschaften mehrerer Objekte zuweisen.
Achtung hitArea kann man nicht für hittest einsetzen wohl aber für getObjectsUnterPoint()
siehe auch den Download Ordner hitArea und den Ordner graphics/ move mit weiteren Beispielen
Diese Methode eines Containers liefert alle Objekte, die unter einem bestimmten Punkt liegen.
siehe EaselJS Doc Es wird ein Array zurückgegeben, welches alle Objekte enthält.
Siehe im Download Ordner unter dragAndDrop
this.getObjectsUnderPoint(p.x, p.y, 2);
Die ersten beiden Parameter sind x und y Position des Punktes.
Der dritte optionale Parameter ist der mode Parameter .
this.myMc.mouseEnabled = false;
this.addEventListener("click", myFunction);
this.mc.cursor = "pointer";
stage.enableMouseOver(10); createjs.Touch.enable(stage); this.form3.mouseEnabled = false; var elemente = new Array(); this.addEventListener("tick", getObjekte.bind(this)); function getObjekte(evt) { for (i = 0; i < elemente.length; i++) { elemente[i].alpha = 1; } var p = this.globalToLocal(this.stage.mouseX, this.stage.mouseY); elemente = this.getObjectsUnderPoint(p.x, p.y, 1); fLen = elemente.length; for (i = 0; i < fLen; i++) { elemente[i].alpha = 0.5; this.anzeige.text = fLen; } }
Im obigen Beispiel liegen einige Zeichnungsobjekte und Movieclips auf der Bühne. Das Textfeld this.anzeige zeigt, die Anzahl der Objects unter dem Punkt an. Ziehe den Mauszeiger auf die Grafiken. Der Movieclip mit Instanznamen form3 wird nicht berücksichtigt, weil
this.form3.mouseEnabled = false;
und der dritte mode Parameter auf 1 gesetzt ist.
getObjectsUnderPoint(x, y, 1);
Es gibt auch getObjectUnderPoint(), damit wird nur das oberste Objekt geliefert.
CreateJS bietet einige Möglichkeiten, eine Farbe zu definieren. Wenn Sie vorhandene Farbwerte verändern wollen, schauen Sie unter Filter/ Color Transform
"#ff00ff"
g1.beginFill("#fa00aa");
Hier ist A ein Transparenz- oder Alpahawert von 0-1.
"rgba(250, 0, 200, 0.5)"
g1.beginFill("rgba(100,0,255,1)");
"rgb(250, 0, 200)"
g1.beginFill("rgb(100,0,255)")
;
Mit der statischen Methode getRGB() kann man einen RGB Wert zuweisen. Der Alpha Wert ist optional. Beachte, dass es nicht getRGBA heißt. Die Methode steht nicht in Anführungszeichen.
createjs.Graphics.getRGB(250, 200, 40, 0.5)
g3.beginFill(createjs.Graphics.getRGB(100, 0, 255, 1));
getHSL(Farbton, Sättigung, Helligkeit, alpha) erzeugt einen HSL Farbwert: Farbton 0-360, Sättigung 0-100, Helligkeit 0-100, alpha (optional) 0-1
createjs.Graphics.getHSL(360, 100, 50, 0.8)
g4.beginFill(createjs.Graphics.getHSL(264, 100, 47, 1));
Mit Filter-Effekten kann man, Farbveränderungen, Weichzeichnungen, halbtransparente Masken etc. hinzufügen. Siehe die EaselJS Dokumentation Filter
In folgenden Beispielen zeige ich wie man Filter anwendet
Beispiel 1
Beispiel 2 blur mit getBounds
Beispiel 3 Alpha / halbtransparente Maske
Beispiel 4 Alpha als Spiegelung
Beispiel 5 color Transform, vorhandene Farben ändern
Wenn man einen MC auf der Bühne anklickt und im Eigenschaftenfenster unter Farbeffekt "Erweitert" wählt hat man einige Einstellmöglichkeiten, die vorhandenen Farbwerte zu ändern. Um das gezielt nutzen zu können, muss man das RGB Model verstehen.
Die Einstellmöglichkeiten im Eigenschaftenfenster entspechen den Werten des createjs.ColorFilter(). Die Zuweisung eines Filters geschieht nach dem Beispiel unter EaselJS Doc
Die ersten 3 Werte des Color Filters entsprechen Rot, Grün, Blau in Prozent. Damit kann man vorhanden Farbwerte verringern
Der 4te und der letzte Wert steht für Alpha, die Transparenz
Die Werte 5 bis 7 entsprechen den xR, xG, xB Werten von 0 bis 255.
näheres dazu in meinen Actionscript Tipps.
Die Cache Funktion erwartet die bounding Box des Objekts. (x-Registrierpunkt, y-Registrierpunkt, Breite, Höhe)
cache(Reg x, Reg y, Breite, Höhe);
Im folgenden Bespiel wurden Werte reduziert
Das geht besonders gut bei der Farbe weiß, da hierbei R, G und B auf 255 steht
Im Beispiel wurde Rot auf 70 Prozent reduziert
Grünwerte wurden auf 0 reduziert.
Blauwert auf 100 Prozent also 255.
Der Schwarze Rand bleibt wie er ist, da bei Schwarz alle 3 Werte 0 sind und es keinen Farbwert unter 0 gibt.
this.box_mc.filters = [
new createjs.ColorFilter(70, 0, 100, 1, 0, 0, 0, 0)
];
this.box_mc.cache(0,0, 130, 80);
Alternative Möglichkeit einen Filter zuzuweisen:
var myFilter = new createjs.ColorFilter(1, 1, 1, 1, 0, 0, 0, 0); myFilter.greenMultiplier = 0.5; myFilter.redOffset = -100; myFilter.greenOffset = 0; myFilter.blueOffset = 100; this.myMc.filters = [myFilter]; this.myMc.cache(-65, -65, 130, 130);
Der Filter erwartet folgende Parameter:
Der Betrag, der mit dem roten Kanal multipliziert werden soll. Dies ist ein Bereich zwischen 0 und 1.
Der Betrag, der mit dem grünen Kanal multipliziert werden soll. Dies ist ein Bereich zwischen 0 und 1.
Der Betrag, der mit dem blauen Kanal multipliziert werden soll. Dies ist ein Bereich zwischen 0 und 1.
Der Betrag, der mit dem Alphakanal multipliziert werden soll. Dies ist ein Bereich zwischen 0 und 1.
Der Betrag, der dem roten Kanal hinzugefügt werden soll, nachdem er multipliziert wurde. Dies ist ein Bereich zwischen -255 und 255.
Der Betrag, der dem grünen Kanal hinzugefügt werden soll, nachdem er multipliziert wurde. Dies ist ein Bereich zwischen -255 und 255.
Der Betrag, der dem blauen Kanal hinzugefügt werden soll, nachdem er multipliziert wurde. Dies ist ein Bereich zwischen -255 und 255.
Der Betrag, der dem Alphakanal hinzugefügt werden soll, nachdem er multipliziert wurde. Dies ist ein Bereich zwischen -255 und 255.
Wenn man die ersten 3 Multiplier Wert auf 0 setzt, kann man mit den Werten 4 (rot), 5(grün), 6 (blau) die Farbe festlegen, um das Objekt komplett einzufärben.
Wenn man ein schwarz-weißes Objekt hat, zum Beispiele weiße Flächen mit schwarzen Konturen wie bei Cartoons oder Comic Figuren, so kann man die weißen Flächen folgendermaßen einfärben. Die ersten 4 Werte bekommen den Wert 1. Die 3 RGB-Offset-Farben (Parameter 4 bis 5) bekommen minus Werte bis -255 aus denen sich die Farbe definiert. Man subtrahiert die Farben wie bei der subtraktiven Farbmischung.
Klickt man auf eine MC Instanz, findet man im Eigenschaftenfenster unter Filter "Farbe anpassen". Das ist der ColorMatrix Filter, mit dem man auf der Basis von HSL (Farbton, Sättigung, Helligkeit) die vorhandenen Farbwerte ändern kann.
var matrix = new createjs.ColorMatrix().adjustHue(180).adjustSaturation(100).adjustBrightness(100); this.myMc.filters = [ new createjs.ColorMatrixFilter(matrix) ];
In Version 2019 hat man die Möglichkeit Filter auf Ebenen anzuwenden. Dazu muss unter Modifizieren / Dokument / erweiterte Ebenen aktiviert sein. Siehe dazu diese Adobe Video und hier die Dokumentation
Achtung! Der Chrome Browser unterbindet Autoplay von Sound oder Video auf der Website. Da eine User Aktivität benötigt wird, könnte man beim Start einen Button zur Verfügung stellen, der Sound und Animation startet.
Ein AnimateCC HTML5 Canvas Dokument benutzt für die Soundprogrammierung das Framework SoundJS.
Die dort aufgeführten Beispiele werden direkt im HTML Dokument erzeugt, nicht in der AnimateCC Arbeitsumgebung. Man kann jedoch in der Zeitleiste von AnimateCC zuvor importierten Sound in Schlüsselbilder einfügen. Erzeuge ein Schlüsselbild in der Zeitleiste mit F6. Wähle es aus und wähle im Eigenschaftenfenster den gewünschten Sound aus. Der Sound muss vorher
siehe Api SoundJS Abstract Soundinstance Class
siehe auch meinen Javascript Tipp Sound
In der AnimateCC Arbeitsumgebung kann man folgendes machen. Suche den Sound in der Bibliothek aus (nicht doppelklicken) und vergebe unter Verknüpfung einen ID Namen. Das Eingabefeld ist schwer zu erkennen, es erscheint erst wenn man es doppelt anklickt.(Namensregeln beachten). Mit folgendem Befehl kann man eine Instanz des Sounds auf die Bühne bringen. Hier ist Gitarre der ID Name des Sounds.
var mySound = createjs.Sound.createInstance("Gitarre");
Achtung! Variablen die in der gesamten Zeitleiste ansprechbar sein sollen, sollte man folgendermaßen erzeugen:
this.mySound
Man kann auch einen Sound registrieren, der sich nicht in der Bibliothek befindet.
createjs.Sound.registerSound("sound.mp3", "soundId", 4);
Die Parameter bedeuten der Reihe nach:
Es gibt verschiedene Möglichkeiten den Sound abzuspielen. Im folgenden Beispiel wird ein zuvor erzeugtes Soundobjekt mittels der Methode play() abgespielt. Der Parameter ist ein ein PlayPropsConfig
Objekt in geschweifeten Klammern. Später mehr zu den einzelnen Eigenschaften.
mySound.play({interrupt:createjs.Sound.INTERRUPT_ANY, loop:-1, pan:0.5, volume:0.2});
Man kann die Parameter zum Abspielen eines Sounds auch in einer Instanz der PlayPropsConfig Klasse definieren und diese Instanz dann der play() Methode zuweisen.
var ppc = new createjs.PlayPropsConfig().set({interrupt: createjs.Sound.INTERRUPT_ANY,loop: -1}); mySound.play(ppc);
Oder man gibt als ersten Parameter die SoundId an.
Die SoundId wird entweder beim Registrieren des Sounds definiert, oder wenn es ein Sound ist, der in der Bibliothek liegt ist die SoundId der Verknüpfungsname.
createjs.Sound.play("SoundId", ppc);
Siehe Api PlayPropsConfig
Stoppt man den Sound und spielt ihn erneut ab, wird er vom Anfang gestartet. Wenn man stattdessen den Sound pausiert und ihn wieder startet, beginnt er bei der Position wo er stehengeblieben ist. Es ist nicht nötig, diese Position in einer Variablen zu speichern und beim Abspielen zuzuweisen.
var leadG = createjs.Sound.createInstance("Gitarre"); this.play_btn.addEventListener("click", playG.bind(this)); this.stop_btn.addEventListener("click", stopG.bind(this)); this.pause_btn.addEventListener("click", pauseG.bind(this)); function playG() { leadG.play({interrupt:createjs.Sound.INTERRUPT_ANY, loop:-1, pan:0, volume:0.2}); } function stopG() { leadG.stop(); } function pauseG() { leadG.paused = true; }
Die Lautstärke bestimmt man über die Eigenschaft volume mit einem Wert von 0 bis 1. Die Balance wird durch pan bestimmt mit einem Wert von -1 bis 1.
Lautstärke erhöhen.
mySound.volume += 0.05;
var mySound = createjs.Sound.createInstance("Gitarre"); var ppc = new createjs.PlayPropsConfig().set({ interrupt: createjs.Sound.INTERRUPT_ANY, loop: -1, volume: 0.5 }); this.play1_btn.addEventListener("click", play1.bind(this)); this.play2_btn.addEventListener("click", play2.bind(this)); this.stop_btn.addEventListener("click", stopG.bind(this)); this.plus_btn.addEventListener("click", volPlus.bind(this)); this.minus_btn.addEventListener("click", volMinus.bind(this)); function play1() { mySound.stop(); mySound = createjs.Sound.createInstance("Gitarre"); mySound.play(ppc); } function play2() { mySound.stop(); mySound = createjs.Sound.createInstance("Organ"); mySound.play(ppc); } function stopG() { mySound.stop(); } function volPlus() { mySound.volume += 0.05; } function volMinus() { mySound.volume -= 0.05; }
In den vorigen Beispielen wurde der Sound in Animate CC importiert. In diesen Beispielen wird der Sound aus einem Ordner geladen. Siehe dazu das Thema Sound Class, in SoundJS.
Achtung, die Beispiele funktionieren nur, wenn Sie von einem Server geladen werden.
In der Dokumentation sind einige Beispiele, die weitere Möglichkeiten eröffnen. Man kann eine alternative Sounddatei wählen, wie mp3 oder ogg. Man kann alternative Plugins wählen und diese auch zur Installation anbieten u.v.m
Mein Beispiel ist einfacher, aber somit auch eingeschränkter. Hier werden 2 Sounds geladen und abgespielt, nachdem der Ladevorgang abgeschlossen ist.
// assign load event handler
createjs.Sound.on("fileload", handleLoad);
// load and register sound (Pfad, ID, wie oft der Sound gleichzeitig abspielen kann)
// mehrere Sounds lassen sich alternativ mit registerSounds laden
createjs.Sound.registerSound("mukke/Bass.mp3", "soundID", 5);
createjs.Sound.registerSound("mukke/Drum.mp3", "soundID2", 5);
var audio1;
var audio2;
// play sound and start timeline playing
function handleLoad(event) {
audio1 = createjs.Sound.play("soundID");
audio2 = createjs.Sound.play("soundID2");
}
Weitere Eigenschaften und Methoden erlauben die Steuerung mehrer Sounds, Lautstärke, Balance, Pause, Stop, Play, Stummschaltung etc.
createjs.Sound.stop();
createjs.Sound.muted = true;
Mit der CSS Komponente hat man die Möglichkeit andere Komponenten mittels CSS zu formatieren. Ziehe eine CSS Komponente auf die Bühne vergebe einen Instanznamen. Erzeuge eine CSS Datei und speichere diese ab. Klicke auf die CSS Komponente und weise im Eigenschaftenfenster unter Quelle den Pfad zur CSS-Datei ein (Bleistift-Symbol).
Erzeuge eine Komponente und vergebe einen Instanznamen. Dieser Instanzname kann in der CSS Datei mit dem ID-Selektor angesprochen und formatiert werden. Beachte, dass nicht alle CSS Eigenschaften möglich sind. Einige Komponenten habe im Eigenschaftenfenster einen Klassennamen. Hierauf kann man über den Klassenselektor in CSS zugreifen.
Einige Komponenten sind HTML- Input Felder. Diese lassen sich mit CSS stylen, zum Beispiel:
input{font-size: 15px;}
Vergebe der Image Komponente einen Instanznamen und verweise im Eigenschaftenfenster unter Quelle auf ein Bild. Das Bild wird beim Veröffentlichen sowieso in einen Unterordner "images" verschoben. So dass man auch alle weiteren Bilder, die per Javascript in der Image-Komponente angezeigt werden, in diesen Ordner kopieren sollte.
Verweise mit folgendem Javascript auf ein Bild namens auto_2.jpg auf eine Image Komponente namens myImages.
$("#myImage").attr("src","images/auto_2.jpg");
Ein Vorteil der Image Komponente ist auch, das man diese über andere Komponenten platzieren kann. Einen händisch auf die Bühen gezogenen Button, könnte nicht über einer Videokomponeten liegen. Eine Image Komponente schon.
Siehe folgendes Beispiel
Beispiel im Ordner Komponente
/ Image
Vergebe der Label-Komponente einen Instanznamen und vergebe einen Text im Eigenschaftenfenster. Mit folgendem Javascript kann man den Text "Hallo Welt" der Label-Komponente mit Instanznamen myLabel zuweisen.
$("#myLabel").text("Hallo Welt");
Vergebe der Textinput Komponente einen Instanznamen. Der Zugriff auf den eingebenen Text erfolgt folgendermaßen, wenn der Instanzname der Input Komponente "myInput" ist.
var inputText = document.getElementById("myInput").value;
Siehe dieses Beispiel,
Beispiel im Ordner Komponente / Combobox
Siehe Video steuern mit Javascript
Siehe Video Tutorial
Man kann in EaselJS bzw. AnimateCC 2017 eine Video Komponente nutzen, um Sie mit HTML5 Canvas zu veröffentlichen. Siehe dazu auch mein VideoTutorial bei Youtube. In diese Videokomponente kann man über das Eigenschaftsfenster einen Pfad zu einem mp4-Video angeben,
Hierbei ist wichtig zu verstehen, dass das Video nicht innerhalb des Canvas-Elements liegt. Das Video liegt in einem HTML5 <video> Element und dieses wird über das Canvas-Element gelegt. Das hat zur Folge, dass es nicht möglich ist irgendetwas aus dem Canvas über der Videokomponente anzuzeigen, selbst wenn man die Videokomponente in die unterste Ebene legt. Auch eine Maskenebene hat auf das Video keinerlei Auswirkungen. Allenfalls andere Komponenten, wie die Image Komponente kann man darüber legen.
Man kann dieses Video mit einer integrierten Steuerungsleiste steuern, oder auch mit eigenen Buttons oder MovieClips pausieren und starten (die müssen außerhalb des Videorechtecks plaziert sein). In den Codefragmenten von Animate CC 2017 finden sich einige wichtige Befehle.
Ein Video mit dem Instanznamen myVideo kann man folgendermaßen abspielen und stoppen.
$("#myVideo")[0].play();
$("#myVideo")[0].pause();
Über die Eigenschaft
currentTime
kann man die Abspielzeit in Sekunden abfragen und die Eigenschaft duration
liefert die Gesamtzeit des Videos.
$("#myVideo")[0].currentTime
;
In dem obigen Beispiel wird das Video an festgelegten Zeitpunkten gestoppt und ausgeblendet. Gleichzeitig wird der Vorhang animiert und der Playbutton eingeblendet. Wenn das Video ausgeblendet wird, sieht man das darunterliegende Platzhalterbild oder Standbild, welches einen stehenden Frosch anzeigt. So entsteht der Eindruck das Video würde stoppen und nicht ausgeblendet. In Wirklichkeit ist einfach nur ein importiertes Bitmap. Bei einem komplexeren Video könnte man stattdessen auch für jeden Stop ein anderes Bild einblenden.
Ziehe 2 Radiobutton Komponenten auf die Bühne, vergebe beiden einen Instanznamen oben im Eigenschaftenfenster. z.B.: r1 und r2. Gebe unten im Eigenschaftenfenster
Klicke den ersten Button an und wähle aus den "Codefragementen" Komponenten, Benutzeroberfläche, Ereignis für Klick auf Kontrollkästchen. Mache das gleiche nochmal nachdem du den zweiten Button ausgewählt hast.
Erzeuge ein dynamisches Textfeld mit Instanznamen info.
Füge im Actionscriptfenster nach //Beginn des benutzerdefinierten Codes folgende Zeile ein:
this.info.text = "Bla bla";
Füge auch im Javascriptblock für den zweiten Button einen ähnlichen Text an gleicher Stelle ein.
this.info.text = "Blu Blub";
if(!this.r1_change_cbk) { function r1_change(evt) { // Beginn des benutzerdefinierten Codes console.log(evt.target.checked); this.info.text = "Bla bla"; // Ende des benutzerdefinierten Codes } $("#dom_overlay_container").on("change", "#r1", r1_change.bind(this)); this.r1_change_cbk = true; } if(!this.r2_change_cbk) { function r2_change(evt) { // Beginn des benutzerdefinierten Codes console.log(evt.target.checked); this.info.text = "Blu Blub"; // Ende des benutzerdefinierten Codes } $("#dom_overlay_container").on("change", "#r2", r2_change.bind(this)); this.r2_change_cbk = true; }
Man kann einen der Radiobuttons schon beim Start als ausgewählt (checked) anzeigen lassen. Im folgendem Codebeispiel ist r1 der Instanzname:
this.r1.on("added", function () { document.getElementById("r1").checked = true; });
Zahlenauswahlfeld- Komponente. Siehe folgendes Beispiel mit Erklärungen: Numeric Stepper
Man kann jedes beliebige HTML-Element in der Displaylist aufführen. Dazu stellt EaselJs ein DomElement Objekt zur Verfügung.
siehe Referenzen
Um das Element sollte im gleichen Html - Container liegen wie auch das Canvas Element, denn dann teilen sich beide Elemente die gleiche Positionierung. Auf der veröffentlichten HTML Seite gibt es ein umgebendes div mit der id animation-container in diesem Gültigkeitsbereich sollte das Html Element eingefügt werden.
Das Domelement liegt immer über dem Canvas. Man kann keinen Movieclip über dem Dom Element plazieren.
Achte beim Veröffentlichen darauf, dass du das eingefügte HTML Element nicht löschst. Einstellungen für Veröffentlichung / HTML überschreiben, sollte nach der ersten Veröffentlichung deaktiviert werden.
Beispiel unter domElement
In meinem Beispiel habe ich ein Bild mit der id="engel"
an besagter Stelle eingefügt.
Auf der Bühne gibt es noch ein Textfeld mit Instanznamen anzeige.
var htmlElement = document.getElementById("angel"); var domElement = new createjs.DOMElement(htmlElement); domElement.x = 20; domElement.y = 20; this.addChild(domElement); domElement.htmlElement.addEventListener("click", sagWas.bind(this)); this.anzeige.text = "click den Engel"; function sagWas(event) { this.anzeige.text = "Hallo"; }
In diesem Tipp zeige ich wie man mit Javascript auf Formularelemente zugreift.
Da innerhalb eines Canvas Dokumentes Javascript die Programmiersprache ist kann man selbstverständlich auch Jquery nutzen, wenn man die Bibliothek einbindet.
Unter https://code.jquery.com/ kann man sich den Einbindungscode kopieren, um ihn in den Head-Bereich der HTML-Seite einzufügen.
In der AnimateCC 2017 Version sind einige JQuery Komponenten in den Codefragmenten enthalten und auch einige Befehle, um Videos mit der Videokomponente zu steuern.
Aber auch mit der älteren Version kann man JQuery Effekte nutzen, wie in diesem Beispiel, wo das Canvas-Element nach Abspielen einer Tweening-Animation sich selbst ausblendet und ein anderes Div der HTML-Seite einblendet.
Achtung
Achtet in AnimateCC 2017 auf den Einbettungscode des Canvas-Elementes in der HTML-Seite. Hier muss auch der div-animation-container
ausgeblendet werden.
$( "#div-animation-container" ).slideUp( 1200 );
$( "#canvas" ).slideUp( 1200 );
Anstatt in einem Frame von Animate CC das Javascript einzufügen, kann man die CreateJS Bibliotheken auch ohne AnimateCC nutzen. Es kommt immer drauf an, was man macht.
Bilder kann in einem Canvas-Element einfügen, siehe dazu meinen Tipp HTML5/CSS3, Canvas
Wenn man mehrere Elemente vorausladen möchte, bietet sich die PreloadJS Bibliothek an.
Wenn man Sounddateien läd, bietet es sich an das Soundplugin zu laden:
var queue = new createjs.LoadQueue(); queue.installPlugin(createjs.Sound);
Zum besseren Verständnis habe ich ein paar Beispiele zusammengestellt.
Beispiel 1, Beispiel 2 , Beispiel 3, Beispiel 4,
Aufträge könnt ihr mir per Email schicken oder anrufen:
Hompage: https://www.pastorpixel.de