Fabric.js image on click and animate outside add function - image

Hi I am developing an application with Fabric.js where the user would enter some string and upon clicking on the delete image last word will be deleted and the image would shift to the left.
I am using image like
fabric.Image.fromURL(srcImg, function (oImg) {
canvas.add(oImg);
oImg.set('left',0);
oImg.set('top', 100);
oImg.scale(.55);
canvas.renderAll();
// and then, we can animate the image
oImg.animate('left', 100, {
onChange: canvas.renderAll.bind(canvas)
});
oImg.on('mouse:down', function() {
//some function here
});
});
Now I want to use the click and the animate outside of the add function, but I get an error undefined index oImg. I want to use click and animate elsewhere so that I can remove the last word and use animate to shift the image to the left I am using text for click and the animate right now but I would like to use image.

fabric.Image.fromURL is an asynchronous method, so it is normal that it will throw an error of undefined calling it just below it. You have mainly two solutions here:
Add the event listener inside the callback:
fabric.Image.fromURL('//lorempixel.com/200/200/', function(img) {
img2 = img
...
img2.on('mousedown', function () {
console.log('throws an error');
});
});
Call events binding function (always after img2 was created)
fabric.Image.fromURL('//lorempixel.com/200/200/', function(img) {
img2 = img
...
bindImageEvents(img2)
});
function bindImageEvents (imageObject) {
imageObject.on('mousedown', function () {
console.log('Something...');
});
}

Related

Mapbox background layer click event not working

I'm trying to set up a click event on a transparent background layer in Mapbox. Here is a code snippet:
map.on('load', function () {
map.addLayer({
id: 'transparent',
type: 'background',
interactive: true,
paint: {
'background-color': '#dedede',
'background-opacity': 0
}
})
}
//This doesn't print Hello World to the console
map.on('click', 'transparent', function () {
console.log('Hello World')
})
Calling the same event on a symbol layer works without a problem. Any help would be appreciated.
Layers specify the Source's styles. The type of layer is specified by the 'type' property and must be one of background, fill, line, symbol, raster, circle, fill-extrusion, heatmap, hillshade.
Except for layers of the background type, each layer needs to refer to a source.
Layers take the data that they get from a source, optionally filter features, and then define how those features are styled.
I recommend adding an event on Map instead like:
map.on('click', function (e) {
//code
});
Example:
https://docs.mapbox.com/mapbox-gl-js/example/mouse-position/
How to add background layer:
https://bl.ocks.org/stevage/a09dcbd11fb24b20033f2d3f6ab01374

How to check if a button is clicked in JavaScript

How to check if a button is clicked or not in prototype JavaScript?
$('activateButton').observe('click', function(event) {
alert(hi);
});
The code above is not working.
With this button:
<button id="mybutton">Click Me</button>
Use this:
$('mybutton').observe('click', function () {
alert('Hi');
});
Tested and works, here.
You might want to encase it in a document.observe('dom:loaded', function () { }) thingy, to prevent it executing before your page loads.
Also, just an explanation:
The single dollar sign in Prototype selects an element by its id. The .observe function is very similar to jQuery's .on function, in that it is for binding an event handler to an element.
Also, if you need it to be a permanent 'button already clicked' thingy, try this:
$('mybutton').observe('click', function () {
var clicked = true;
window.clicked = clicked;
});
And then, if you want to test if the button has been clicked, then you can do this:
if (clicked) {
// Button clicked
} else {
// Button not clicked
}
This may help if you are trying to make a form, in which you don't want the user clicking multiple times.
How one may do it in jQuery, just for a reference:
$('#mybutton').on('click', function () {
alert('Hi');
});
Note that, the jQuery code mentioned above could also be shortened to:
$('#mybutton').click(function () {
alert('Hi');
});
jQuery is better in Prototype, in that it combines the usage of Prototype's $ and $$ functions into a single function, $. That is not just able to select elements via their id, but also by other possible css selection methods.
How one may do it with plain JavaScript:
document.getElementById('mybutton').onclick = function () {
alert('Hi');
}
Just for a complete reference, in case you need it.
$('body').delegate('.activateButton', 'click', function(e){
alert('HI');
});

JQuery animation of image

Ok, I was doing a simple JQuery animation. When a user will click on an image,it will move to the left by 1000px. Here is the code below:
function cloud2 () {
$('#cloud2').animate({left:'1000px'},40000);
setTimeout(cloud2,2000);
}
$(document).ready(function() {
$('#cloud2').click(function() {
cloud2();
});
});
Very nice nothing is wrong, all is working like a BOSS! When the image reaches 1000px, it stops. All good! What I want now, is to replace the image with another image once it stops when it completes the 1000px animation. How to do that? For example, once it stops, the image changes to another one, let's say image2.jpg for instance.
Thank!
animate() has an event for ending animation.
For example you have something like:
<img src="image1.jpg" id="myimg">
function moveimg() {
$('#myimg').animate({left: '1000px'}, 40000, function() {
$('#myimg').attr('src', 'image2.jpg');
});
}
setTimeout("moveimg()", "2000")

How to trigger events on Leaflet map polygons?

I'm trying to figure out how to manually trigger events for Leaflet polygons (loaded via GeoJSON).
In a nutshell, I have a Leaflet map with numerous polygons. I also have a regular hyperlink outside of the map that when clicked, should trigger a mouseover event (or any event really) on a particular polygon.
How do I assign ID's to all of my polygons so that I can bind hyperlink(s) to a specific polygon's event? Or is that even the most logical way of doing this?
Ultimately, I'm trying to create a map with numerous polygons along with an HTML table of text labels that are associated to each polygon. When clicking on the HTML table text, I'd like to trigger events on the map polygons (and vice versa). I just don't know how to reference each polygon.
Here is my very simplified HTML:
<body>
<div id="map" style="height: 550px; width:940px"></div>
Click to trigger a specific polygon mouseover event
</body>
Here is my very simplified JS:
$(document).ready(function () {
// build the map and polygon layer
function buildMap(data) {
var map = new L.Map('map');
var cloudmadeUrl = 'http://{s}.tile.cloudmade.com/***yourkeyhere***/66267/256/{z}/{x}/{y}.png',
cloudmadeAttribution = '',
cloudmade = new L.TileLayer(cloudmadeUrl, {maxZoom: 18, attribution: cloudmadeAttribution});
var mapLoc = new L.LatLng(43.675198,-79.383287);
map.setView(mapLoc, 12).addLayer(cloudmade);
var geojsonLayer = new L.GeoJSON(null, {});
geojsonLayer.on("featureparse", function (e){
// apply the polygon style
e.layer.setStyle(polyStyle);
(function(layer, properties) {
layer.on("mouseover", function (e) {
// change the style to the hover version
layer.setStyle(polyHover);
});
});
layer.on("mouseout", function (e) {
// reverting the style back
layer.setStyle(polyStyle);
});
layer.on("click", function (e) {
// do something here like display a popup
console.log(e);
});
})(e.layer, e.properties);
});
map.addLayer(geojsonLayer);
geojsonLayer.addGeoJSON(myPolygons);
}
// bind the hyperlink to trigger event on specific polygon (by polygon ID?)
$('#testlink').click(function(){
// trigger a specific polygon mouseover event here
});
});
OK, I've figured it out.
You need to create a click event for each polygon that opens the popup, and assign a unique ID to each polygon so you can reference it later and manually trigger its popup.
The following accomplishes this:
var polyindex = 0;
popup = new L.Popup();
geojsonLayer = new L.GeoJSON(null, {});
geojsonLayer.on("featureparse", function (e){
(function(layer, properties) {
//click event that triggers the popup and centres it on the polygon
layer.on("click", function (e) {
var bounds = layer.getBounds();
var popupContent = "popup content here";
popup.setLatLng(bounds.getCenter());
popup.setContent(popupContent);
map.openPopup(popup);
});
})(e.layer, e.properties);
//assign polygon id so we can reference it later
e.layer._leaflet_id = 'polyindex'+polyindex+'';
//increment polyindex used for unique polygon id's
polyindex++;
});
//add the polygon layer
map.addLayer(geojsonLayer);
geojsonLayer.addGeoJSON(neighbourhood_polygons);
Then to manually trigger a specific layers click event, simply call it like this:
map._layers['polyindex0'].fire('click');
Everything between the square brackets is the unique ID of the layer you want to trigger. In this case, I'm firing the click event of layer ID polyindex0.
Hope this info helps somebody else out!
So, quick update.
Just call fireEvent (or its alias fire) on whatever layer you need.
You don't need to risk ._private[Vars], just get a reference to the target layer and fire away, e.g.
var vectorLayer = map.getLayer('myVectorLayer');
vectorLayer.fire('click');
function clickMarker(i){
var popupContent = "content here or html format",
popup = new L.Popup({offset:new L.Point(0,-28)});
popup.setLatLng(LatLng);
popup.setContent(popupContent);
map.panTo(LatLng);
map.openPopup(popup); }
i = got a corresponding coordinate which is LatLng

ckeditor - onpaste event

Does anyone know how I can attach an onpaste event in CKEditor 3.x?
I basically want to grab CTRL + V data and add few text to it and then add it to the editor.
I have looked around but have not found a definitive answer. CKEditor forum is of not much help.
This should do the trick
var editor = CKEDITOR.instances.YourInputControlName;
editor.on('paste', function(evt) {
// Update the text
evt.editor.setData(evt.editor.getData() + ' your additional comments.');
}, editor.element.$);
Your both examples are a little bit synthetic.
At first, editor.getData() gets all the content of editor, so if you want to process only pasted data, you need to get ev.data.html and paste to correct place.
editor = CKEDITOR.instances.editor1;
editor.on('paste', function (evt) {
var editor = evt.editor;
evt.stop(); // we don't let editor to paste data, only for current event
// show loader that blocks editor changes
$.post('clean.php', {html: evt.data.html}, function (data) {
editor.insertHtml( data.html ); // text will be inserted at correct place
// hide loader
}, 'json');
});
Don't use functions editor.setReadonly(true/false), you won't be able to paste text in correct place (in cases with async data processing).
This example edits the content to be pasted by removing all img elements.
CKEDITOR.on('instanceReady', function (ev) {
ev.editor.on('paste', function (ev) {
ev.data.html = ev.data.html.replace(/<img( [^>]*)?>/gi, '');
});
});
editor = CKEDITOR.instances[id];
editor.on('paste', function (evt) {
evt.stop();
var data = evt.data.dataValue;
if (window.chrome || window.safari) {
// removing span wrapper on webkit browsers.
data = $(data).html();
}
evt.editor.insertHtml(data);
});
I know it's an old question, but thought I'd add my version of aliaksej's answer as it allows the use of a custom 'cleaner' - it didn't quite work for me until I modded it as below.
editor = CKEDITOR.instances[id];
editor.on('paste', function (evt) {
evt.stop();
$.post('/actions/clean.php', {html: evt.data.dataValue}).done(function (data) {
evt.editor.insertHtml(data);
}, 'json');
});

Resources