Why Does Turn.js Only Work Once in Meteor Application? - meteor

I want to integrate Turn.js in a meteor project, but come across a "small" problem ,
the script work well the first time I "load" the template , but wouldn't work when i come across the same template.
{{#if correspondances_readingMode}}
<script >
function loadApp() {
// Create the flipbook
$('.flipbook').turn({
// Width
width:922,
// Height
height:600,
// Elevation
elevation: 50,
// Enable gradients
gradients: true,
// Auto center this flipbook
autoCenter: true
});
}
// Load the HTML4 version if there's not CSS transform
yepnope({
test : Modernizr.csstransforms,
yep: ['../../lib/turn.js'],
nope: ['../../lib/turn.html4.min.js'],
both: ['css/basic.css'],
complete: loadApp
});
</script>
<style>
.page{
width:400px;
height:300px;
background-color:white;
line-height:300px;
font-size:20px;
text-align:center;
}
</style>
<div class="flipbook">
{{#each myPost}}
<div class="page">
{{{text}}}
</div>
{{/each}}
</div>
{{/if}}
All seems to go as if the script was only executed when the user come across the template the first time , but wouldn't launch again the second time.
I have try many thing, but I came to think it's because of the handlebar {{#if}}
P.s :
On chrome the second time it's loaded it doesn't show turn.js as a script :

I was running into the same problem. I figured that the width of the booklet was calculated before the containing div got its full width. I set a delay of 1 second after rendering and now it seems to work fine.
Template.menu.rendered = function(){
setTimeout(function() {
import '/imports/turn.min.js';
$(window).ready(function() {
$('#magazine').turn({
display: 'double',
acceleration: true,
gradients: !$.isTouch,
elevation:50,
when: {
turned: function(e, page) {
// console.log('Current view: ', $(this).turn('view'));
}
}
});
});
$(window).bind('keydown', function(e){
if (e.keyCode==37)
$('#magazine').turn('previous');
else if (e.keyCode==39)
$('#magazine').turn('next');
});
}, 1000);
};
`

Related

AngularJS ng-class updating content

I've got some code in AngularJS here working half percent (I will explain) :
<button ng-class="{'svgMinus-dark': isDarkTheme, 'svgMinus': !isDarkTheme}"></button>
I also tried another writing to say the same :
<button ng-class="{'svgMinus-dark': true-condition, 'svgMinus': !isDarkTheme}" href=""></button>
And I got exactly the same result (and problem). My problem is, when I do set isDarkTheme to true (working), the class doesn't edit instantly. I have to click on my button. And I don't know why, when the $scope edits itself, the class doesn't toggle instantly.
Why do I have to click to see the class of my true-condition (or false condition) update ?... Is there a way to force my ng-class update when my $scope.isDarkTheme toggle to true or false ?
thanks a lot in advance, I'm getting less and less hair haha
Here is a working example. It might not help you, but you can use it (copy it) to edit your question and create a snippet to demonstrate your code.
angular.module('myApp', [])
.controller('myCtrl', ['$scope', '$timeout', function($scope, $timeout) {
$scope.isDarkTheme = false;
$scope.toggleDarkMode = function() {
$scope.isDarkTheme = !$scope.isDarkTheme
};
$timeout($scope.toggleDarkMode, 2000)
}]);
div {
padding: 20px;
height: 100%;
}
.is-dark {
background: #111;
}
.is-dark h1 {
color: #ccc;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl" ng-class="{'is-dark': isDarkTheme}">
<h1>Toggle in 2 seconds</h1>
<button ng-click="toggleDarkMode()">Toggle dark mode</button>
</div>

Is there a way to make a css property reactive with vuejs #scroll?

I'm making a vuejs component in my project, and i need to create a zoom with scroll, in a div (like googlemaps).
<div #scroll="scroll">
<Plotly :data="info" :layout="layout" :display-mode-bar="false"></Plotly>
</div>
<style>
div {
transform: scale(property1);
}
<\style>
<script>
export default {
methods: {
scroll(event) {
},
},
created() {
window.addEventListener('scroll', this.scroll);
},
destroyed() {
window.removeEventListener('scroll', this.scroll);
}
}
</script>
How can i make a method that make the "property1" reactive? Or there is another way to zoom with scroll only the div?
you can bind a dynamic style object to your div which includes the transform property with a dynamic value (see docs for deeper explanation):
<div #scroll="scroll" :style="{ transform : `scale(${property1})`}">
<Plotly :data="info" :layout="layout" :display-mode-bar="false"></Plotly>
</div>
new Vue({
...
data() {
return {
property1: defaultValue
}
},
methods : {
scroll(e){
// e is the event emitted from the scroll listener
this.property1 = someValue
}
}
})
You can also add some modifiers in the template as shown in the documentation to reduce the method code (here we could be preventing the page from scrolling whenever the user will be scrolling while hovering this specific element):
<div #scroll.self.stop="scroll" :style="{ transform : `scale(${property1})`}">
<Plotly :data="info" :layout="layout" :display-mode-bar="false"></Plotly>
</div>

Polymer web-component-tester failing due to variant browser viewport sizes

I'm using the Polymer/web-component-tester to run automated tests of my components.
I've run into an issue where a component test will pass if run in isolation, but fail when run using a file glob - for example:
FAILS: wct components/**/test
SUCCEEDS: wct components/btn-component/test
After a fair bit of digging, I found the reason is the change in browser behaviour: in both cases the launched browser has two iFrames side-by-side, with the right one showing the test progress, and the left showing the component. The globbed test run results in a significantly narrower left (component) iFrame.
When using polymer-gestures to simulate mouse clicks, the narrower iFrame causes issues because it can often render a horizontal scrollbar and change a component's clickability.
The following is an example of a component & test that fails as described. It renders a Cancel button a few hundred pixels to the right.
Component
<link rel="import" href="../../bower_components/polymer/polymer.html">
<polymer-element name="btn-component" attributes="name">
<template>
<style>
:host {
display: block;
width: 400px;
}
</style>
<div layout horizontal>
<span flex></span>
<div id="cancel_button" on-tap="{{cancel}}">Cancel</div>
</div>
</template>
<script>
Polymer({
ready: function() {
console.log("btn-component component ready!");
},
cancel: function(event, detail, sender) {
console.log("Cancel Btn!", event, detail, sender);
this.fire('cancel_btn', {});
}
});
</script>
</polymer-element>
Test
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>btn-component Tests</title>
<script src="../../../bower_components/webcomponentsjs/webcomponents.js"></script>
<script src="../../../bower_components/web-component-tester/browser.js"></script>
<script src="../../../bower_components/polymer-gestures/test/js/fake.js"></script>
<link href="../btn-component.html" rel="import">
</head>
<body>
<btn-component id="component"></btn-component>
<script>
function runAfterEvent(eventName, element, callback) {
var listener = function(event) {
element.removeEventListener(eventName, listener)
callback(event.detail);
};
element.addEventListener(eventName, listener);
}
suite('<btn-component>', function() {
var c = document.getElementById('component');
var fake = new Fake();
test('hitting cancel fires cancel event', function(done) {
runAfterEvent('cancel_btn', c, function(event) {
assert.ok(1, "the cancel_btn event should be fired");
done();
});
var cancelBtn = document.querySelectorAll("btn-component /deep/ #cancel_button")[0];
console.log(cancelBtn);
setTimeout(function() {
fake.downOnNode(cancelBtn);
fake.upOnNode(cancelBtn);
}, 1000);
});
});
</script>
The fail happens trying to click the button.
I guess there's a variety of ways to approach resolving this - including in my own tests (e.g. checking the viewport size vs the element position and scrolling right before trying to simulate a click), but starts to get quite fiddly/fragile. A reasonable option might be to add a config to wct that specifies a minimum viewport size on the component iFrame.
Perhaps I'm missing some available configuration that could help here. Is there a recommended way to handle this scenario?
A simple solution is pretty obvious. I added the following to my test's index.html
<style>
#subsuites {
width: 600px !important;
}
</style>
The css used by the wct tool sets the width at 50% and nests frames when using file globs - resulting in progressive narrowing.

Can Meteor live changes have animations?

How does Meteor handle live changes? For instance I don't want changes to be instantaneous, but with some kind of animation of sorts. If we place the items being changed using css animations/transitions does this work? What about jQuery animations for older browsers?
Here is a working example of a simple animation with meteor.
The situation here is that we have a list of items. If the user clicks on any of those items the item will animate 20px to the left.
JS
//myItem
Template.myItem.rendered = function(){
var instance = this;
if(Session.get("selected_item") === this.data._id){
Meteor.defer(function() {
$(instance.firstNode).addClass("selected"); //use "instance" instead of "this"
});
}
};
Template.myItem.events({
"click .myItem": function(evt, template){
Session.set("selected_item", this._id);
}
});
//myItemList
Template.myItemList.helpers({
items: function(){
return Items.find();
}
});
Templates
<template name="myItem">
<div class="myItem">{{name}}</div>
</template>
<template name="myItemList">
{{#each items}}
{{> myItem}}
{{/each}}
</template>
CSS
.myItem { transition: all 200ms 0ms ease-in; }
.selected { left: -20px; }
Instead of using fancy CSS you can also animate with jQuery:
Template.myItem.rendered = function(){
if(Session.get("selected_item") === this.data._id){
$(this.firstNode).animate({
left: "-20px"
}, 300);
}
};
But then you need to remove the CSS code.
.myItem { transition: all 200ms 0ms ease-in; }
.selected { left: -20px; }
There is a workaround like this:
<template name="foo">
..content..
{{bar}}
</template>
In this case Meteor will call Template.foo.bar everytime this template gets rendered. So within this function you can do all kinds of Jquery or CSS3 animations (for example by adding a class to the templates div).
For CSS transitions, there are two options you can go with:
1. Reactively: the Meteor way
2. Directly: the jQuery way
Here is a working example:
http://bindle.me/blog/index.php/658/animations-in-meteor-state-of-the-game

Not having any luck with :hover, either with jquery or css

Neither seem to work right for me. Starting with query:
<script>
$(function() {
$("#button1").hover(function() {
$("#button1").animate({opacity: 0.5}, 500);
});
});
</script>
This causes the opacity to shift down, but it doesnt resume on mouseleave. Jquerys hover page says to put a in and out action like so:
.hover( handlerIn(eventObject), handlerOut(eventObject) )
so when i do this it just gives me both animations on mouse in and again on mouseout:
<script>
$(function() {
$("#button1").hover(function() {
$("#button1").animate({opacity: 0.5}, 500),
$("#button1").animate({opacity: 1}, 500);
});
});
</script>
So i gave up on that and tried mouseenter/mouseleave combo:
<script>
$(function() {
$("#button1").mouseenter(function() {
$("#button1").animate({opacity: 0.5}, 500);
});
("#button1").mouseleave(function() {
$("#button1").animate({opacity: 1}, 500);
});
});
</script>
It just sticks on the mouseenter animation. So i tried the css method:
<style>
a:hover {
opacity: 0.5;
}
</style>
<div>
<a id="button1" ><img src="Assets/button.png"></a>
</div>
Doesnt do jack. :shrug:
Try passing in the hover handlers in separate functions, like this:
$(function() {
$("#button1").hover(function() {
$("#button1").animate({
opacity: 0.5
}, 500);
}, function() {
$("#button1").animate({
opacity: 1
}, 500)
});
});​
I don't use jQuery, but the CSS example you've provided works perfectly for me. I just copied code from the example and swapped the image with one of my own.
Consider checking whether your browser (it's version) fully supports opacity. I'm using Firefox 12.0
nm, i give up. The only way ive gotten mouse events to work is by putting it directly within the element (onmouseup: onmousedown: etc...). I did get a:hover to work finally but theres no way to animate it without cutting out ie9 and below, so thats out of the question. At least theres a solution, no thanks to jquery.

Resources