Adding an opacity slider to an Openlayers map - javascript

It is straightforward to add an opacity slider for a raster layer using this line of code:
layer.setOpacity(this.value) to lyr_MyMapImage.setOpacity(this.value)
But this is untidy as the slider is located above the map.
How can I insert a slider (horizontal or vertical) onto the map to control the opacity of the layer so that it looks similar to the other map controls? Is there a plugin?
Thanks.

you can use jQuery slider. Example below:
$("#sliderLayer").slider({
min: 0,
max: 100,
value: 100,
slide: function(event, e) {
lyr_MyMapImage.setOpacity(e.value / 100);
},
disabled: true
});
Also, here is jsFiddle:
https://jsfiddle.net/Svinjica/L7edtgx3/19/
Hope it helps:)

In my jsfiddle I position the slider inside a proper openlayers custom control:
const sliderita = document.createElement('div');
sliderita.className = 'ol-control ol-unselectable slider';
sliderita.innerHTML = '<div id="sliderOSM"> <div id="custom-handle" class="ui-slider-handle"></div></div>';
map.addControl(new ol.control.Control({element: sliderita}));
https://jsfiddle.net/5w6sahx4/5/

Related

Facing problem while moving svg polygon to center on click

I have an SVG image which is made up to multiple polygons. When I click on any of the polygons then that polygon will come up in the center after moving the whole SVG image automatically.
I have tried tweenmax library for this and here is the code snippet :
jQuery('[data-name^="retailer_"]').on('click', function (event) {
var ActiveFloorValue = jQuery('#mapit-floors-filters a.active').attr('data-floor-index');
jQuery('polygon').attr("class","");
var map_store_name = jQuery(this).data('name');
jQuery('#mapit-floor-'+ActiveFloorValue+ ' svg').attr('id','svg-'+ActiveFloorValue);
var main1x = document.getElementById('mapit-floor-'+ActiveFloorValue);
TweenLite.to( main1x, 0, { ease: Linear.easeOut, clearProps:"scale"});
TweenMax.to(main1x, 1.5, {
scale: 1.9,
x:-event.clientX/2 ,
y:-event.clientY/2 ,
ease:Linear.easeOut,
transformOrigin:"center center"
})
});
So please help me to make it possible. I hope you understand my question.
Thanks in advance.

Adding filter to pattern image of shape in fabric.js

I am trying to apply a filter to the pattern image of shape but receiving numerous errors. I googled a lot but still cannot find a solution that works. Below is my code. Q 1. Is it even possible? Q 2. How to achieve it!?
var canvas = new fabric.Canvas('c1');
var circle = new fabric.Circle({
radius: 100, fill: 'green', left: 100, top: 100
});
canvas.add(circle);
loadPattern('http://i0.wp.com/www.illustratoring.com/wp-content/uploads/2012/12/chevron-pattern-illustrator.png?resize=40%2C40', circle);
function loadPattern(url, obj){
fabric.util.loadImage(url, function(img) {
obj.setPatternFill({
source: img,
repeat: 'repeat'
});
canvas.renderAll();
});
}
here is the JSfilddle https://jsfiddle.net/eepmzy9n/2/ I want to apply filters to the pattern image.
Yes, this should be possible using the fabric js filters. Combining patterns and filters shouldn't be an issue.
Info on image filters:
http://fabricjs.com/fabric-intro-part-2/#image_filters
http://fabricjs.com/image-filters/
Other code examples using filters:
Fabric js image filter
How to apply filter to canvas backgroundImage in Fabric.js

Ion.RangeSlider color from middle

I'm trying to use Ion.RangeSlider to make a slider where the color starts from the center and goes in the direction of the slider control until it hits the slider control. Right now, this is what I have:
Instead, I would like the color to go from the center of the slider to the slider control.
How can I make the RangeSlider work like that so that the color starts from the middle (as shown above)?
EDIT:
I looked at this question, but it deals with sliders with two controls instead one.
EDIT 1:
setup.js:
jQuery(document).ready(function($){
$(".slider").each(function() {
console.log($(this).attr("id"));
$(this).ionRangeSlider({
type: $(this).attr("data-slider_type"),
grid: $(this).attr("data-slider_grid"),
min: $(this).attr("data-slider_min"),
max: $(this).attr("data-slider_max"),
prefix: $(this).attr("data-slider_prefix")+" ",
postfix: " " + $(this).attr("data-slider_suffix"),
step: $(this).attr("data-slider_stepper"),
from: $(this).attr("data-slider_from")
});
$(this).on("change", function () {
var $this = $(this),
value = $this.prop("value").split(";");
});
});
});
Use: https://github.com/jordansoltman/ion.rangeSlider with has the additional boolean option: fixMiddle. For example:
$(".slider").ionRangeSlider({
fixMiddle: true,
...
});
Note: use ion.rangeSlider.js as ion.rangeSlider.min.js has not been updated.

OpenLayers setOpacity fails with multiple layers in selectFeature

Using OpenLayers 2.13. I have a map with 2 vector layers, and a JQuery slider which allows adjustment of the layer opacity.
If I set up a selector to include both layers (for highlighting and popups), my JQuery slider to adjust the opacity doesn't work (layername.setOpacity(x) fails to set the opacity of the layer). If only one layer participates in the selector then setOpacity works fine. Both layers use the same styleMap.
$("#slider-id").slider({
value: 70,
min: 10,
max: 100,
step: 10,
slide: function(e, ui) {
layer1.setOpacity(ui.value / 100);
layer2.setOpacity(ui.value / 100);
} });
This selector allows the opacity to be set for both layers:
var selector = new OpenLayers.Control.SelectFeature(layer1,{
hover:false
});
But this selector does not (setOpacity() fails no matter what):
var selector = new OpenLayers.Control.SelectFeature([layer1, layer2],{
hover:false
});
The Selector is added and activated.
map.addControl(selector);
selector.handlers.feature.stopDown = false; //allow dragging on map
selector.activate();
Is there some way to have multiple layers participate in the selector, while allowing the opacity to be changed?
It might be bad form to answer your own question, but I found a workaround and am posting it here for anyone else with this problem.
Deactivate the selector before changing the opacity.
$("#slider-id").slider({
value: 70,
min: 10,
max: 100,
step: 10,
slide: function(e, ui) {
selector.deactivate();
layer1.setOpacity(ui.value / 100);
layer2.setOpacity(ui.value / 100);
selector.activate();
}

Zoom and Pan in KineticJS

Is there a way one could zoom and pan on a canvas using KineticJS? I found this library kineticjs-viewport, but just wondering if there is any other way of achieving this because this library seems to be using so many extra libraries and am not sure which ones are absolutely necessary to get the job done.
Alternatively, I am even open to the idea of drawing a rectangle around the region of interest and zooming into that one particular area. Any ideas on how to achieve this? A JSFiddle example would be awesome!
You can simply add .setDraggable("draggable") to a layer and you will be able to drag it as long as there is an object under the cursor. You could add a large, transparent rect to make everything draggable. The zoom can be achieved by setting the scale of the layer. In this example I'm controlling it though the mousewheel, but it's simply a function where you pass the amount you want to zoom (positive to zoom in, negative to zoom out). Here is the code:
var stage = new Kinetic.Stage({
container: "canvas",
width: 500,
height: 500
});
var draggableLayer = new Kinetic.Layer();
draggableLayer.setDraggable("draggable");
//a large transparent background to make everything draggable
var background = new Kinetic.Rect({
x: -1000,
y: -1000,
width: 2000,
height: 2000,
fill: "#000000",
opacity: 0
});
draggableLayer.add(background);
//don't mind this, just to create fake elements
var addCircle = function(x, y, r){
draggableLayer.add(new Kinetic.Circle({
x: x*700,
y: y*700,
radius: r*20,
fill: "rgb("+ parseInt(255*r) +",0,0)"
})
);
}
var circles = 300
while (circles) {
addCircle(Math.random(),Math.random(), Math.random())
circles--;
}
var zoom = function(e) {
var zoomAmount = e.wheelDeltaY*0.001;
draggableLayer.setScale(draggableLayer.getScale().x+zoomAmount)
draggableLayer.draw();
}
document.addEventListener("mousewheel", zoom, false)
stage.add(draggableLayer)
http://jsfiddle.net/zAUYd/
Here's a very quick and simple implementation of zooming and panning a layer. If you had more layers which would need to pan and zoom at the same time, I would suggest grouping them and then applying the on("click")s to that group to get the same effect.
http://jsfiddle.net/renyn/56/
If it's not obvious, the light blue squares in the top left are clicked to zoom in and out, and the pink squares in the bottom left are clicked to pan left and right.
Edit: As a note, this could of course be changed to support "mousedown" or other events, and I don't see why the transformations couldn't be implemented as Kinetic.Animations to make them smoother.
this is what i have done so far.. hope it will help you.
http://jsfiddle.net/v1r00z/ZJE7w/
I actually wrote kineticjs-viewport. I'm happy to hear you were interested in it.
It is actually intended for more than merely dragging. It also allows zooming and performance-focused clipping. The things outside of the clip region aren't rendered at all, so you can have great rendering performance even if you have an enormous layer with a ton of objects.
That's the use case I had. For example, a large RTS map which you view via a smaller viewport region -- think Starcraft.
I hope this helps.
As I was working with Kinetic today I found a SO question that might interest you.
I know it would be better as a comment, but I don't have enough rep for that, anyway, I hope that helps.
These answers seems not to work with the KineticJS 5.1.0. These do not work mainly for the signature change of the scale function:
stage.setScale(newscale); --> stage.setScale({x:newscale,y:newscale});
However, the following solution seems to work with the KineticJS 5.1.0:
JSFiddle: http://jsfiddle.net/rpaul/ckwu7u86/3/
Unfortunately, setting state or layer draggable prevents objects not draggable.
Duopixel's zooming solution is good, but I would rather set it for stage level, not layer level.
Her is my solution
var stage = new Kinetic.Stage({
container : 'container',
width: $("#container").width(),
height: $("#container").height(),
});
var layer = new Kinetic.Layer();
//layer.setDraggable("draggable");
var center = { x:stage.getWidth() / 2, y: stage.getHeight() / 2};
var circle = new Kinetic.Circle({
x: center.x-100,
y: center.y,
radius: 50,
fill: 'green',
draggable: true
});
layer.add(circle);
layer.add(circle.clone({x: center.x+100}));
// zoom by scrollong
document.getElementById("container").addEventListener("mousewheel", function(e) {
var zoomAmount = e.wheelDeltaY*0.0001;
stage.setScale(stage.getScale().x+zoomAmount)
stage.draw();
e.preventDefault();
}, false)
// pan by mouse dragging on stage
stage.on("dragstart dragmove", function(e) {window.draggingNode = true;});
stage.on("dragend", function(e) { window.draggingNode = false;});
$("#container").on("mousedown", function(e) {
if (window.draggingNode) return false;
if (e.which==1) {
window.draggingStart = {x: e.pageX, y: e.pageY, stageX: stage.getX(), stageY: stage.getY()};
window.draggingStage = true;
}
});
$("#container").on("mousemove", function(e) {
if (window.draggingNode || !window.draggingStage) return false;
stage.setX(window.draggingStart.stageX+(e.pageX-window.draggingStart.x));
stage.setY(window.draggingStart.stageY+(e.pageY-window.draggingStart.y));
stage.draw();
});
$("#container").on("mouseup", function(e) { window.draggingStage = false } );
stage.add(layer);
http://jsfiddle.net/bighostkim/jsqJ2/

Categories

Resources