Dynamic transition component VueJS 2 - components

I would like to be able to switch between transition A and B dynamically
Parent component
<child></child>
Child component
Transition A
<transition name="fade">
<p v-if="show">hello</p>
</transition>
.fade-enter-active, .fade-leave-active {
transition: opacity .5s
}
.fade-enter, .fade-leave-to /* .fade-leave-active in <2.1.8 */ {
opacity: 0
}
Transition B (using animate.css library)
<transition
name="custom-classes-transition"
enter-active-class="animated tada"
leave-active-class="animated bounceOutRight"
>
<p v-if="show">hello</p>
</transition>

You can do the dynamic transition with properly assigning the enterClass and leaveClass. Here is the working demo: https://fiddle.jshell.net/j9h3Lmr5/1/
JS:
var vm = new Vue({
el: '#vue-instance',
data: {
show: true,
transitionType: "fade",
enterClass: "fade-enter",
leaveClass: "fade-enter-active"
},
methods: {
changeTransition() {
if (this.transitionType === "fade") {
this.transitionType = "custom-classes-transition"
this.enterClass = "animated slideInUp"
this.leaveClass = "animated slideOutDown"
} else {
this.transitionType = "fade"
this.enterClass = "fade-enter"
this.leaveClass = "fade-enter-active"
}
}
}
});

Related

update page content

I have a morris chart that compares different students statistics. I also have a modal in which I can add a new student and the graph should update with new student statistics. After adding, the graph is getting updated but only when I refresh the whole page. How would I update the page without refreshing?
component.ts
ngOnInit() {
this.getData();
}
getData() {
this.http.get('url')
.subscribe(data => {
const graphData = data.stathistory;
const graphDataArr = [];
let currentChar = 'a';
for (const graphdata in graphData) {
const curDate = graphdata.replace(/(\d{4})(\d{2})(\d{2})/g, '$1-$2-$3');
const graphdataObj = { 'y': curDate };
for (const element in graphData[graphdata]) {
graphdataObj[currentChar] = Number(graphData[graphdata][element].rank);
currentChar = this.nextChar(currentChar);
}
graphDataArr.push(graphdataObj)
currentChar = 'a';
}
const yKeysArr = [];
for (let i = 0; i < data.domains.length; i++) {
yKeysArr.push(currentChar);
currentChar = this.nextChar(currentChar);
}
this.generateChart(graphDataArr, data.names, yKeysArr);
});
}
generateChart(graphRanks = [], names = [], yKeys = []) {
this.graphData = graphRanks;
this.graphOptions = {
xkey: 'y',
ykeys: yKeys,
labels: names,
resize: true,
parseTime: false,
pointSize: 0,
};
}
addStudent(name) {
this.http.post('url', {
name: name,
})
.subscribe(response => {
this.getData();
}
);
}
html
<div *ngIf = 'graphData' mk-morris-js [options]="graphOptions" [data]="graphData" type="Line" style="height: 500px; width: 100%;">
**code for modal dialog**
<button type="button" class="btn btn-primary" (click)="addStudent(name)">
Please let me know if more info is needed.
This looks fine. I would suggest you to add console.log(graphRanks); just before this.graphData = graphRanks; to ensure that the new data is loaded when expected. By the way your button calls the function addDomain(name) while in your script the function name is addStudent(name).
I would recommend that you make your graphData an observable and use the async pipe in your html. Something like this:
graphData$ = this.http.get('url').pipe(
map(x => // do stuff with x here)
)
Then, in your html you can make:
[graphData]="graphData$ | async"
Here is a good post by Todd Motto on the ng-if piece:
https://toddmotto.com/angular-ngif-async-pipe
EDIT:
If you don't want to make your graphData an observable - you could probably use a switchMap in you addStudent function.
addStudent(name) {
this.http.post('url', {
name: name,
})
.pipe(
switchMap(x => this.getData())
}
);
}
I finally got it working. I tried to clear the morris chart and generate the chart with new data. So, whenever there is a data change, it would clear the graph and redraw the graph with new data.
Clearing the chart
document.getElementById('idofthegraph').innerHTML = '';
This would draw the chart again
this.generateChart(graphDataArr, data.names, yKeysArr);

Using AnmiateCC html5 output with Haxe

Because FLASH is Dead I have a mission to convert some games to work as html5.
Graphics and animation is made on timeline in AnimateCC.
Until now the process looks like: publish to swc/swf, FlashDevelop -> AddToLibrary and I've access to all the objects.
When publish target is HTML5 canvas I have two files:
testHaxe.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>testHaxe</title>
<script src="https://code.createjs.com/createjs-2015.11.26.min.js"></script>
<script src="testHaxe.js"></script>
<script>
var canvas, stage, exportRoot;
function init() {
canvas = document.getElementById("canvas");
images = images||{};
var loader = new createjs.LoadQueue(false);
loader.addEventListener("fileload", handleFileLoad);
loader.addEventListener("complete", handleComplete);
loader.loadManifest(lib.properties.manifest);
}
function handleFileLoad(evt) {
if (evt.item.type == "image") { images[evt.item.id] = evt.result; }
}
function handleComplete(evt) {
exportRoot = new lib.testHaxe();
stage = new createjs.Stage(canvas);
stage.addChild(exportRoot);
stage.update();
createjs.Ticker.setFPS(lib.properties.fps);
createjs.Ticker.addEventListener("tick", stage);
}
</script>
</head>
<body onload="init();" style="background-color:#D4D4D4;margin:0px;">
<canvas id="canvas" width="550" height="400" style="background-color:#FFFFFF"></canvas>
</body>
</html>
testHaxe.js
(function (lib, img, cjs, ss) {
var p; // shortcut to reference prototypes
lib.webFontTxtFilters = {};
// library properties:
lib.properties = {
width: 550,
height: 400,
fps: 24,
color: "#FFFFFF",
webfonts: {},
manifest: [
{src:"images/Bitmap1.png", id:"Bitmap1"}
]
};
lib.webfontAvailable = function(family) {
lib.properties.webfonts[family] = true;
var txtFilters = lib.webFontTxtFilters && lib.webFontTxtFilters[family] || [];
for(var f = 0; f < txtFilters.length; ++f) {
txtFilters[f].updateCache();
}
};
// symbols:
(lib.Bitmap1 = function() {
this.initialize(img.Bitmap1);
}).prototype = p = new cjs.Bitmap();
p.nominalBounds = new cjs.Rectangle(0,0,103,133);
(lib.в1 = function(mode,startPosition,loop) {
this.initialize(mode,startPosition,loop,{});
// Warstwa 1
this.instance = new lib.Bitmap1();
this.instance.setTransform(-2,-2);
this.timeline.addTween(cjs.Tween.get(this.instance).wait(1));
}).prototype = p = new cjs.MovieClip();
p.nominalBounds = new cjs.Rectangle(-2,-2,103,133);
// stage content:
(lib.testHaxe = function(mode,startPosition,loop) {
this.initialize(mode,startPosition,loop,{});
// Layer 1
this.instance = new lib.в1();
this.instance.setTransform(85,90,1,1,0,0,0,49.5,64.5);
this.timeline.addTween(cjs.Tween.get(this.instance).wait(1));
}).prototype = p = new cjs.MovieClip();
p.nominalBounds = new cjs.Rectangle(308.5,223.5,103,133);
})(lib = lib||{}, images = images||{}, createjs = createjs||{}, ss = ss||{});
var lib, images, createjs, ss;
I'm looking for a way to connect thouse files into haxe and access files on Stage or from library ex: new a1();
There are externs for createJS in haxeLib but I don't know how to use them with this output.
You can write externs for your generated lib, eg.:
package lib;
import createjs.MovieClip;
#:native("lib.B1")
extern class B1 extends MovieClip {
}
#:native("lib.testHaxe")
extern class TextHaxe extends MovieClip {
public var instance:B1;
}
Obviously that could be very tedious so I wrote a tool for it:
https://github.com/elsassph/createjs-def
And posted a complete example here: http://philippe.elsass.me/2013/05/type-annotations-for-the-createjs-toolkit/
However it's currently broken for recent versions of Animate CC because the JS output has changed - it needs to be fixed.

Jest/Jasmine .toContain() fails even though matching values are present

I'm writing a simple React application with a Button component, which looks like this:
import React, { Component } from 'react';
// shim to find stuff
Array.prototype.contains = function (needle) {
for (var i = 0; i < this.length; i++) {
if (this[i] == needle) return true;
}
return false;
};
class Button extends Component {
propTypes: {
text: React.PropTypes.string.isRequired,
modifiers: React.PropTypes.array
}
render() {
return(
<span className={this.displayModifiers()}>{this.props.text}</span>
);
}
displayModifiers() {
const modifiers = this.props.modifiers || ["default"];
if (modifiers.contains("default") ||
modifiers.contains("danger") ||
modifiers.contains("success")) {
// do nothing
} else {
// add default
modifiers.push("defualt");
}
var classNames = "btn"
for (var i = 0; i < modifiers.length; i++) {
classNames += " btn-" + modifiers[i]
}
return(classNames);
}
}
export default Button;
I then wrote this to test it:
it("contains the correct bootstrap classes", () => {
expect(mount(<Button modifiers={["flat"]}/>).html()).toContain("<span class=\"btn btn-flat btn-default\"></span>");
});
That code should pass, but I receive the following error message:
expect(string).toContain(value)
Expected string:
"<span class=\"btn btn-flat btn-defualt\"></span>"
To contain value:
"<span class=\"btn btn-flat btn-default\"></span>"
at Object.it (src\__tests__\Button.test.js:42:293)
Any ideas why this is not passing?
From the docs:
Use .toContain when you want to check that an item is in a list.
To test strings you should use toBe or toEqual
it("contains the correct bootstrap classes", () => {
expect(mount(<Button modifiers={["flat"]}/>).html()).toBe("<span class=\"btn btn-flat btn-default\"></span>");
});
But there is a better way of testing the output rendered components: snapshots.
it("contains the correct bootstrap classes", () => {
expect(mount(<Button modifiers={["flat"]}/>).html()).toMatchSnapshot();
});
Note that you will need enzymeToJson for snapshot testing using enzyme.

Angular2 :How to make a movable svg object with hammer.js?

i'm Working on an angular2 app, and i'm using hammer.js to make movable a simple rectangle svg object in the view of my component , the methode i uses consists on using the "pan action " of hammer which gives me the x and y position of every deplacing clich mouvement , and i'm affecting thos x and y into the x and y attribtes of my svg rectangle , the problem is that this affectation is not done even i'm seeing in the console the value of x and y of the action ,
any idea to pass the value of depalcement into the svg element postion ???
this is my code :
the view:
<div>
<svg class="simulation">
<rect id="test1" x="{{NX}}" y="{{NY}}" height="150" width="200"
style="stroke:#EC9A20;stroke-width: 15; fill: none"/>
</svg>
</div>
and the TS.file :
export class ContentComponent implements AfterViewInit{
static hammerInitialized = false;
public NX:any ;
public NY:any ;
ngAfterViewInit():any {
console.log('in ngAfterViewInit');
if (!ContentComponent.hammerInitialized) {
var myElement = document.getElementById('test1');//indiquer ici l'element
var animation = new Hammer(myElement);
animation.get('pan').set({direction:Hammer.DIRECTION_ALL})
animation.on("panleft panright panup pandown tap press",
(ev):any => {
myElement.textContent = ev.type +" gesture detected.";
console.log(ev);
this.NX=ev.center.x;
console.log("NX="+this.NX) // this show successfully the value of the action movement NX
this.NY=ev.center.y;
console.log("NY="+this.NY) // this show successfully the value of the action movement NY
}
);
ContentComponent.hammerInitialized = true;
}
else {
console.log('hammer already initialised');
}
console.log("NX="+this.NX); //here it shows me that NX is undefined
console.log("NY="+this.NY) //undefined too
}
}
that worked by not passing the hammer function as a static param
ngAfterViewInit() {
/////////////////////////////////////////////////
//reference à l'element svg
var myElement = document.getElementById('idsimulation');
var actionHammer = new Hammer(myElement);
//action pan
actionHammer.get('pan').set({direction:Hammer.DIRECTION_ALL});
//actionHammer.on("panleft panright panup pandown tap press",hammer);
//actionHammer.on('pan',hammer);
actionHammer.on('pan',ev => {
//console.log(ev);
console.log("X=" + ev.center.x);
console.log("Y=" + ev.center.x);
this.ParamService.dormant.X0 = (ev.center.x) - 200; //170
this.ParamService.dormant.Y0 = (ev.center.y) - 190; //150
// myElement.setAttribute("x", ev.center.x+200);
// myElement.setAttribute("y", ev.center.y+270);
});
//action pinch
actionHammer.get('pinch').set({enable:true});
actionHammer.on('pinch',ev =>{
console.log(ev);
})
}

How to define new icons with winjs commands?

How to use an icon which is not provided by WinJS? For example, use one from here.
The html looks like:
<div data-win-control="WinJS.UI.SplitViewCommand" data-win-options="{ label: 'Home', icon: 'home'}"></div>
The png image should be 20x20 pixels with a transparent background (https://msdn.microsoft.com/en-us/library/windows/apps/hh700483.aspx). The png is set as in javascript:
document.getElementById("thatFancyButton").style.backgroundImage = url('pathOfPNGImage');
so in your case it is (notice \' \' in url()):
<div data-win-control="WinJS.UI.SplitViewCommand" data-win-options="{ label: 'Home', icon: 'url(\'pathOfPng.png\')'}"></div>
You can also set one letter glyphs like icon: '©' and it will show it as icon.
Below is the snippet of the SplitViewCommand icon setting logic:
/// <field type="String" locid="WinJS.UI.SplitViewCommand.icon" helpKeyword="WinJS.UI.SplitViewCommand.icon">
/// Gets or sets the icon of the SplitViewCommand. This value is either one of the values of the AppBarIcon enumeration or the path of a custom PNG file.
/// </field>
icon: {
get: function () {
return this._icon;
},
set: function (value) {
this._icon = (_Icon[value] || value);
// If the icon's a single character, presume a glyph
if (this._icon && this._icon.length === 1) {
// Set the glyph
this._imageSpan.textContent = this._icon;
this._imageSpan.style.backgroundImage = "";
this._imageSpan.style.msHighContrastAdjust = "";
this._imageSpan.style.display = "";
} else if (this._icon && this._icon.length > 1) {
// Must be an image, set that
this._imageSpan.textContent = "";
this._imageSpan.style.backgroundImage = this._icon;
this._imageSpan.style.msHighContrastAdjust = "none";
this._imageSpan.style.display = "";
} else {
this._imageSpan.textContent = "";
this._imageSpan.style.backgroundImage = "";
this._imageSpan.style.msHighContrastAdjust = "";
this._imageSpan.style.display = "none";
}
}
},
If you happen to have errors with the background image size, modify win-commandimage class. I did this fix in styles to fit the image into button correctly:
.win-commandimage {
background-size:contain;
}

Resources