OpenLayers3 : Draggable OverviewMapControl - controls

In OpenLayers 2, in the OverviewMapControl, you can drag the "box" to move the map.
You can not do this in OpenLayers 3.
I've tried to implement a custom control based on https://github.com/openlayers/ol3/blob/master/src/ol/control/overviewmapcontrol.js, but you can not use goog.xxx or other fancy stuff like ol.extent.scaleFromCenter when you are not in debug !
How should I proceed ?
basically, implementing drag'n drop is fairly "simple" :
var dragging = null;
var getMap = this.getMap.bind(this); //during ctor of a control, we have no access to the map !
$(document.body).on("mousemove", function (e) {
if (dragging) {
dragging.el.offset({
top: e.pageY,
left: e.pageX
});
}
});
$(box).on("mousedown", function (e) {
dragging = {
el: $(e.target)
};
});
$(document.body).on("mouseup", function (e) {
if (dragging) {
debugger;
var coords = ovmap.getEventCoordinate(e.originalEvent);
//TODO: taking event coordinates is not good, we must use center of the box coordinates
//the problem is that ovmap.getCoordinateFromPixel(dragging.el.offset()) is not working at all because we need to adjust ovmap viewport
getMap().getView().setCenter(coords);
dragging = null;
}
});

For those interested (which does not seem to be the case at the moment :)), here is the way I solved
/**
* Mostly a big copy/paste from https://raw.githubusercontent.com/openlayers/ol3/master/src/ol/control/overviewmapcontrol.js
* without rotation and zoom/dezoom plus some adapations from http://ol3.qtibia.ro/build/examples/overviewmap-custom-drag.html
* to add the possibility to drag the box on the minimap to move the main map
*/
ol.control.CustomOverviewMap = function (opt_options) {
var options = typeof opt_options !== 'undefined' ? opt_options : {};
this.collapsed_ = typeof options.collapsed !== 'undefined' ? options.collapsed : true;
this.onCollapseOrExpand = options.onCollapseOrExpand || function () { };
this.needFirstRenderUpdate_ = this.collapsed_; //prepare the hack to render the map when uncollapsed the first time
var tipLabel = typeof options.tipLabel !== 'undefined' ? options.tipLabel : 'Overview map';
this.collapseLabel_ = $('<span>\u00BB</span>').get(0);
this.label_ = $('<span>\u00AB</span>').get(0);
var activeLabel = (!this.collapsed_) ? this.collapseLabel_ : this.label_;
var button = $('<button type="button" title="{0}"></button>'.replace('{0}', tipLabel)).append(activeLabel);
button.on('click', this.handleClick_.bind(this));
//ol.control.Control.bindMouseOutFocusOutBlur(button);
button.on('mouseout', function () { this.blur(); });
button.on('focusout', function () { this.blur(); });
var ovmapDiv = $('<div class="ol-overviewmap-map"></div>').get(0);
this.ovmap_ = new ol.Map({
controls: new ol.Collection(),
interactions: new ol.Collection(),
layers: [options.tileLayer],
target: ovmapDiv,
view: new ol.View(opt_options.view)
});
var box = $('<div class="ol-overviewmap-box"></div>');
this.boxOverlay_ = new ol.Overlay({
position: [0, 0],
positioning: 'bottom-left',
element: box.get(0)
});
this.ovmap_.addOverlay(this.boxOverlay_);
var cssClasses = 'ol-overviewmap ol-unselectable ol-control' +
(this.collapsed_ ? ' ol-collapsed' : '');
var element = $('<div class="{0}"></div>'.replace('{0}', cssClasses)).append(ovmapDiv).append(button).get(0);
ol.control.Control.call(this, {
element: element,
render: ol.control.CustomOverviewMap.render
});
// deal with dragable minimap
this.dragging = null;
box.on("mousedown", this.onStartDrag.bind(this));
$(document.body).on("mousemove", this.onDrag.bind(this));
$(document.body).on("mouseup", this.onEndDrag.bind(this));
};
ol.inherits(ol.control.CustomOverviewMap, ol.control.Control);
ol.control.CustomOverviewMap.prototype.onStartDrag = function (e) {
// remember some data to use during onDrag or onDragEnd
var box = $(e.target);
this.dragging = {
el: box,
evPos: { top: e.pageY, left: e.pageX },
elPos: box.offset()
};
}
ol.control.CustomOverviewMap.prototype.onDrag = function (e) {
if (this.dragging) {
//set the position of the box to be oldPos+translation(ev)
var curOffset = this.dragging.el.offset();
var newOffset = {
top: curOffset.top + (e.pageY - this.dragging.evPos.top),
left: curOffset.left + (e.pageX - this.dragging.evPos.left)
};
this.dragging.evPos = { top: e.pageY, left: e.pageX };
this.dragging.el.offset(newOffset);
}
}
ol.control.CustomOverviewMap.prototype.onEndDrag = function (e) {
if (this.dragging) {
//see ol3.qtibia.ro href at the top of the class to understand this
var map = this.getMap();
var offset = this.dragging.el.position();
var divSize = [this.dragging.el.width(), this.dragging.el.height()];
var mapSize = map.getSize();
var c = map.getView().getResolution();
var xMove = offset.left * (Math.abs(mapSize[0] / divSize[0]));
var yMove = offset.top * (Math.abs(mapSize[1] / divSize[1]));
var bottomLeft = [0 + xMove, mapSize[1] + yMove];
var topRight = [mapSize[0] + xMove, 0 + yMove];
var left = map.getCoordinateFromPixel(bottomLeft);
var top = map.getCoordinateFromPixel(topRight);
var extent = [left[0], left[1], top[0], top[1]];
map.getView().fitExtent(extent, map.getSize());
map.getView().setResolution(c);
//reset the element at the original position so that when the main map will trigger
//the moveend event, this event will be replayed on the box of the minimap
this.dragging.el.offset(this.dragging.elPos);
this.dragging = null;
}
}
ol.control.CustomOverviewMap.render = function (mapEvent) {
//see original OverviewMap href at the top of the class to understand this
var map = this.getMap();
var ovmap = this.ovmap_;
var mapSize = map.getSize();
var view = map.getView();
var ovview = ovmap.getView();
var overlay = this.boxOverlay_;
var box = this.boxOverlay_.getElement();
var extent = view.calculateExtent(mapSize);
var ovresolution = ovview.getResolution();
var bottomLeft = ol.extent.getBottomLeft(extent);
var topRight = ol.extent.getTopRight(extent);
overlay.setPosition(bottomLeft);
// set box size calculated from map extent size and overview map resolution
if (box) {
var boxWidth = Math.abs((bottomLeft[0] - topRight[0]) / ovresolution);
var boxHeight = Math.abs((topRight[1] - bottomLeft[1]) / ovresolution);
$(box).width(boxWidth).height(boxHeight);
}
};
ol.control.CustomOverviewMap.prototype.handleClick_ = function (event) {
event.preventDefault();
this.collapsed_ = !this.collapsed_;
$(this.element).toggleClass('ol-collapsed');
// change label
if (this.collapsed_) {
this.collapseLabel_.parentNode.replaceChild(this.label_, this.collapseLabel_);
} else {
this.label_.parentNode.replaceChild(this.collapseLabel_, this.label_);
}
// manage overview map if it had not been rendered before and control is expanded
if (!this.collapsed_ && this.needFirstRenderUpdate_) {
this.needFirstRenderUpdate_ = false;
this.ovmap_.updateSize();
this.ovmap_.once("postrender", function () {
this.render();
}.bind(this));
}
//trigger event
this.onCollapseOrExpand(this.collapsed_);
};

Related

Mapbox GL Menu Doesn't Respond to First Click

Similar to this question, the layer switcher in my Map does not react to the first click. I learned that this issue has something to do with the definition of the initial visibility on the layers.
Here is the code. Unfortunately I don't know how and where to insert default visibility - do you have an idea?
map.on('click', ({ point }) => {
const features = map.queryRenderedFeatures(point, {
layers: ['City'] // replace with your layer name
});
if (!features.length) {
return;
}
const feature = features[0]; const popup = new mapboxgl.Popup({offset: [0, -15], closeButton: false, closeOnMove: true})
.setMaxWidth("auto")
.setLngLat(feature.geometry.coordinates)
.setHTML(
`<table>\
<tr>\
<td>City</td>\
<td>${feature.properties.City}</td>
</tr>\ </table>`
)
.addTo(map); }); var toggleableLayerIds = ['City']
for (var i = 0; i < toggleableLayerIds.length; i++) {
var id = toggleableLayerIds[i]
var link = document.createElement('a')
link.href = '#'
link.className = 'active'
link.textContent = id
link.onclick = function (e) {
var clickedLayer = this.textContent
e.preventDefault()
e.stopPropagation()
var visibility = map.getLayoutProperty(clickedLayer, 'visibility')
if (visibility === 'visible') {
map.setLayoutProperty(clickedLayer, 'visibility', 'none')
this.className = ''
} else {
this.className = 'active'
map.setLayoutProperty(clickedLayer, 'visibility', 'visible')
}
}
var layers = document.getElementById('menu')
layers.appendChild(link)
}

Moving element on Window scroll

You'll see in this JsFiddle https://jsfiddle.net/xpvt214o/402281/ there is an image scrolling within another one on window scroll.
How can I modify the below so that it doesn't start scrolling until it hits that element (after all the br tags)?
I've tried offsetting it but not getting anywhere.
It would also be fine if it just scrolled a lot slower.
jQuery(document).ready(
function() {
var $w = $(window);
var $d = $('.oh');
$(window).scroll(function(event) {
var st = $w.scrollTop();
_x = st;
lastScrollTop = st;
$d.css('bottom', _x);
});
});
Here's an example of what I'm trying to achieve https://www.sketchapp.com/
I found this which does what I'm looking for
https://codepen.io/JTParrett/pen/BkDie
$.fn.moveIt = function(){
var $window = $(window);
var instances = [];
$(this).each(function(){
instances.push(new moveItItem($(this)));
});
window.addEventListener('scroll', function(){
var scrollTop = $window.scrollTop();
instances.forEach(function(inst){
inst.update(scrollTop);
});
}, {passive: true});
}
var moveItItem = function(el){
this.el = $(el);
this.speed = parseInt(this.el.attr('data-scroll-speed'));
};
moveItItem.prototype.update = function(scrollTop){
this.el.css('transform', 'translateY(' + -(scrollTop / this.speed) +
'px)');
};
// Initialization
$(function(){
$('[data-scroll-speed]').moveIt();
});

Ckeditor scrollbar marker / Text Position Indicator

I would like to implement scrollbar marker into ckeditor and i can't seem to find the right way to do it i have triyed this code
var win = new CKEDITOR.dom.window( window );
var pos = win.getScrollPosition();
console.log(pos);
but it only return the google chrome scrollbar x=0 & Y=0
var win = new CKEDITOR.dom.window( domWindow );
var pos = win.getScrollPosition();
console.log(pos);
and this give me an error domWindow is not defined
i found this example it may help: https://codepen.io/Rplus/pen/mEjWJm
(() => {
var containerQS = '.article';
var container = document.querySelector(containerQS);
var form = document.querySelector('.form');
var input = form.querySelector('input[type="text"]');
var markClass = 'mark';
var markerHeight = '2px';
var _color = 'currentColor';
var containerY = container.offsetTop;
var containerH = container.scrollHeight;
var customStyle = document.createElement('style');
container.appendChild(customStyle);
var renderScrollMarker = ($parent, posArr) => {
var _posArr = posArr.map(i => {
return `transparent ${i}, ${_color} ${i}, ${_color} calc(${i} +
${markerHeight}), transparent calc(${i} + ${markerHeight})`;
});
customStyle.innerHTML = `article::-webkit-scrollbar-track {
background-image: linear-gradient(${_posArr.join()});
}`;
};
var calcEleRelativePos = ($ele) => {
return ($ele.offsetTop - containerY) / containerH;
};
var markOpt = {
className: markClass,
done: function () {
var marks = document.querySelectorAll(`.${markClass}`);
var allY = [].map.call(marks, (mark) => {
return (calcEleRelativePos(mark) * 100).toFixed(2) + '%';
});
renderScrollMarker(container, allY);
console.log(allY);
}
};
var instance = new Mark(container);
form.addEventListener('submit', (e) => {
e.preventDefault();
var _text = input.value.trim();
console.log(_text, form.oldText);
if (_text === '') {
instance.unmark(markOpt);
return;
}
form.oldText = _text;
instance.unmark().mark(_text, markOpt);
});
// trigger
form.querySelector('input[type="submit"]').click();
})();
but as ckeditor secures a lot of element, i would love to know if any one has done this before with CKeditor
i just got the real editor scrollbar position, i only need to put a marker using style or any availble methode
var win=CKEDITOR.instances.editor1.document.getWindow();
var pos = win.getScrollPosition().y;
console.log(pos);
this worked for me :
var jqDocument = $(editor.document.$);
var documentHeight = jqDocument.height();
var scrollTo =jqDocument.scrollTop();
var docHeight = jqDocument.height();
var scrollPercent = (scroll)/(docHeight);
var scrollPercentRounded = Math.round(scrollPercent*100);
$(".ui-slider-handle").css("bottom", 100-scrollPercentRounded+"%");

google map api not working for ajax from 2nd response onwards

In my application i have to show the path covered by an user in particulat date working fine for first response,from second response from ajax i am getting data which is diffrent from first one but still map showing 1st response result
I included google map javascript api like below in header section of html
<script src="https://maps.googleapis.com/maps/api/js?sensor=false"></script>
I am using following code in my jsp file
<script>
$(document).ready(function(){
window.setInterval(positionCheck, 20000);
});
</script>
<script>
$(document).ready(function(){
document.getElementById("directions_panel").innerHTML = "";
document.getElementById("map").innerHTML = "";
$("#searchSubmit").onclick(){
positionCheck();
}
});
</script>
<script type="text/javascript">
function positionCheck(){
var username=$("#xmlLabel").val();
var searchDate=$("#searchDate").val();
if(username!=""&& searchDate!=''){
This part where i used ajax call working fine for first response
from second response onwards problem arises it is showing content of first response from server
$.ajax({
type : "POST",
url : "searchLocation.mnt",
data :"xmlLabel="+username+"&searchDate="+searchDate,
dataType : "json",
mimeType : 'application/json',
success : function(data) {
if(data!=""){
mapLoaded(data);
function mapLoaded(data){
var size=0;
var counts=0;
var stops = data;
alert(stops);
size =stops.length;
if(stops.length>0){
var mapid=document.getElementById("map");
var map = new window.google.maps.Map(mapid);
// new up complex objects before passing them around
var directionsDisplay = new window.google.maps.DirectionsRenderer({suppressMarkers: true,polylineOptions: {
strokeColor: "black"
}});
var directionsService = new window.google.maps.DirectionsService();
Tour_startUp(stops);
window.tour.loadMap(map, directionsDisplay);
window.tour.fitBounds(map);
alert(stops.length);
if (stops.length > 1)
window.tour.calcRoute(directionsService, directionsDisplay);
}
alert(stops.length);
function Tour_startUp(stops) {
if (!window.tour) window.tour = {
updateStops: function (newStops) {
stops = newStops;
},
// map: google map object
// directionsDisplay: google directionsDisplay object (comes in empty)
loadMap: function (map, directionsDisplay) {
var myOptions = {
zoom:4,
center: new window.google.maps.LatLng(17.379818, 78.478542), // default to Hyderabad
mapTypeId: window.google.maps.MapTypeId.ROADMAP
};
map.setOptions(myOptions);
directionsDisplay.setMap(map);
},
fitBounds: function (map) {
var bounds = new window.google.maps.LatLngBounds();
// extend bounds for each record
jQuery.each(stops, function (key, val) {
var myLatlng = new window.google.maps.LatLng(val.latitude, val.longitude);
bounds.extend(myLatlng);
});
map.fitBounds(bounds);
},
calcRoute: function (directionsService, directionsDisplay) {
var batches = [];
var itemsPerBatch = 10; // google API max = 10 - 1 start, 1 stop, and 8 waypoints
var itemsCounter = 0;
var wayptsExist = stops.length > 0;
while (wayptsExist) {
var subBatch = [];
var subitemsCounter = 0;
for (var j = itemsCounter; j < stops.length; j++) {
subitemsCounter++;
subBatch.push({
location: new window.google.maps.LatLng(stops[j].latitude, stops[j].longitude),
stopover: true
});
if (subitemsCounter == itemsPerBatch)
break;
}
itemsCounter += subitemsCounter;
batches.push(subBatch);
wayptsExist = itemsCounter < stops.length;
// If it runs again there are still points. Minus 1 before continuing to
// start up with end of previous tour leg
itemsCounter--;
}
// now we should have a 2 dimensional array with a list of a list of waypoints
var combinedResults;
var unsortedResults = [{}]; // to hold the counter and the results themselves as they come back, to later sort
var directionsResultsReturned = 0;
for (var k = 0; k < batches.length; k++) {
var lastIndex = batches[k].length - 1;
var start = batches[k][0].location;
var end = batches[k][lastIndex].location;
// trim first and last entry from array
var waypts = [];
waypts = batches[k];
waypts.splice(0, 1);
waypts.splice(waypts.length - 1, 1);
var request = {
origin: start,
destination: end,
waypoints: waypts,
travelMode: window.google.maps.TravelMode.WALKING
};
(function (kk) {
directionsService.route(request, function (result, status) {
if (status == window.google.maps.DirectionsStatus.OK) {
var unsortedResult = { order: kk, result: result };
unsortedResults.push(unsortedResult);
directionsResultsReturned++;
if (directionsResultsReturned == batches.length) // we've received all the results. put to map
{
// sort the returned values into their correct order
unsortedResults.sort(function (a, b) { return parseFloat(a.order) - parseFloat(b.order); });
var count = 0;
for (var key in unsortedResults) {
if (unsortedResults[key].result != null) {
if (unsortedResults.hasOwnProperty(key)) {
if (count == 0) // first results. new up the combinedResults object
combinedResults = unsortedResults[key].result;
else {
// only building up legs, overview_path, and bounds in my consolidated object. This is not a complete
// directionResults object, but enough to draw a path on the map, which is all I need
combinedResults.routes[0].legs = combinedResults.routes[0].legs.concat(unsortedResults[key].result.routes[0].legs);
combinedResults.routes[0].overview_path = combinedResults.routes[0].overview_path.concat(unsortedResults[key].result.routes[0].overview_path);
combinedResults.routes[0].bounds = combinedResults.routes[0].bounds.extend(unsortedResults[key].result.routes[0].bounds.getNorthEast());
combinedResults.routes[0].bounds = combinedResults.routes[0].bounds.extend(unsortedResults[key].result.routes[0].bounds.getSouthWest());
}
count++;
}
}
}
directionsDisplay.setDirections(combinedResults);
var legs = combinedResults.routes[0].legs;
var summaryPanel = document.getElementById('directions_panel');
summaryPanel.innerHTML = '';
var totdist=0;
// alert(legs.length);
for (var i=0; i < legs.length;i++){
var markerletter = "A".charCodeAt(0);
var markerletter2= "B".charCodeAt(0)
markerletter += i;
markerletter2 += i;
markerletter = String.fromCharCode(markerletter);
markerletter2 = String.fromCharCode(markerletter2);
createMarker(directionsDisplay.getMap(),legs[i].start_location,legs[i].start_address,markerletter);//To display location address on the marker
var routeSegment = i + 1;
var point=+routeSegment+1;
summaryPanel.innerHTML += '<b>Route Segment: ' + routeSegment + '</b><br>';
summaryPanel.innerHTML += '<b>Point '+ routeSegment +' :</b>'+ ' ' +legs[i].start_address + ' <br> ';
summaryPanel.innerHTML += '<b>Point '+ point +' :</b>'+ ' '+legs[i].end_address + '<br>';
summaryPanel.innerHTML += '<b>Distance Covered '+' :</b>'+legs[i].distance.text + '<br><br>';
var test=legs[i].distance.text.split(' ');
var one=parseFloat(test[0]);
if(test[1]=="m"){
var one=parseFloat(test[0]/1000);
}
totdist=parseFloat(totdist)+parseFloat(one);
}
summaryPanel.innerHTML += '<b> Total Distance :'+totdist + 'km'+ '</b><br><br>';
var i=legs.length;
var markerletter = "A".charCodeAt(0);
markerletter += i;
markerletter = String.fromCharCode(markerletter);
createMarker(directionsDisplay.getMap(),legs[legs.length-1].end_location,legs[legs.length-1].end_address,markerletter);
}
}
});
})(k);
}
}
};
}
var infowindow = new google.maps.InfoWindow(
{
size: new google.maps.Size(150,50)
});
var icons = new Array();
icons["red"] = new google.maps.MarkerImage("mapIcons/marker_red.png",
// This marker is 20 pixels wide by 34 pixels tall.
new google.maps.Size(20, 34),
// The origin for this image is 0,0.
new google.maps.Point(0,0),
// The anchor for this image is at 9,34.
new google.maps.Point(9, 34));
function getMarkerImage(iconStr) {
counts++;
if(counts==size){
var markerimageLoc = "http://www.maps.google.com/mapfiles/ms/icons/blue.png";
}else{
if (iconStr=="undefined") {
iconStr = "red";
var markerimageLoc = "http://www.maps.google.com/mapfiles/ms/icons/red.png";
}
else{
var markerimageLoc="http://www.google.com/mapfiles/marker"+ iconStr +".png";
// var markerimageLoc = "http://www.maps.google.com/mapfiles/ms/icons/red.png";
}
}
icons[iconStr] = new google.maps.MarkerImage(markerimageLoc,
// This marker is 20 pixels wide by 34 pixels tall.
new google.maps.Size(25, 34),
// The origin for this image is 0,0.
new google.maps.Point(0,0),
// The anchor for this image is at 6,20.
new google.maps.Point(9, 34));
return icons[iconStr];
}
// Marker sizes are expressed as a Size of X,Y
// where the origin of the image (0,0) is located
// in the top left of the image.
// Origins, anchor positions and coordinates of the marker
// increase in the X direction to the right and in
// the Y direction down.
var iconImage = new google.maps.MarkerImage('mapIcons/marker_red.png',
// This marker is 20 pixels wide by 34 pixels tall.
new google.maps.Size(20, 34),
// The origin for this image is 0,0.
new google.maps.Point(0,0),
// The anchor for this image is at 9,34.
new google.maps.Point(9, 34));
var iconShadow = new google.maps.MarkerImage('http://www.google.com/mapfiles/shadow50.png',
// The shadow image is larger in the horizontal dimension
// while the position and offset are the same as for the main image.
new google.maps.Size(37, 34),
new google.maps.Point(0,0),
new google.maps.Point(9, 34));
// Shapes define the clickable region of the icon.
// The type defines an HTML <area> element 'poly' which
// traces out a polygon as a series of X,Y points. The final
// coordinate closes the poly by connecting to the first
// coordinate.
var iconShape = {
coord: [9,0,6,1,4,2,2,4,0,8,0,12,1,14,2,16,5,19,7,23,8,26,9,30,9,34,11,34,11,30,12,26,13,24,14,21,16,18,18,16,20,12,20,8,18,4,16,2,15,1,13,0],
type: 'poly'
};
function createMarker(map, latlng, label, character) {
var markerletter=character;
if( /[^a-zA-Z]/.test( character ) ) {
var markerletter="undefined";
}
var contentString = '<b>'+label+'</b><br>';
var marker = new google.maps.Marker({
position: latlng,
map: map,
shadow: iconShadow,
icon: getMarkerImage(markerletter),
shape: iconShape,
title: label,
zIndex: Math.round(latlng.lat()*-100000)<<5
});
marker.myname = label;
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(contentString);
infowindow.open(map,marker);
});
return marker;
}
}
}else{
}
},
error : function(e) {
alert('Error: ' + e,"Alert Box");
}
});
}
}
</script>
and i included div tag like this in body section
<div id="map" style="border: 2px solid #3872ac; height: 500px;"
class="col-sm-6"></div>
above code working fine if i am not using ajax,problem exist only for ajax
sorry to trouble all of you,i feel very silly that i declared variable of stops globally and i need to call methods like below
function initialize(data) {
size = 0;
counts = 0;
var map=0;
var stops = data;
size = stops.length;
if (stops.length > 0) {
var map = new window.google.maps.Map(document
.getElementById("map"));
// new up complex objects before passing them around
var directionsDisplay = new window.google.maps.DirectionsRenderer(
{
suppressMarkers : true,
polylineOptions : {
strokeColor : "black"
}
});
var directionsService = new window.google.maps.DirectionsService();
Tour_startUp(stops);
window.tour.loadMap(map, directionsDisplay);
i changed the below methods from window.tour.fitBounds(map); window.tour.calcRoute(stops,directionsService,
directionsDisplay); to
window.tour.fitBounds(map,stops);
if (stops.length > 1)
window.tour.calcRoute(stops,directionsService,
directionsDisplay);
}
}

How to get Famo.us draggable modifier's render node

I am trying to get parent renderNode of a draggable modifier on 'end' event, is there any api to get a renderNode to which draggable belongs to? My code is as follows :
/*globals define*/
define(function(require, exports, module) {
var View = require('famous/core/View');
var Surface = require('famous/core/Surface');
var Transform = require('famous/core/Transform');
var StateModifier = require('famous/modifiers/StateModifier');
var Draggable = require("famous/modifiers/Draggable");
var RenderNode = require('famous/core/RenderNode');
/*
* #name DragTest
* #constructor
* #description
*/
function DragTest() {
View.apply(this, arguments);
_createDragSurface.call(this);
}
DragTest.prototype = Object.create(View.prototype);
DragTest.prototype.constructor = DragTest;
DragTest.DEFAULT_OPTIONS = {
};
function _createDragSurface(){
var yOffset=0;
for(var i=0;i<2;i++){
var draggable = new Draggable({
xRange: [-220,0],
yRange: [0,0]
});
var dragSurface= new Surface({
content:'this is a drag surface',
size:[150,150],
properties:{
marginLeft: '10px',
backgroundColor:'grey'
}
});
var dragSurfaceModifier= new StateModifier({
align:[0.5,yOffset]
});
yOffset+=0.3;
dragSurface.pipe(draggable);
draggable.on('end',function(e){
this.setPosition([0,0,0], {
method: 'snap',
period: 300
});
});
var nodePlayer = new RenderNode(draggable);
nodePlayer.add(dragSurfaceModifier).add(dragSurface);
this.add(nodePlayer);
}
}
module.exports = DragTest;
});
On drag of a surface to the left, once it reaches threshold, I want to remove the renderNode i.e.,
draggable.on('end',function(e){
if(e.position[0]<-50){
renderNode.remove()//how to achieve this part of the code as I dont have an access to nodePlayer renderNode here.
}
else{
this.setPosition([0,0,0], {
method: 'snap',
period: 300
});
}
});
If I simply use the name of a renderNode i.e., nodePlayer it will remove the last surface no matter which surface is been dragged.Any input on this is much appreciated.
Best Regards.
There are a lot of ways to accomplish what you want to do.
Since you are using the end event on the draggable and using the position value from the custom event, let's bind the references to the needed items to be able to access them.
There is not a .remove() method on the RenderNode so the example shows a way you could remove a node from the view with a RenderController.
Remember: There is no need to remove nodes from the DOM. Famo.us will manage the renderables in the render tree.
define('main', function(require, exports, module) {
var Engine = require('famous/core/Engine');
var Surface = require('famous/core/Surface');
var Transform = require('famous/core/Transform');
var Modifier = require('famous/core/Modifier');
var StateModifier = require('famous/modifiers/StateModifier');
var Draggable = require('famous/modifiers/Draggable');
var TransitionableTransform = require('famous/transitions/TransitionableTransform');
var DragTest = require('DragTest');
var mainContext = Engine.createContext();
var dragTest = new DragTest();
mainContext.add(dragTest);
dragTest.on('removed', function(e) {
console.log('removed ', e.removedNode);
});
});
define('DragTest', function(require, exports, module) {
var View = require('famous/core/View');
var Surface = require('famous/core/Surface');
var Transform = require('famous/core/Transform');
var StateModifier = require('famous/modifiers/StateModifier');
var Draggable = require("famous/modifiers/Draggable");
var RenderNode = require('famous/core/RenderNode');
var RenderController = require('famous/views/RenderController');
/*
* #name DragTest
* #constructor
* #description
*/
function DragTest() {
View.apply(this, arguments);
_createDragSurface.call(this);
}
DragTest.prototype = Object.create(View.prototype);
DragTest.prototype.constructor = DragTest;
DragTest.DEFAULT_OPTIONS = {};
function _endingDrag(e) {
console.log('end position', e.position, this);
if (e.position[0] < -180) {
this.renderController.hide(this.nodePlayer, function() {
this.surface.emit('removed', {
removedNode: this.nodePlayer
});
}.bind(this));
} else {
this.draggable.setPosition([0, 0, 0], {
duration: 300
});
}
}
function _updatingDrag(e) {
console.log('update position', e.position);
this.surface.setContent('Position ' + e.position);
}
function _createDragSurface() {
var yOffset = 0;
for (var i = 0; i < 2; i++) {
var dragSurface = new Surface({
content: 'this is a drag surface',
size: [150, 150],
properties: {
marginLeft: '10px',
backgroundColor: 'grey'
}
});
var dragSurfaceModifier = new StateModifier({
origin: [0, 0],
align: [0.5, yOffset]
});
yOffset += 0.3;
var draggable = new Draggable({
xRange: [-220, 0],
yRange: [0, 0]
});
var renderController = new RenderController();
this.add(renderController);
var nodePlayer = new RenderNode();
nodePlayer.add(dragSurfaceModifier).add(draggable).add(dragSurface);
renderController.show(nodePlayer)
draggable.on('end', _endingDrag.bind({
draggable: draggable,
renderController: renderController,
nodePlayer: nodePlayer,
surface: dragSurface
}));
draggable.on('update', _updatingDrag.bind({
surface: dragSurface
}));
draggable.subscribe(dragSurface);
dragSurface.pipe(this._eventOutput); // so we can emit a custom removed event to this widget
}
}
module.exports = DragTest;
});
require(['main']);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://requirejs.org/docs/release/2.1.16/minified/require.js"></script>
<script src="http://code.famo.us/lib/requestAnimationFrame.js"></script>
<script src="http://code.famo.us/lib/classList.js"></script>
<script src="http://code.famo.us/lib/functionPrototypeBind.js"></script>
<link rel="stylesheet" type="text/css" href="http://code.famo.us/famous/0.3.5/famous.css" />
<script src="http://code.famo.us/famous/0.3.5/famous.min.js"></script>

Resources