Image viewer/editor with CamanJS - javascript

I am trying to make a simple image viewer application using Electron and with the possibility to edit images. I am using CamanJS for image manipulation effects but I have a small problem. When I load the folder with all images, I can scroll through them, also, I can apply some filters to image number 3 for example, save it and scroll no next one. But when I am trying to edit another image, say number 5, when I press the button it renders the image nr 3 and apply the effects to image nr 3. I have tried to resolve this bug but with no success. Can someone help me? Bellow is some code.
Here is the image on the "web page"
<canvas id="currentImage" class="img-thumb center"></canvas>
I have an array of indexes with images from the folder and I iterate through it to change the image that is displayed. Below is the function how I change the image:
var onPreviousClick = function() {
var currentImageId = $currentImage.data('currentIndex');
if (currentImageId > 0) {
showImage(--currentImageId);
}
};
And this is how I apply the Lomo effect to the image:
$lomobtn.on('click', function() {
Caman('#currentImage', function() {
this.lomo().render();
});
});
I suppose that is something related to this. First time when I press the button it references to the first image, and second time when I press the button it also references to the first image.
UPDATE
I find out that I have to use the function reloadCanvasData() to refresh the data from canvas, but I can't find out how to use this function. https://github.com/meltingice/CamanJS/blob/master/src/core/caman.coffee#L387-L392
Can someone help me to use this function? Tried different methods to call this function and I receive and error.

This is a few months old question, but hopefully still relevant for you or someone else.
I had the same issue. Just use it like this:
$lomobtn.on('click', function() {
Caman('#currentImage', function() {
this.reloadCanvasData() // <--- here, before you apply your filter
this.lomo().render();
});
});

Related

Prevent render of fabric-js canvas until fully populated

In FabricJS canvas.loadFromJSON() seems to run some sort of renderAll function even if not specified? As I'm both loading images from JSON and some from another function, I would like the canvas to stay empty until everything is loaded and then render everything simultaneously.
I have created a short fiddle with a simplified version: https://jsfiddle.net/Xikura/cas6j7b3/168/
The fiddle toggles one of the layers then redraws the canvas, especially if you disable caching you can see that the props shows up on it's own, then the rest of the images a bit later.
Quite minor one might say, but when there are between 10 and 30 images with various blend-settings, the loading could take some time until common images starts to get cached, moving around on the early visible props isn't doing my solution much good...
I see the documentation of loadFromJSON adds the renderAll() in it's callback, I trigger my own preload images in that same callback instead, to be able to add the other images.
if (!jsonCanvas) {
// First load
preload(images);
} else {
// Loading from saved JSON
canvas.loadFromJSON(jsonCanvas, function () {
preload(images);
});
}
Right now I can't seem to grasp why loadFromJSON seem to trigger some sort of render so the props are displayed first? Does FabricJS have any functionality I could use to prevent a render until I trigger it myself with renderAll() ?
I found the FabricJS-setting which one would think would solve this: renderOnAddRemove which I set to false, it did fix some other render-difficulties I had earlier, but had no effect on the loadFromJSON-part.
So I have been working the whole day on this, but after completing my question I decided to give it a rest and move on to other problems. By accident while trying to optimize the performance of my application I stumbeled upon this Improving FabricJS speed-site, which both answers my question and solves my problem.
By switching out loadFromJSON with fabric.util.enlivenObjects I'm able to trigger my own callback and not the (undocumented?) canvas.renderAll() which loadFromJSON calls.
if (!jsonCanvas) {
// First load
preload(images);
} else {
// Loading from saved JSON
fabric.util.enlivenObjects(jsonCanvas.objects, (objs) => {
objs.forEach((item) => {
canvas.add(item);
});
preload(images);
})
}
I updated my fiddle to include this fix.

AmMaps MapImage appears on window resize/move after deleteObject() call on it

I need to show pulsar animation in the map point on an event. I add circle image to the map and remove it after some time. I animate the image using CSS. All works ok, but if I try to resize the window, the image appears again and is never removed after.
Here is the issue screencast:
See the codepen (the event is illustrated using setTimeout()).
Am I using the wrong method for image deletion or missing smth?
Typically you're supposed to call validateData() or validateNow() on the entire map when adding new images. Since you're using tap.validate() to add a single image, you have to leverage some internal APIs similar to what was suggested in this ticket to make that work. Using your code as a base:
tap.validate();
this.map.dataProvider.images.push(tap);
// add to internal objects
this.map.imagesProcessor.allObjects.push(tap);
this.map.imagesProcessor.allSvgObjects.push(tap.displayObject);
tap.parentArray = map.dataProvider.images;
setTimeout(() => {
tap.deleteObject();
}, 1000);
Updated codepen

How to add a "pin it" button dynamically?

I'm trying to optimize my Wordpress install - and one of the culprits I'm seeing, is the "Pin It" button widget for Pinterest. I'm now trying to find a way to dynamically load the JS code (when they initially hover over the button), and then apply it to the page. So far I've only managed to get this far:
jQuery(document).on("mouseenter click",'.pinItSidebar', function() {
jQuery.getScript("http://assets.pinterest.com/js/pinit_main.js", function() {
// do something here?
});
});
I can't seem to find a function that I can call (as a callback, after the JS is loaded). Obviously I will only do this once per page load (the above is just a very basic version at the moment)
Does anyone have any suggestions on how I can achieve this? The end game of how I want it to function, is with:
Working solution:
Here is a working solution I've now got, which will allow you to load the pinterest stuff ONLY when they click the button (and then trigger the opener as well). The idea behind this, is that it saves a ton of Pinterest JS/CSS / onload calls, which were slowing the page down.
jQuery(document).on("click",'.pinItSidebar', function() {
if (typeof PinUtils == "undefined") {
jQuery.getScript("http://assets.pinterest.com/js/pinit_main.js", function() {
PinUtils.build();
PinUtils.pinAny();
});
} else {
PinUtils.pinAny();
}
});
...and just call with:
foo
Hopefully this helps save someone else some time :)
Extra tweak: I'm just playing around, to see if I can make this even more awesome :) Basically, I want to be able to decide which images are pinnable. Below this will do that for you:
jQuery("img").each(function() {
if (jQuery(this).data('pin-do')) {
// its ok, lets pin
} else {
jQuery(this).attr('nopin',"1");
}
});
All you need to do to make an image pinnable, is have the data-pin-do="1" param set the images you want to allow them to share :)

Can't assign html .src to a javascript variable

I'm trying to switch an image on a HTMLbutton using javascript.
It works, but I think it loads the image every time I click the button, and that's not good. So I want to load the images only one time and than I can switch between the images.
This Is what I have now.
mute.onclick=function () {
if (audioEngine.isMuted)
{
document.getElementById('muteIcon').src="images/unmuted.png";
}
else{
document.getElementById('muteIcon').src="images/unmuted.png";
}
But I think every time I click the button it looks in the path "images/unmuted.png" to see what's there and load it. So I was thinking this is an easy fix. I just define a variable unmuteImage and assign that to document.getElementById('muteIcon').src. Like this
var unmuteImage=new Image();
unmuteImage.src='images/unmuted.png';
mute.onclick=function () {
if (audioEngine.isMuted)
{
document.getElementById('muteIcon').src=unmuteImage;
}
else{
document.getElementById('muteIcon').src="images/unmuted.png";
}
But when I do this, I get the following error in my consols:
GET file:///path/to/the/mian/html/file/[object%20HTMLImageElement] (In red text)
And I don't get the image, I get the "borken image" picture because somehow it didn't find the picture.
Can somebody help me please?
Thanks
this may work for you if you have jquery
$('#muteIcon').replaceWith(unmuteImage);
other wise you have to use src itself
document.getElementById('muteIcon').src = unmuteImage.src;

jquery Fade In, Fade Out, Fade In 2

I'm done a bit of reading on here, but I'm posting because I can't seem to figure out specifically what I'm looking to do. I've tried tweaking existing code I've found here, but no such luck. It probably doesn't help that I'm not very well versed in javascript. I'm a recovering flash designer.
Let me explain:
I have 2 divs, one with a very large image, one with text. Ideally I'd like the webpage to function in this manner:
nothing on screen
fade in image div (and I think it might need some time to load first)
fade out image div
nothing on screen (ie: not a crossfade)
fade in text div
leave the image div there permanently.
Any thoughts on how to approach this would be much appreciated! Again, forgive my ignorance.
Since the image could be large, wire up the .load() event on the image which will be fired once the image has loaded successfully. From there just use the callback function in the .fadeOut() and .fadeIn() to show/hide your divs.
$(function() {
$(".image img").load(function() {
$(".image").fadeIn("slow", function() {
$(this).fadeOut("slow", function() {
$(".text").fadeIn("slow");
});
});
});
});
Code example on jsfiddle
$(document).ready(function(){
$('#id-of-img').fadeIn(5000).delay(5000).fadeOut(5000); // 5000 is 5 seconds, change this as you wish
$('#id-of-text').fadeIn(5000);
});
This requires jQuery 1.4.2 or above for the delay() function
-- edit --
Just re-read your question. You say "leave the image div there permanently', did you mean the text div? If so, what I've done should work, if not then I don't really know what you mean.
Using Event Callbacks
You want to load the image in a way that provides a callback when it has finished pre-loading:
var $textDiv = jQuery('.textDiv'); // contains the text
var img = new Image();
img.src = "images/myImageUrl.jpg";
img.onload = function() {
jQuery(this).hide().appendTo('.imgDiv').fadeIn(300, function(){
$(this).fadeOut(300, function() {
$textDiv.fadeIn(300);
}
});
};

Categories

Resources