I'm stuck on an issue with the TUI Image Editor where the buttons don't work after using the loadImageFromURL function.
Currently, I load images from a gallery beneath the TUI editor with the exception of the first image using the scripts below:
My initialization
window.onresize = function() {
instance.ui.resizeEditor();
}
var instance = new tui.ImageEditor('#tui-image-editor', {
includeUI: {
theme: blackTheme, // or whiteTheme
menu: ['rotate'],
menuBarPosition: 'bottom'
},
loadImage: {
path: 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7',
name: 'Blank'
},
cssMaxWidth: 700,
cssMaxHeight: 500,
selectionStyle: {
cornerSize: 20,
rotatingPointOffset: 70
}
});
// Patch the loadImageFromURL of our tui instance instance:
instance.loadImageFromURL = (function() {
var cached_function = instance.loadImageFromURL;
function waitUntilImageEditorIsUnlocked(instance) {
return new Promise((resolve,reject)=>{
const interval = setInterval(()=>{
if (!instance._invoker._isLocked) {
clearInterval(interval);
resolve();
}
}, 100);
})
}
return function() {
return waitUntilImageEditorIsUnlocked(instance).then(()=>cached_function.apply(this, arguments));
};
})();
// Load an image and tell our tui imageEditor instance the new and the old image size:
instance.loadImageFromURL("{{ url('/') }}{{Storage::url('manifests/'.$images->first()->name)}}", "SampleImage").then(result=>{
instance.ui.resizeEditor({
imageSize: {oldWidth: result.oldWidth, oldHeight: result.oldHeight, newWidth: result.newWidth, newHeight: result.newHeight},
});
}).catch(err=>{
console.error("Something went wrong:", err);
})
/* instance.loadImageFromURL("{{ url('/') }}{{Storage::url('manifests/'.$images->first()->name)}}",'{{$images->first()->name}}').then(result => {
console.log('old : ' + result.oldWidth + ', ' + result.oldHeight);
console.log('new : ' + result.newWidth + ', ' + result.newHeight);
});*/
My script to select other images:
$(document).on('click', '.selectImage', function() {
var path = $(this).data('path');
$('#image_id').val($(this).data('image_id'));
instance.clearObjects().then(() => {
console.log('cleared');
instance.loadImageFromURL("{{ url('/') }}"+path,'name').then(result=>{
instance.ui.resizeEditor({
imageSize: {oldWidth: result.oldWidth, oldHeight: result.oldHeight, newWidth: result.newWidth, newHeight: result.newHeight},
});
console.log(result);
}).catch(err=>{
console.error("Something went wrong:", err);
})
});
});
Now, oddly enough, the images load fine. But the buttons don't do anything. If I highlight over the rotate button, it'll show a help popup of "Rotate" but won't actually do anything.
Do I have to reset the canvas somehow when loading the images?
I had a similar issue, you need to re-enable the menu by calling ui.activeMenuEvent(). So applying the changes to your code it would look like this
$(document).on('click', '.selectImage', function() {
var path = $(this).data('path');
$('#image_id').val($(this).data('image_id'));
instance.clearObjects().then(() => {
console.log('cleared');
instance.loadImageFromURL("{{ url('/') }}"+path,'name').then(result=>{
instance.ui.resizeEditor({
imageSize: {oldWidth: result.oldWidth, oldHeight: result.oldHeight, newWidth: result.newWidth, newHeight: result.newHeight},
});
instance.ui.activeMenuEvent();
console.log(result);
}).catch(err=>{
console.error("Something went wrong:", err);
})
});
});
Related
I am implementing a picture upload functionality to my app which I am developing with Ionic 4. I'm using the native plugin camera and a few others to do the following:
async selectImage() {
const actionSheet = await this.actionsheet.create({
header: "Select Image source",
buttons: [{
text: 'Load from Library',
handler: () => {
this.takePicture(this.camera.PictureSourceType.PHOTOLIBRARY);
}
},
{
text: 'Use Camera',
handler: () => {
this.takePicture(this.camera.PictureSourceType.CAMERA);
}
},
{
text: 'Cancel',
role: 'cancel'
}
]
});
await actionSheet.present();
}
takePicture(sourceType: PictureSourceType) {
var options: CameraOptions = {
quality: 100,
sourceType: sourceType,
saveToPhotoAlbum: false,
correctOrientation: true
};
this.camera.getPicture(options).then(imagePath => {
var currentName = imagePath.substr(imagePath.lastIndexOf('/') + 1);
var correctPath = imagePath.substr(0, imagePath.lastIndexOf('/') + 1);
this.copyFileToLocalDir(correctPath, currentName, this.createFileName());
});
}
copyFileToLocalDir(namePath, currentName, newFileName) {
this.file.copyFile(namePath, currentName, this.file.dataDirectory, newFileName).then(success => {
this.presentToast('Dispongo a actualizar.');
this.updateStoredImages(newFileName);
}, error => {
// this.presentToast('Error while storing file.');
});
}
updateStoredImages(name) {
this.storage.get(STORAGE_KEY).then(images => {
let arr = JSON.parse(images);
if (!arr) {
let newImages = [name];
this.storage.set(STORAGE_KEY, JSON.stringify(newImages));
} else {
arr.push(name);
this.storage.set(STORAGE_KEY, JSON.stringify(arr));
}
let filePath = this.file.dataDirectory + name;
let resPath = this.pathForImage(filePath);
let newEntry = {
name: name,
path: resPath,
filePath: filePath
};
this.images = [newEntry, ...this.images];
this.ref.detectChanges(); // trigger change detection cycle
});
}
So, in the action sheet, when I press the first option (Load from Library) it opens the library and I can choose the picture without any problem. When I press ok, it throws an error: the error expected from the copyFileToLocalDir. However, if I do the same with the second option (Use Camera) and I take a photo with the camera, it loads it fine and I can store it later.
I can't find the problem, please help.
im using this code using ionic 3 and it's working fine .
and after i chose one image it will be uploading to firebase and on the same time view it at page.html
app.module.ts
you have to import
import { Camera } from "#ionic-native/camera";
import { File } from "#ionic-native/file";
and added them #providers
then use this code at page.ts which you will chose one image :
html view
<button ion-button full (click)="openGallery()">open gallery</button>
<img [src]="camel_profile_image_path" />
ts page
import { Camera, CameraOptions } from "#ionic-native/camera";
private camera: Camera,
async openGallery() {
try {
const opstions: CameraOptions = {
quality: 100,
targetHeight: 600,
targetWidth: 600,
destinationType: this.camera.DestinationType.DATA_URL,
encodingType: this.camera.EncodingType.JPEG,
mediaType: this.camera.MediaType.PICTURE,
sourceType: this.camera.PictureSourceType.PHOTOLIBRARY,
correctOrientation: true
}
const result = await this.camera.getPicture(opstions);
const image = 'data:image/jpeg;base64,' + result;
const pictures = storage().ref('Profile Images/' + this.randomNumber + '.jpg');
pictures.putString(image, 'data_url');
this.base64Image = image;
this.camel_profile_image_path = this.randomNumber; // view the image on html page
this.slidetothis();
} catch (error) {
console.error(error);
}
}
I have to JavaScript class called GKChart :-
class GKChart {
constructor(data) {
try {
console.info("Enter: Chart Designing initialize function");
this.chartID = data.id;
this.chartData = data.data;
this.chartCall = new chartCalling();
this.load = this.initialize(this.chartData.config.chartType, this.chartData, this.chartID, this.chartCall);
this.load();
this.resize(this.load);
console.info("Exit: Chart Designing initialize function");
} catch (err) {
console.log("Error Found in GKChart Constructoru", err);
}
}
initialize(chartTypeLoad, chartDataLoad, chartIDLoad, chartCallLoad) {
try {
console.log("Start : initialize");
let chartType = chartTypeLoad;
let chartData = chartDataLoad;
let chartID = chartIDLoad;
var chartCall = chartCallLoad;
/*Define chart css properties*/
var loadIt = function() {
console.warn("Resize Load : "+chartID);
css(document.querySelector("#" + chartID), {
'display': 'block'
});
switch (chartType) {
case "line":
{
chartCall.lineChart(chartData, chartID);
break;
}
case 'bar':
{
chartCall.barChart(chartData, chartID);
break;
}
default:
{
console.log("Invalid choice of chart");
break;
}
}
}
return loadIt;
console.log("End : initialize");
} catch (err) {
console.error("Exception occurred in Home module: " + err.message);
}
}
resize(loadFun) {
try {
window.addEventListener("resize", function (e) {
window.resizeEvt;
window.addEventListener("resize", function () {
clearTimeout(window.resizeEvt);
window.resizeEvt = setTimeout(function () {
loadFun();
console.warn("ResizeCalled");
}, 250);
});
});
} catch (err) {
console.log("error occured while resizing the chart");
}
}
}
And i want to call this class for more then 20 instances with some dome data
new GKChart({id: "stepChartComparision", data: stepChartComparision});
new GKChart({id: "stepChartFill", data: stepChartFill});
new GKChart({id: "stepChartComparisionFill", data: stepChartComparisionFill});
...
...
...
So for these all calls i am drawing some canvas charts.
To make these canvas charts responsive i have to draw every chart for resize. So i have tried to create a closure function to keep a copy of "this.load" function, but as i can see its only calling once for the last instance.
Please help me to get it for every instance of call, or in other words i want to resize every singe canvas chart.
Thank you.
My Closure is working properly but due to ASYNC call of setTimeout function, only last call is running, but when i have removed this and tried to run it, its working properly.
Ans Code is :-
resize(loadFun) {
try {
window.addEventListener("resize", function (e) {
window.resizeEvt;
window.addEventListener("resize", function () {
loadFun();
});
});
} catch (err) {
console.log("error occured while resizing the chart");
}
}
I have a function which calls a service.
submitPost(value:any)
{
this._adminLogin.postAdminLogin(this.adminLoginmodel).subscribe(
data => {
this.responseStatus = data;
if(this.responseStatus.status == 1)
{
localStorage.setItem('admin_id', this.responseStatus.detail.id);
this._flashMessagesService.show(this.responseStatus.message, { cssClass: 'alert-success', timeout: 5000 });
top.location.href = 'admin/dashboard';
}
else
{
this._flashMessagesService.show(this.responseStatus.message, { cssClass: 'alert-danger', timeout: 2000 });
}
},
err => {
console.log(err)
},
() => {}
);
this.status = true;
}
My concern is with this section of code:-
if(this.responseStatus.status == 1)
{
localStorage.setItem('admin_id', this.responseStatus.detail.id);
this._flashMessagesService.show(this.responseStatus.message, { cssClass: 'alert-success', timeout: 5000 });
top.location.href = 'admin/dashboard';
}
Is there any way by which the redirect action could take place after the flash message disappears after 5000 ms? Something like this:-
if(this.responseStatus.status == 1)
{
localStorage.setItem('admin_id', this.responseStatus.detail.id);
this._flashMessagesService.show(this.responseStatus.message, { cssClass: 'alert-success', timeout: {function(){ top.location.href = 'admin/dashboard'; }, 5000 });
}
The following code should navigate after the message disappears. Yout flashMessage will be displayed for 5000 ms and your navigate should happen after 7000ms
if(this.responseStatus.status == 1)
{
localStorage.setItem('admin_id', this.responseStatus.detail.id);
this._flashMessagesService.show(this.responseStatus.message, { cssClass: 'alert-success', timeout: 5000 });
setTimeout(()=>{
top.location.href = 'admin/dashboard';
},7000);
}
I would do this by having the _flashMessagesService.show() return an Observable.
In the _flashMessageService, something like this:
myObserver : Observer<any>
function show(){
// do stuff
return Observable.create(observer =>{
this.myObserver =observer;
});
}
When you're ready to resolve the Observable, you can do:
this.myObserver.next('Possibly some value here');
this.myObserver.complete();
In your invoking code
this._flashMessagesService.show()
.subscribe(result=> { top.location.href = 'admin/dashboard'});}
I have been working on something similar.
An alternate approach, perhaps simpler is to just use Observable.timer in your main component:
Observable.timer(5000).subscribe(result=> { top.location.href = 'admin/dashboard'});
I prefer the first way, because it is contingent on the flashMessage service deciding when the flash message goes away, not on a hard coded time value.
I'm working with NativeStorage and barcodeScanner plugins for cordova.
The capture works well, and I receive the QRCode, but for any reason angular doesn't print it.
After working a lot on my code, I'm not able to do a valid callback, so angular can print it binding the data.
Here bellow I paste the code.
read.js
(function() {
'use strict';
var read = angular.module('app.read', ['monospaced.qrcode']);
read.controller('ReadController', [
function() {
var data = this;
var qr = function(string) {
data.code = string;
console.log(string);
};
cordova.plugins.barcodeScanner.scan(
function(result) {
if (!result.cancelled) {
if (result.format === "QR_CODE") {
(function(cb) {
cb(result.text);
})(qr);
NativeStorage.getItem("historic", function(d) {
var storage = JSON.parse(d);
storage.push(result.text);
NativeStorage.setItem("historic", JSON.stringify(storage), function(response) {}, function(e) {
console.log(e);
});
}, function(e) {
window.alert("Scanning failed: " + e);
});
}
}
},
function(e) {
window.alert("Scanning failed: " + e);
}, {
"preferFrontCamera": true, // iOS and Android
"showFlipCameraButton": true, // iOS and Android
"prompt": "Place a barcode inside the scan area", // supported on Android only
"formats": "QR_CODE,PDF_417", // default: all but PDF_417 and RSS_EXPANDED
"orientation": "portrait" // Android only (portrait|landscape), default unset so it rotates with the device
}
);
}
]);
}());
read.html
<div ng-controller="ReadController as myRead">
<qrcode version="5" error-correction-level="H" size="200" data="{{myRead.code}}" href="{{myRead.code}}"></qrcode>
{{myRead.code}}
</div>
Just adding some extra tests I have done before, I just missed the barcodeScanner.scan process and I did just the storage as I show bellow:
NativeStorage.getItem("historic", function (d) {
var storage = JSON.parse(d);
storage.push('https://google.es');
data.code = 'https://google.es';
NativeStorage.setItem("historic", JSON.stringify(storage), function (response) {}, function (e) {
console.log(e);
});
}, function (e) {
window.alert("Scanning failed: " + e);
});
Could you show me where am I wrong?
Thanks in advice.
A qualified guess is that the callbacks from cordova.plugins.barcodeScanner.scan doesn't trigger AngularJS' digest cycle, which means no dirty checking will be performed, no changes will be detected and the UI won't be updated.
Try wrapping the code in the success callback in $apply:
function(result) {
$scope.$apply(function() {
if (!result.cancelled) {
if (result.format === "QR_CODE") {
(function(cb) {
cb(result.text);
})(qr);
NativeStorage.getItem("historic", function(d) {
var storage = JSON.parse(d);
storage.push(result.text);
NativeStorage.setItem("historic", JSON.stringify(storage), function(response) {}, function(e) {
console.log(e);
});
}, function(e) {
window.alert("Scanning failed: " + e);
});
}
}
});
}
I'm working with Notification API but i can't make it work with SetInterval(), can somebody point out what i'm doing wrong. As long as i click the event, the notification only displays once. Here is my code:
document.addEventListener('DOMContentLoaded', function() {
document.getElementById('notifyBtn').addEventListener('click', function() {
if (!('Notification' in window)) {
alert('Web Notification is not supported');
return;
} else {
setInterval(Notification.requestPermission(function(permission) {
var notification = new Notification("Hi there!", {
body: 'I am here to talk about HTML5 Web Notification API',
icon: 'icon.png',
dir: 'auto'
});
setTimeout(function() {
notification.close();
}, 2000);
}),5000);
}
;
});
});
I'm really stucked here, please halp.
You need to pass valid callback to setInterval(). Instead, you are passing the result of some method. Try this:
setInterval(function () {
Notification.requestPermission(function(permission) {
var notification = new Notification("Hi there!", {
body: 'I am here to talk about HTML5 Web Notification API',
icon: 'icon.png',
dir: 'auto'
});
setTimeout(notification.close, 2000);
})}, 5000);
Bonus: see how I simplified your setTimeout callback, by just passing the notification.close method itself, instead of calling it in anonymous function. Much cleaner.
Wrap your method in anonymous function
document.addEventListener('DOMContentLoaded', function() {
document.getElementById('notifyBtn').addEventListener('click', function() {
if (!('Notification' in window)) {
alert('Web Notification is not supported');
return;
} else {
setInterval(function(){Notification.requestPermission(function(permission) {
var notification = new Notification("Hi there!", {
body: 'I am here to talk about HTML5 Web Notification API',
icon: 'icon.png',
dir: 'auto'
});
setTimeout(function() {
notification.close();
}, 2000);
})},5000);
}
;
});
});
I found something like this :
document.addEventListener('DOMContentLoaded', function() {
document.getElementById('notifyBtn').addEventListener('click', function() {
if (!('Notification' in window)) {
alert('Web Notification is not supported');
return;
} else {
setInterval(notify, 5000);
}
});
function notify() {
Notification.requestPermission(function(permission) {
var n = new Notification("Hi there!", {
body: 'I am here to talk about HTML5 Web Notification API',
icon: 'icon.png',
dir: 'auto'
})
setTimeout(function(){n.close()}, 2000)
})
}