Rendering an image in Konva.js with Vue.js works fine with desktop browsers but not with IOS Chrome or Safari - vuejs2

I have a particular issue and I'm hoping someone can point out what I'm not doing correctly. My original code is posted here: Solved:Vue.js Konva library to display a simple image, what am I missing?
.
What's happening is I'm displaying a single image with Konva successfully (see code), however when I try to view the same page using mobile IOS Chrome or Safari, nothing displays. It works fine in desktop OSX Chrome and Safari, but not on the mobile versions. I just get a blank area where normally I would see the image on my OSX browsers. I'm sure there may be a step I am missing. Furthermore another interesting issue on the OSX browsers is that when I bring up the page to display the image initially it is blank until I do a page refresh, then it displays. Now maybe this is Vue.js and not Konva. However I thought I would point that out if anyone has further insights. Any suggestions would be greatly appreciated.
[Updated: Got it working] - Ok, I've done some testing and this is what I found out that seemed to solve the issue. After research, the biggest issue related to this is somewhere during the lifecycle the image is not attached to the dom before it is rendered. Even though I am doing image.src during the mounted stage which is the same as ".ready()" from what I understand. I even tried loading the image using the updated stage in Vue. Same issue. What worked was I used v-if to hide the Konva stage, then attached the source during mounted then ran v-if=true post image attachment to display the Konva stage and Bingo! everything works. It even works on the IOS browsers.
<template>
<div id="app">
<h1>Display Image via Konva</h1>
<div v-if=ShowStage>
<v-stage ref="stage" :config="configKonva">
<v-layer ref="layer">
<v-image :config="configImg"></v-image>
</v-layer>
</v-stage>
</div>
</div>
<script>
import Vue from 'vue';
import VueKonva from 'vue-konva'
Vue.use(VueKonva)
export default {
data() {
return {
ShowStage: false,
testImg: new Image(),
configKonva: {
width: 500,
height: 500
}
},
computed: {
configImg: function() {
return {
x: 20,
y: 20,
image: this.testImg,
width: 200,
height: 200,
}
}
},
mounted() {
this.testImg.src = "https://konvajs.github.io/assets/lion.png"
this.ShowStage = true
}
}
</script>

I am experiencing the same issue right now.
Locally it seems to work on IPhone with Safari but deployed to the Server it is not working anymore.
However did you try something like this?
const image = new Image()
image.src = url
image.crossOrigin = 'anonymous'
image.onload = () => {
new Konva.Image({image: image})
// Further code ...
}
The crossOrigin set to anonymous helped me at least partly.

Related

Barba.js Transitions No error in console. Transition still not running how do I fix this?

So I started playing around with Barba the other day, I successfully made a sample project with the same out line Im using now except on this project the transition would start on my second page with the third page to slide in. This is not working.
These are the steps I did :
CDN and js page tags at the bottom
wrapped my text in the barba wrappers
3.slide-in & keyframes animation on the css
Initialize the dom
inserted JS code
No errors are being thrown in the console but no transition is working here is my code
network page (2)
<div class="Page2">
<h1>Welcome to the Networking </h1>
About
BACK HOME
</div>
</div>
**Page 1 is Exactly the same , both pages share the same CSS page and JS page and all reside in the same folder.
My CSS reads like this :
.slide-in{
animation: slide-in 0.5s ease forwards;
}
#keyframes slide-in{
from{
transform: translateX(100%);
visibility: visible;
}
to{
transform: translateX(0%);
}
}
My javascript is as follows:
(function(Barba, $){
document.addEventListener("DOMContentLoaded", function(event) {
console.log('pjax start');
Barba.Pjax.start();
Barba.Prefetch.init();
var FadeTransition = Barba.BaseTransition.extend({
start: function() {
/**
This function is automatically called as soon the Transition starts
this.newContainerLoading is a Promise for the loading of the new container
(Barba.js also comes with an handy Promise polyfill!)
*/
// As soon the loading is finished and the old page is faded out, let's fade the new page
Promise
.all([this.newContainerLoading, this.fadeOut()])
.then(this.fadeIn.bind(this));
},
fadeOut: function() {},
fadeIn: function(){
this.newContainer.classList.add("slide-in");
var that = this;
this.newContainer.addEventListener("animationend", function(){
that.newContainer.classList.remove("slide-in");
that.done();
});
}
});
});
Barba.Pjax.getTransition = function () {
return FadeTransition;
};
});

How to properly load Bootstrap5's Masonry into Nuxt?

I am trying to use the Masonry plugin with Bootstrap5 and NuxtJS. When I follow the example here
https://getbootstrap.com/docs/5.0/examples/masonry/ and incorporate it into my own codesandbox, I notice that my demo is not in the correct masonry format. See the gaps? My sandbox
My example:
Bootstrap's example:
What do I need to do to get my demo into format shown on the Bootstrap Masonry example page?
I checked how to load the script from a CDN either globally or locally. It was working but at one condition: you needed to NOT start on the masonry page.
Meaning that if you loaded the app on a specific page, then moved to the one with the masonry it was working. But not if you started on this specific page. So, a pretty subpar solution.
This article was really helpful to understand how to wait until the CDN script is fully loaded: https://vueschool.io/articles/vuejs-tutorials/how-to-load-third-party-scripts-in-nuxt-js/
Then I realized that we are far better installing it directly as an NPM dependency. Therefore, I proceeded to the masonry repo. Found a great message on how to setup the whole thing in Nuxt.
And after a removal of some useless stuff and some modern dynamic import, here we are
<template>
<main>
<h1>Bootstrap and Masonry</h1>
<div class="row" id="masonry">
<!-- ... -->
</main>
</template>
<script>
export default {
async mounted() {
if (process.browser) {
let { default: Masonry } = await import('masonry-layout')
new Masonry('#masonry', { percentPosition: true })
}
},
}
</script>
The final solution is looking pretty well and there is not a lot of code. On top of that, the code is properly loaded. And you can load it on a click or any other event.

attribute binding in vue 3

I'm new to Vue and currently trying to dynamically change the video or image source link by passing the data in through a prop. I created a component with specific template structure that I would like to pass in the source from the main app.js page. I've tried binding it in both areas but unsure if I'm doing it correctly. I tried using regular divs and stuff to embed the video in app.js and it shows the content perfectly.
parent element contains 'Video' component-
<Video theme="IL" :vidSrc="srcIL.vid"></Video>
import Video from "./components/Video.vue";
export default {
name: "App",
components: {
Video
},
data() {
return {
srcIL: {
vid: "./assets/invi-lines/invisible-lines-film.mp4"
}
};
}
child 'Video component'
<template>
<div class="introVid top">
<video controls :src="vidSrc"></video>
</div>
</template>
<script>
export default {
props: ["theme", "vidSrc"]
};
</script>
This seems like you have it set up properly, and it is hard to know exactly what is causing the issues from the info provided, but I'm going to make a guess that it might be that the asset is not getting bundled.
I tried using regular divs and stuff to embed the video in app.js and it shows the content perfectly
I suspect you had something like:
<video controls src="./assets/invi-lines/invisible-lines-film.mp4"></video>
which would have taken the resource from the assets and packaged it for use.
see relative-path-imports for details.
You can try forcing these to load using require somewhere in the project, which will force the compiler to copy the asset, but really, if you have dynamic assets (assuming there's more than a handful and they can change) you should have them in the public folder already, not in the source folder. So my recommendation is that you move the dynamic assets to the public folder (assuming that was your issue to begin with)

DRY for displaying meteor templates for different urls

I am having trouble setting up a simple website with different webpages and staying DRY.
I have everything set up so I the last fragment of the url is the name of the template that needs to be loaded in the content part of the webpage. All I want to do now is load that template in a specific location based on the url.
In any examples, they do this:
{{#if showCreateDialog}}
{{> createDialog}}
{{/if}}
{{#if showInviteDialog}}
{{> inviteDialog}}
{{/if}}
I'd like to do something along the lines of
{{> {{template_name}} }}
Sadly, that doesnt work. I tried this as well:
{{{content}}}
Template.content.content = function () {
var url_frag = Session.get("url_frag");
return Template[url_frag]();
}
This didnt work either. Please help!
Edit:
hmm. perhaps, my error is not in loading the template but in capturing the url:
var TodosRouter = Backbone.Router.extend({
routes: {
"*url": "main"
},
main: function (url) {
Session.set("url", url.split('/'))
}
});
The error I am getting arises when url_frag is undefined...
var url_frag = Session.get("url_frag");
initially, this works, but upon changing webpages, it fails...
Solved. I just left backbone out of it
Template.content.content = function () {
var url = window.location.pathname.split('/');
var url_frag = url.pop()
return Template[url_frag]();
Then in the html:
<template name="content">
{{{content}}}
</template>
You could also try the router smart package at atmosphere, which also supports complex routes and filters.
https://atmosphere.meteor.com/package/router
Install meteorite using npm install -g meteorite
Install router using mrt add router
Add {{renderPage}} to body
Tada! /login now renders {{> login}}
Read the document here: https://github.com/tmeasday/meteor-router

Flowplayer in jQuery UI tabs in IE keeps playing video in inactive tab

I have been working on a mediaplayer with playlist using flowplayer in combination with jQuery tabs. But I run into issues with IE where when I switch tabs it still keeps playing the video in the closed tab. This does not happen in firefox or chrome, only in IE.
You can checkout my demo here
I was browsing the flowplayer forums and someone posted a solution, but the persons solution was not using jQuery UI, instead he was using jQuery Tools. So I am trying to figure out how to implement it in jQuery UI. I did not get any help from the flowplayer forums, so I thought I'd try in here.
This is the code the person used to supposedly solve the issue in jQuery Tools (forum post) I tried this using jQuery Tools and it didn't work completely.
incomplete jQuery Tools solution:
$(function() {
var api = $(".items").tabs(".tabs-cont").data("tabs");
api.onClick(function(index) {
var video = api.getCurrentPane().find("div.video"),
videoCont = video.find("div.video-cont");
videoCont.detach();
video.append(videoCont);
});
});
html:
<div class='video'>
<div class="video-cont"><object>FLASH EMED HERE</object></div>
</div>
I was able to figure something out on my own. Don't know if there is a better way of doing it, but it did solve my problem.
$( "#tabs" ).tabs({
show: function(e, ui) {
$.cookie( "tab-name", ui.panel.id );
},
select: function (e, ui) {
var tab = "#" + $.cookie ( "tab-name");
var video = $( tab ).find("div.media-container"),
flow = video.find("div.flow-container").attr('id');
$f(flow).stop();
}
});