scroll zoom on two images - javascript

I have two images with same dimensions and same positions, but placed in divs with dynamic width depending on user interaction using the jquery beforeAfter plugin.
I would like to enable scroll zooming on these images using wheelzoom, such that zooming on one of these images will zoom the same amount in the same position as the other.
What I am unable to do is this linking of (I suppose) the event handlers along the lines of this:
function onwheel(e){
//adjust image to fit zoom level ...
other_img.onwheel(e);
}
If this is not possible, is it possible to copy the event and change the target image?
I am looking for a solution using either jquery or native Javascript.
Code here (ignore the handle).
EDIT: Any top-level pointers to what should work would also be appreciated

I made a worked example: http://plnkr.co/edit/kH0ec8TVMXUIYlMoBaMq?p=preview
here is the core code:
document.getElementsByClassName("before")[0].addEventListener("wheel", function(event){
if(flag){
flag= false;
return;
};
flag=true;
var newEvent = new WheelEvent("wheel",event);
var elementToTrigger = document.getElementsByClassName("after")[0];
elementToTrigger.dispatchEvent(newEvent);
});
I do something simple, when an event happening("wheel") a trigger the same event to another element and pass as argument the data from the first event to the new event. I use flag variable to deter the custom event trigger again the other event and start an eternal loop.
This is a solution without to edit the source code of plugin. You can do more good solutions if you change the code of wheelzoom.js.

Make the zooming a function that takes enough parameters to handle zooming, and get the values you need from the event handler.
function handleZoom(domNode, zoomDirection, zoomAmount) {
// Do stuff to change the size of `domNode`
}
var img1, img2;
img1 = /* select image node */;
img2 = /* select image node */;
function handleScroll(scrollEvent) {
var direction, amount;
// Use `scrollEvent` to figure out which direction and how far to zoom
handleZoom(img1, direction, amount);
handleZoom(img2, direction, amount);
}
img1.onscroll = handleScroll;
img2.onscroll = handleScroll;

Related

Is there a way to change the layout/style when a user zooms in a plotly line chart?

The documentation for plotly is a bit hard to use and couldn't find a specific settings for relayout on zoom.
The method I used is to add a 'plotly_relayout' event listener and then check the event data if it has 'xaxis.range[0]'. If it does then I make some update and then do a relayout and restyle.
var gd = document.getElementById(chart_id);
gd.on('plotly_relayout', function (eventdata) {
// Check if a pan or zoom occurred.
if (eventdata.hasOwnProperty('xaxis.range[0]')) {
layout_update = {...,...};
trace_update = {...,...};
Drupal.plotly.relayout(chart_id, layout_update);
Drupal.plotly.restyle(chart_id, trace_update);
}
}
This might be an inefficient way of going about it, though. It seems to be a bit slow. Also it cannot differentiate between a pan and a zoom action as the event data is the same. Is there a better way?

change default cursor style in PIXI.js

I want to change my cursor when triggering a mousedown event. I found a lot of hints how to achieve that - but these have one major issue. To change the defaultCursorStyle property I need to instantiate the InteractionManager prototype.
var renderer = PIXI.autoDetectRenderer(640, 480),
var interactionManager = new PIXI.interaction.InteractionManager(renderer)
interactionManager.defaultCursorStyle = "crosshair" // a native html/css cursor style
That looks fine at first but the problem here is that this InteractionManager seems to batch-register all events applied to PIXI object via the .on(event, callback) event-binding function per instance.
That means that if there would be a second instance of this InteractionManager, all events would be bound twice and therefore triggered twice. I had this exact issue.
So I needed to revert my changes and try to access the default InteractionManager. Somebody in the HTML5GameDev forum told me to access it like this:
renderer.plugins.interaction
knowing that I tried the following:
renderer.plugins.interaction.defaultCursorStyle = "crosshair"
My events now worked properly again. But the cursor change did not happen. However debugging the line told me that the property defaultCursorStyle was successfully set to "crosshair". Now I'm looking for a way to make this change visible.
My question:
Is there a better way to change the cursor style than the mentioned one above? If no, how can I make my default cursor change visible after setting the new style to the default InteractionManager?
There's a setCursorMode method in the docs, guess it's what you need.
const app = new PIXI.Application({ height, width })
app.renderer.plugins.interaction.cursorStyles.default = 'crosshair'
setTimeout(() => {
app.renderer.plugins.interaction.setCursorMode('pointer')
}, 1000)
Whenever cursor leaves the renderer, PIXI resets cursor mode (here's exactly the line). So you might want to set new cursor mode as default each time you change it.
function changeCursorMode (cursorMode) {
app.renderer.plugins.interaction.cursorStyles.default = cursorMode
app.renderer.plugins.interaction.setCursorMode(cursorMode)
}
app.renderer.plugins.interaction.cursorStyles.crosshair = 'crosshair'
changeCursorMode('crosshair')

How to Manipulate Image After Uploaded To Canvas (FabricJS)

I've been racking my brain on this for a while now, but I can't seem to rotate the image on Canvas after uploading. Here's the code sample in question:
// INITIATE & DRAW CANVAS
var canvas = new fabric.Canvas('CanvasArtArtboard');
// CREATE OVERLAY GRIDS
canvas.setOverlayColor('rgba(205, 173, 64, 0.6)', canvas.renderAll.bind(canvas));
// UPLOAD USER IMAGE TO CANVAS
document.getElementById('imgLoader').onchange = function handleImage(e) {
var reader = new FileReader();
reader.onload = function (event) {
var imgObj = new Image();
imgObj.src = event.target.result;
imgObj.onload = function () {
// start fabricJS stuff
var image = new fabric.Image(imgObj);
image.set({
originX: 'left',
originY: 'top',
padding: 0,
cornersize: 10,
scaleX: 0.4,
scaleY: 0.4,
});
//image.scale(getRandomNum(0.1, 0.25)).setCoords();
canvas.add(image);
image.sendToBack();
canvas.renderAll();
//end fabricJS stuff
}
}
reader.readAsDataURL(e.target.files[0]);
}
// ROTATE UPLOADED IMAGE
$("#angle-control").click(function(){
var curAngle = canvas.item(0).getAngle();
canvas.item(0).setAngle(curAngle+15);
canvas.renderAll();
});
I've looked at the following example:
Add image from user computer to canvas (Stack OverFlow Question)
http://jsfiddle.net/PromInc/3efe2x9j/
Once the user uploads their image and clicks the "rotate 90*" button, I'm looking for the image to then rotate.
EDIT: Apologies, here is my JSFiddle in it's current state: http://jsfiddle.net/darnellcreates/oq6htzew/3/
I had a look at your fiddle and there is a lot wrong. The code for rotating is ok (sort of) but the page is full of problems.
First there is no JQuery and you are using the JQuery $ function as selector to access DOM elements. I do not see the point in using jQuery if all you are doing is using it as a selector, you use document.getElementById in some parts and $ in others. This totally negates any benefit Jquery would provide.
Second you are duplicating DOM element ID's (This is a strict no no) DOM ID's must be unique to the page.
To get you on your way here are a few changes,
Change the slider element in the HTML to
<input type="range" id="angleControl1" value="0" min="-90" max="90">
Note that the id is unique to the page. I have also avoided the naming convention (did not make it angle-control1) as this is a simple page and I will take some shortcuts and access the DOM elements directly in JavaScript.
Next remove the click handler for the range slider and replace it with a mouse move event listener.
// keep a copy of the last value so there is no needless rotates
var lastValue = angleControl1.value; // no need to search the node tree.
// you can access elements directly by
// their ID.
// Listen to the mousemoves of the range control. Click, change will
// only update at the end of the mouse down up process. This does not
// provide good user feedback
angleControl1.addEventListener("mousemove",function(){
if(this.value !== lastValue){ // only update the angle if it has changed
// set the angle to the absolute angle rather than relative as you had it
canvas.item(0).setAngle(Number(this.value)); // Number() is me being pedantic
canvas.renderAll(); // rerender
lastValue = this.value; // remember the last value
}
}); // all done for this function
Note. Direct DOM element access can be problematic in some situations (if you duplicate ID's, use that id as a variable before the DOM has loaded, your page is sharing the global namespace, or someone is using an old netscape browser) but for simple pages it is the easiest and safest way (If someone has netscape they can't run the page anyway because there is not canvas element).
Also remove the other Jquery calls $() as they cause the page to crash and stop everything from running.
You need to use the DevTools in these types of situations. It will show you all the errors and give you warnings (FireFox) for bad habits. To access the DevTool hit f12 on most browsers.The DevTools console will list errors and provide a link directly to the code where it is happening. You can also step through the code line by line so you can see what is going on.
i updated your jsfiddle ,to work both the rotate button 90o and the range bar,
just in case you need it.
link: http://jsfiddle.net/rqevmp3y/1/
$("#angle-control").on('click', function (event) {
console.log('rotate');
var curAngle = canvas._objects[0].getAngle();
canvas._objects[0].setAngle(curAngle+90);
canvas.renderAll();
});
$("#rangeControl").on('change', function (event) {
console.log('rotate from range',$(this).val());
var curAngle = canvas._objects[0].getAngle();
canvas._objects[0].setAngle(curAngle+parseInt($(this).val()));
canvas.renderAll();
});

How to find out the dimension of the lightbox?

About the lightboxes. The box adjusts its dimension to match the picture. Question is how do the box find out the size of the picture?
To answer the comment about detecting when its done loading, i believe you can use the onLoad event. in jquery this would look somthing like:
$('img').attr('src', 'uri/for/image').load(callbackFunction);
or manually:
var tmp = new Image();
tmp.onload = callbackFunction;
tmp.src = 'uri/for/image';
your callbackFunction could then use $(this).height() and $(this).height() safely. so your callbackFunction is where you would have the actual logic to trigger the rest of your implementation.
in alot of cases if seen this callback (or its equiv. implementation) simply set a global variable and then somewhere else in the code youll see polling of this variable every N ms. and when its set it will trigger the rest of the script.
I assume something akin to:
imgWidth = $(img).width();
imgHeight = $(img).height();
It would load the image in a hidden element (or positioned off screen), get the dimensions, animate the container to fit, then expose the image (usually via some sort of transition/animation).

Mootools Slider plugin functions

I am using mootools to create a CSS skin for the Youtube chromeless player using the javascript API to control playback. I cannot post the code unfortunately. The question I have is a more general one. When using the slider plugin a call to mySlider.set(step) moves the knob to the correct step on the slider but it triggers all of the plugins event functions (onChange, onTick, onComplete). The problem with this is, how do you know if the sliders knob position was changed by a user or a call to the set() function? I would have thought there would be a function reserved for when the knob was released by a mouse only and not be called if the position was simply set in code. I have code that updates the knobs position based on where the videos playback duration is currently at. I need to be able to move the knob to the current position in code without it thinking a user let go of the knob.
To simplify the question, is there a way to set the knobs position on a slider in code without triggering the functions used when a user interacts?
You can find the Slider plugin reference here http://mootools.net/docs/more/Drag/Slider
Thanks
I got this problem and ended up doing this
var slider = new Slider(track,knob, {
onChange: function(){
console.log("doesn't fire after autosize()");
}
});
// fake .set();
slider.step = 50; // new value
slider.autosize(); // redraw the knob
Make a variable that indicates that you're setting it programatically, then skip your event handlers if the variable is true.
Then, each time you set the slider in code, set the variable to true first, then back to false afterwords in a finally block.

Categories