Error while trying to export gee data and display appears (Error code: 3) - google-earth-engine

when I export the GEE data it appears
Error: Image.clipToBoundsAndScale, argument 'input': Invalid type.
Expected type: Image. Actual type: FeatureCollection.
(Error code: 3)
can you help me solve it
following is the script code
var maskL8 = function(image) {
var qa = image.select('BQA');
var mask = qa.bitwiseAnd(1 << 4).eq(0);
return image.updateMask(mask);
}
var composite = ee.ImageCollection('LANDSAT/LC08/C01/T1_TOA')
.filterDate('2021-01-01', '2021-12-31')
.filterBounds(geometry)
.map(maskL8)
.median().clip(geometry);
//visualisasi citra
var RGBTrue = composite.select(['B2', 'B4', 'B7']);
var RGBparam = { min: 0, max: 0.2,};
Map.addLayer(RGBTrue, RGBparam, 'TRUE');
var aoi = vegetasi.merge(badan_air).merge(lahan_terbangun).merge(tegalan)
.merge(rumput).merge(industri).merge(kosong).merge(sawah);
var bands = ['B1','B2','B3','B4','B5','B6','B7'];
var training = composite.select(bands).sampleRegions({
collection: aoi,
properties: ['lc'],
scale: 30
});
var classifier = ee.Classifier.smileCart().train({
features: training,
classProperty: 'lc',
inputProperties: bands
});
var classified = composite.select(bands).classify(classifier);
Map.addLayer(classified,
{min: 0, max: 7, palette:['darkgreen','blue','red','darkblue','green','orange','yellow', 'brown']},
'classification');
//Klasifikasi
var uji_aoi = uji_akurasi_vegetasi.merge(uji_akurasi_badanair).merge(uji_akurasi_lahanterbangun).merge(uji_akurasi_tegalan)
.merge(uji_akurasi_rumput).merge(uji_akurasi_industri).merge(uji_akurasi_kosong).merge(uji_akurasi_sawah);
var validasi = classified.sampleRegions({
collection: uji_aoi,
properties: ['lc'],
scale: 30,
});
print(validasi);
var akurasi = validasi.errorMatrix('lc', 'classification');
print('Confusion matrix', akurasi);
print('Overall accuracy: ', akurasi.accuracy());
var class_areas = ee.Image.pixelArea().divide(1000*1000).addBands(classified)
.reduceRegion({
reducer: ee.Reducer.sum().group({
groupField: 1,
groupName: 'code',
}),
geometry: geometry,
maxPixels : 500000000,
scale: 30,
}).get('groups');
print(class_areas);
//legenda
var panel = ui.Panel({
style: {
position: 'bottom-left',
padding: '5px;'
}
})
var title = ui.Label({
value: 'Klasifikasi Tutupan Lahan',
style: {
fontSize: '14px',
fontWeight: 'bold',
margin: '0px;'
}
})
panel.add(title)
var color = ['darkgreen','blue','red','darkblue','green','orange','yellow', 'brown']
var lc_class = ['Vegetasi', 'Lahan Terbangun', 'Sawah', 'Badan Air','Lahan Kosong','Rerumputan','Industri','Tegalan']
var list_legend = function(color, description) {
var c = ui.Label({
style: {
backgroundColor: color,
padding: '10px',
margin: '4px'
}
})
var ds = ui.Label({
value: description,
style: {
margin: '5px'
}
})
return ui.Panel({
widgets: [c, ds],
layout: ui.Panel.Layout.Flow('horizontal')
})
}
for(var a = 0; a < 8; a++){
panel.add(list_legend(color[a], lc_class[a]))
}
Map.add(panel)
// Export the image, specifying the CRS, transform, and region.
Export.image.toDrive({
image: geometry,
description: 'imageToDriveExample_transform',
region: geometry
});
I try to export data but the result is always the same. Is there an error in this code?

Related

How to remove maplabel library and polygon in Google Map API

I'm using google maps API to allow the user draw polygons and display the length of every single border using maplabel library. But I have a problem when removing polygon and map label, I don't know how to remove them from Google Map.
My code looks like this:
HTML
<button id="enablePolygon">draw</button>
<button id="removePolygon">remove</button>
<div id="map"></div>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&libraries=drawing"></script>
<script src="https://cdn.jsdelivr.net/npm/js-map-label#1.0.1/src/maplabel.js"></script>
JS
var labels = [];
var allOverlays = [];
function setSelection(shape) {
selectedShape = shape;
shape.setEditable(true);
}
function initMap() {
var options = {
zoom: 14,
center: {
lat: 52.250618,
lng: 20.9774
}
};
var map = new google.maps.Map(document.getElementById("map"), options);
var drawingManager = new google.maps.drawing.DrawingManager({
polygonOptions: {
draggable: false,
fillColor: "#0e97fa",
fillOpacity: 0.2,
strokeWeight: 2,
strokeColor: "#0e97fa",
editable: true,
zIndex: 1
},
drawingControl: false,
drawingControlOptions: {
position: google.maps.ControlPosition.TOP_CENTER,
drawingModes:
[
google.maps.drawing.OverlayType.POLYGON,
/* google.maps.drawing.OverlayType.POLYLINE, */
]
},
map: map,
drawingMode: 'polygon'
});
function attachPolygonInfoWindow(polygon) {
if (!polygon.labels) polygon.labels = [];
for (var i = 0; i < polygon.labels.length; i++) {
polygon.labels[i].setMap(null);
}
polygon.labels = [];
var path = polygon.getPath();
var points = path.getArray();
var area = google.maps.geometry.spherical
.computeArea(path.getArray())
.toFixed(0);
var bounds = new google.maps.LatLngBounds();
var i;
for (i = 0; i < points.length; i++) {
bounds.extend(points[i]);
}
var boundsCenter = bounds.getCenter();
var centerLabel = new MapLabel({
map: map,
position: boundsCenter,
fontSize: 14,
align: "center",
zIndex: 3
});
polygon.labels.push(centerLabel);
centerLabel.set("position", bounds.getCenter());
centerLabel.set("text", area + " m2");
if (path.getLength() < 2) return;
for (var i = 0; i < polygon.getPath().getLength(); i++) {
// for each side in path, compute center and length
var start = polygon.getPath().getAt(i);
var end = polygon.getPath().getAt(i < polygon.getPath().getLength() - 1 ? i + 1 : 0);
var sideLength = google.maps.geometry.spherical.computeDistanceBetween(start, end);
console.log(sideLength)
var sideCenter = google.maps.geometry.spherical.interpolate(start, end, 0.5);
/* console.log("sideCenter=" + sideCenter.toUrlValue(6)); */
var sideLabel = new MapLabel({
map: map,
fontSize: 14,
align: "center",
zIndex: 3
});
sideLabel.set("position", sideCenter);
sideLabel.set("text", sideLength.toFixed(2) + "m");
polygon.labels.push(sideLabel);
}
}
function removePolygonInfoWindow() {
for (var i = 0; i < labels.length; i++) {
labels[i].setMap(null);
}
labels = [];
}
google.maps.event.addListener(drawingManager, "overlaycomplete", function(e) {
allOverlays.push(e);
if (e.type != google.maps.drawing.OverlayType.MARKER) {
drawingManager.setDrawingMode(null);
var newShape = e.overlay;
newShape.type = e.type;
google.maps.event.addListener(newShape, "click", function() {
setSelection(newShape);
});
if (newShape.type == "polygon") {
var path = newShape.getPath();
google.maps.event.addListener(path, "insert_at", function() {
attachPolygonInfoWindow(newShape);
});
google.maps.event.addListener(path, "set_at", function() {
attachPolygonInfoWindow(newShape);
});
attachPolygonInfoWindow(newShape);
}
setSelection(newShape);
}
});
var enablePolygon = document.getElementById('enablePolygon');
enablePolygon.addEventListener('click', function(){
drawingManager.setMap(map);
drawingManager.setDrawingMode(google.maps.drawing.OverlayType.POLYGON);
});
var removePolygon = document.getElementById('removePolygon');
removePolygon.addEventListener('click', function(){
selectedShape.setMap(null);
drawingManager.setMap(null);
centerLabel.setRemoveLabel(true);
});
}
initMap();
Here is demo
I get a javascript error with the posted code: Uncaught ReferenceError: centerLabel is not defined. Not sure why you are using that variable, you are saving the labels in a property of the polygons labels. To remove them, iterate through that array, calling .setMap(null) on each label.
removePolygon.addEventListener('click', function() {
selectedShape.setMap(null);
drawingManager.setMap(null);
for (var i = 0; i < selectedShape.labels.length; i++) {
selectedShape.labels[i].setMap(null);
}
});
updated fiddle
code snippet:
var labels = [];
var allOverlays = [];
function setSelection(shape) {
selectedShape = shape;
shape.setEditable(true);
}
function initMap() {
var options = {
zoom: 14,
center: {
lat: 52.250618,
lng: 20.9774
}
};
var map = new google.maps.Map(document.getElementById("map"), options);
var drawingManager = new google.maps.drawing.DrawingManager({
polygonOptions: {
draggable: false,
fillColor: "#0e97fa",
fillOpacity: 0.2,
strokeWeight: 2,
strokeColor: "#0e97fa",
editable: true,
zIndex: 1
},
drawingControl: false,
drawingControlOptions: {
position: google.maps.ControlPosition.TOP_CENTER,
drawingModes: [
google.maps.drawing.OverlayType.POLYGON,
/* google.maps.drawing.OverlayType.POLYLINE, */
]
},
map: map,
drawingMode: 'polygon'
});
function attachPolygonInfoWindow(polygon) {
if (!polygon.labels) polygon.labels = [];
for (var i = 0; i < polygon.labels.length; i++) {
polygon.labels[i].setMap(null);
}
polygon.labels = [];
var path = polygon.getPath();
var points = path.getArray();
var area = google.maps.geometry.spherical
.computeArea(path.getArray())
.toFixed(0);
var bounds = new google.maps.LatLngBounds();
var i;
for (i = 0; i < points.length; i++) {
bounds.extend(points[i]);
}
var boundsCenter = bounds.getCenter();
var centerLabel = new MapLabel({
map: map,
position: boundsCenter,
fontSize: 14,
align: "center",
zIndex: 3
});
polygon.labels.push(centerLabel);
centerLabel.set("position", bounds.getCenter());
centerLabel.set("text", area + " m2");
if (path.getLength() < 2) return;
for (var i = 0; i < polygon.getPath().getLength(); i++) {
// for each side in path, compute center and length
var start = polygon.getPath().getAt(i);
var end = polygon.getPath().getAt(i < polygon.getPath().getLength() - 1 ? i + 1 : 0);
var sideLength = google.maps.geometry.spherical.computeDistanceBetween(start, end);
console.log(sideLength)
var sideCenter = google.maps.geometry.spherical.interpolate(start, end, 0.5);
/* console.log("sideCenter=" + sideCenter.toUrlValue(6)); */
var sideLabel = new MapLabel({
map: map,
fontSize: 14,
align: "center",
zIndex: 3
});
sideLabel.set("position", sideCenter);
sideLabel.set("text", sideLength.toFixed(2) + "m");
polygon.labels.push(sideLabel);
}
}
function removePolygonInfoWindow() {
for (var i = 0; i < labels.length; i++) {
labels[i].setMap(null);
}
labels = [];
}
google.maps.event.addListener(drawingManager, "overlaycomplete", function(e) {
allOverlays.push(e);
if (e.type != google.maps.drawing.OverlayType.MARKER) {
drawingManager.setDrawingMode(null);
var newShape = e.overlay;
newShape.type = e.type;
google.maps.event.addListener(newShape, "click", function() {
setSelection(newShape);
});
if (newShape.type == "polygon") {
var path = newShape.getPath();
google.maps.event.addListener(path, "insert_at", function() {
attachPolygonInfoWindow(newShape);
});
google.maps.event.addListener(path, "set_at", function() {
attachPolygonInfoWindow(newShape);
});
attachPolygonInfoWindow(newShape);
}
setSelection(newShape);
}
});
var enablePolygon = document.getElementById('enablePolygon');
enablePolygon.addEventListener('click', function() {
drawingManager.setMap(map);
drawingManager.setDrawingMode(google.maps.drawing.OverlayType.POLYGON);
});
var removePolygon = document.getElementById('resetPolygon');
removePolygon.addEventListener('click', function() {
selectedShape.setMap(null);
drawingManager.setMap(null);
for (var i = 0; i < selectedShape.labels.length; i++) {
selectedShape.labels[i].setMap(null);
}
});
}
initMap();
html,
body,
#map {
height: 100%;
margin: 0;
padding: 0;
}
<button id="enablePolygon">draw</button>
<button id="resetPolygon">remove</button>
<div id="map"></div>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&libraries=drawing"></script>
<script src="https://cdn.jsdelivr.net/npm/js-map-label#1.0.1/src/maplabel.js"></script>

Evenly distribute a given number of segments along an existing path

without seeing the codepen it is tricky to explain my situation, but here goes. I'm creating some paths by getting pathData using opentype.js. I am then placing random shapes at the position of the path's segment's points. Because of the nature of a font's paths some paths have far more segments than others for example '1' has way fewer segments thant '0'. I would like to average out the number of segments along each path so that when I add the shapes they look a consistent number of segments. Thanks in advance.
Is it possible to evenly distribute a given number of segments along an existing path?
Here is a link to the Codepen
paper.install(window);
const minMax = (min, max) => {
return Math.floor(Math.random() * max + min);
};
window.onload = () => {
paper.setup("canvas");
let pathData;
const font = opentype.load(
"https://assets.codepen.io/1070/pphatton-ultralight-webfont.woff",
(err, font) => {
if (err) {
console.log(err);
} else {
class Doughnut {
constructor(x, y) {
this.x = x;
this.y = y;
this.shape = new paper.Path.RegularPolygon({
position: [this.x, this.y],
sides: minMax(3, 8),
radius: minMax(6, 12),
fillColor: "black"
});
}
// makeShape(){
// this.shape
// }
}
pathData = font.getPath("100", 0, 600, 600).toSVG();
// const rect = new paper.Path.Rectangle({
// point: [80, 25],
// size: [300, 200],
// fillColor: "black"
// });
const number = new paper.Path(pathData);
number.selected = true;
// number.flatten(10);
const amount = 50;
const length = number.length
const points = [];
const segments = number.segments;
number.fitBounds(paper.view.bounds);
for(let i = 0; i < amount; i++){
const offset = i / amount * length
const point = number.getPointAt(offset)
new Doughnut(point.x, point.y);
}
segments.forEach((seg) => {
points.push(number.getPointAt(seg));
});
points.forEach((point) => {
console.log(point);
new Doughnut(point.x, point.y);
});
number.reduce();
}
}
);
const shapes = [];
class Doughnut {
constructor(x, y) {
this.x = x;
this.y = y;
this.shape = new paper.Path.RegularPolygon({
position: [this.x, this.y],
sides: minMax(3, 8),
radius: minMax(6, 12),
fillColor: "black"
});
}
// makeShape(){
// this.shape
// }
}
// for (let i = 0; i < 10; i++) {
// shapes.push(new Doughnut(minMax(100, 500), minMax(100, 500)));
// }
// console.log(shapes)
// shapes.makeShape()
};
The path.divideAt() method can help you greatly.
What is tricky in your case is that, in order to preserve the path appearance, you can't move the existing segments. So you'll have to find a way to only add segment where it is needed.
Otherwise, here's a simple sketch demonstrating a possible solution. It should get you on the track to find a solution more specific to your use case.
const circle = new Path.Circle({
center: [0, 0],
radius: 75,
selected: true
});
const rectangle = new Path.Rectangle({
from: [0, 0],
to: [200, 100],
selected: true
});
rectangle.position = circle.position + [circle.bounds.width + rectangle.bounds.width, 0];
const cloneAndAddSegments = (item) => {
const clone = item.clone().translate(0, 200);
const length = clone.length;
const step = 20;
const iterations = Math.floor(length / step);
for (let i = 1; i <= iterations; i++) {
const offset = i * step;
clone.divideAt(offset);
}
return clone;
};
const circleClone = cloneAndAddSegments(circle);
const rectangleClone = cloneAndAddSegments(rectangle);
const showSegments = (item) => {
item.segments.forEach(({ point }) => new Path.Circle({
center: point,
radius: 5,
fillColor: 'orange'
}))
}
showSegments(circle);
showSegments(rectangle);
showSegments(circleClone);
showSegments(rectangleClone);
project.activeLayer.fitBounds(view.bounds.scale(0.8));

Leaflet-markercluster default icons missing

Default icons not showing for MarkerCluster plugin after using IconCreateFunction.
I want to use the default icons for the plugin but when using attached code I loose all the icons functions, I only get the numbers with no icons and if I activate the "childCount" I get one type of circle with the numbers offcenter within the icon. The markers has already been clustered and I want to add this value to the markercluster that is why I'm using the IconCreateFuncton so the numbers on the map shows correctly but I have lost all the icons and its beautiful functions... what is missing?
Result below using "var childCount"
$.getJSON("../test/test.geojson", function(json) {
geoLayer = L.geoJson(json, {
pointToLayer: function(feature, latlng) {
var log_p = feature.properties.log_p;
var marker;
if (log_p > 0){
marker = new L.shapeMarker(latlng, {radius: log_p*25, fillColor: '#2b83ba', fillOpacity: 0.5, color: '#000000', weight: 1, shape: 'circle'});
}
else {
marker = null
}
return marker;
},
onEachFeature: function(feature, layer) {
var popupText = "Amount per day: " + '<b>' + feature.properties.total + '</b>';
layer.bindPopup(popupText, {
closeButton: true,
offset: L.point(0, -20)
});
layer.on('click', function() {
layer.openPopup();
});
},
});
var markers = new L.MarkerClusterGroup({
iconCreateFunction: function(cluster) {
var children = cluster.getAllChildMarkers();
var sum = 0;
for (var i = 0; i < children.length; i++) {
sum += children[i].feature.properties.total;
}
/*
var childCount = cluster.getAllChildMarkers();
var c = ' marker-cluster-';
if (childCount < 10) {
c += 'small';
} else if (childCount < 500) {
c += 'medium';
} else {
c += 'large';
}
*/
return new L.DivIcon({ html: '<b>' + sum + '</b>', className: 'marker-cluster'/* + c */, iconSize: new L.Point(40, 40) });
}
});
markers.addLayer(geoLayer)
map.addLayer(markers);
});
Markercluster icons, styles and functions are lost
I manage to solve the problem, a few lines of code was missing. I added them to the original JavaScript code as follows.
$.getJSON("../test/test.geojson", function(json) {
geoLayer = L.geoJson(json, {
pointToLayer: function(feature, latlng) {
var log_p = feature.properties.log_p;
var marker;
if (log_p > 0) {
marker = new L.shapeMarker(latlng, {
radius: log_p * 25,
fillColor: '#2b83ba',
fillOpacity: 0.5,
color: '#000000',
weight: 1,
shape: 'circle'
});
} else {
marker = null
}
return marker;
},
onEachFeature: function(feature, layer) {
var popupText = "Amount per day: " + '<b>' + feature.properties.total + '</b>';
layer.bindPopup(popupText, {
closeButton: true,
offset: L.point(0, -20)
});
layer.on('click', function() {
layer.openPopup();
});
},
});
var clusters = new L.MarkerClusterGroup({
maxClusterRadius: 125,
iconCreateFunction: function(cluster) {
var children = cluster.getAllChildMarkers();
var sum = 0;
for (var i = 0; i < children.length; i++) {
sum += children[i].feature.properties.total;
}
var childCount = cluster.getChildCount()
var c = ' marker-cluster-';
if (childCount + sum <= 50) {
c += 'small';
} else if (childCount + sum <= 250) {
c += 'medium';
} else {
c += 'large';
}
return new L.DivIcon({
html: '<div><span>' + sum + '</span></div>',
className: 'marker-cluster marker-cluster-' + c,
iconSize: new L.Point(40, 40)
});
},
});
clusters.addLayer(geoLayer)
map.addLayer(clusters);
});

Muti-bar column Chart with Legend from Datatable

I am trying to plot a mutibar column chart with legend. This is my code. The code is seems to be working but its not adding legend in an appropriate format. I'm adding screenshots of my data table and the output coming from my code. The legend should be showing Different types of priorities but its showing "Legend Text" everywhere.
Output
Datatable
//Plotting Matrix Chart
chartMatrix.Visible = true;
LoadChartData(dtHourvsPriorityMatrix);
chartMatrix.Series["Priority"].ChartType = SeriesChartType.Column;
chartMatrix.Series["Priority"]["DrawingStyle"] = "Emboss";
//chartMatrix.ChartAreas["ChartArea1"].Area3DStyle.Enable3D = true;
chartMatrix.Series["Priority"].IsValueShownAsLabel = true;
// Create a new legend called "Legend".
chartMatrix.Legends.Add(new Legend("Legend"));
// Set Docking of the Legend chart to the Default Chart Area.
chartMatrix.Legends["Legend"].DockedToChartArea = "ChartAreaF";
// Assign the legend to Series=Priority.
chartMatrix.Series["Priority"].Legend = "Legend";
chartMatrix.Series["Priority"].IsVisibleInLegend = true;
LegendCellColumn lcc = new LegendCellColumn("Priority", LegendCellColumnType.Text, "LEGENDTEXT");
lcc.HeaderFont = new System.Drawing.Font("Trebuchet MS", 12F, System.Drawing.FontStyle.Bold);
chartMatrix.Legends["Legend"].CellColumns.Add(lcc);
private void LoadChartData(DataTable initialDataSource)
{
for (int i = 1; i < initialDataSource.Columns.Count; i++)
{
Series series = new Series();
foreach (DataRow dr in initialDataSource.Rows)
{
int y = (int)dr[i];
series.Points.AddXY(dr["Hour"].ToString(), y);
}
chartMatrix.Series.Add(series);
}
}
Try to use canvasjs chart.
Use web service for binding data
<script type="text/javascript">
$(document).ready(function () {
var district = $('#ContentPlaceHolder1_hiddistrict').val();
var assembly = $('#ContentPlaceHolder1_hidassembly').val();
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
dataType: "json",
url: "../WebMyVoterService.asmx/GenderWise",
data: '{"districtid":"' + district + '","assembly" :"' + assembly + '" }',
processData: false,
success: OnSuccess,
failure: function (response) {
alert(response);
},
error: function (response) {
alert(response);
}
});
function OnSuccess(response) {
var dpmale = [];
var dpfemale = [];
for (var i = 0; i < response.d.length; i++) {
var obj = response.d[i];
var datamale =
{
y: parseInt(obj.male),
label: obj.boothno,
};
var datafemale =
{
y: parseInt(obj.female),
label: obj.boothno,
};
dpmale.push(datamale);
dpfemale.push(datafemale);
}
var chart = new CanvasJS.Chart("chartContainerbar", {
animationEnabled: true,
axisX: {
interval: 1,
labelFontSize: 10,
lineThickness: 0,
},
axisY2: {
valueFormatString: "0",
lineThickness: 0,
labelFontSize: 10,
},
toolTip: {
shared: true
},
legend: {
verticalAlign: "top",
horizontalAlign: "center",
fontSize: 10,
},
data: [{
type: "stackedBar",
showInLegend: true,
name: "Male",
axisYType: "secondary",
color: "#f8d347",
dataPoints: dpmale
},
{
type: "stackedBar",
showInLegend: true,
name: "Female",
axisYType: "secondary",
color: "#6ccac9",
dataPoints: dpfemale
}
]
});
chart.render();
}
});
</script>
URL : http://canvasjs.com/

famo.us lightbox demo transition

I'm trying to get a transition that is similar to the lightbox demo that famous has put out. I have a grid layout, when I click a surface in the grid, Id like to have the surface transition, grow in size and be centered in the browser window.
--edit
Here is the demo, what I would like to nail is the flyout of the clicked image from its location to the center of the screen. http://demo.famo.us/lightbox/
I have the following code that I've been using as a basis. http://codepen.io/heyimlance/pen/JooQMX
var Engine = famous.core.Engine;
var Surface = famous.core.Surface;
var GridLayout = famous.views.GridLayout;
var StateModifier = famous.modifiers.StateModifier;
var Transform = famous.core.Transform;
var RenderNode = famous.core.RenderNode;
var Easing = famous.transitions.Easing;
var mainContext = Engine.createContext();
var grid = new GridLayout({
dimensions: [8, 8],
});
var surfaces = [];
grid.sequenceFrom(surfaces);
function newSurface(id) {
var surface = new Surface({
content: id + 1,
properties: {
backgroundColor: "hsl(" + (id * 70 / 64) + ", 60%, 70%)",
lineHeight: '50px',
textAlign: 'center'
}
});
var smod = new StateModifier({
size: [50,50],
transform: Transform.translate(0,0,1),
origin: [.5,.5]
});
var rnode = new RenderNode();
rnode.add(smod).add(surface);
surfaces.push(rnode);
surface.on('click', function() {
console.log(smod)
var zpos = (this.up || this.up == undefined) ? 0 : -180;
if (!zpos) {
this.up = false;
smod.setTransform(Transform.translate(0,0,2000), { curve:Easing.outElastic, duration: 1000 })
gridModifier.setTransform(Transform.translate(0,0,-2000), { curve:Easing.outElastic, duration: 500 })
} else {
this.up = true;
gridModifier.setTransform(Transform.translate(0,0,0), { curve:Easing.outElastic, duration: 400 })
smod.setTransform(Transform.translate(0,0,0), { curve:Easing.outElastic, duration: 1000 })
}
});
}
for(var i = 0; i < 64; i++) {
newSurface(i);
}
var gridModifier = new StateModifier({
size: [400, 400],
align: [.5, .5],
origin: [.5, .5],
transform : Transform.translate(0,0,0),
});
var gridRotate = new StateModifier({
transform : Transform.rotate(0,0,0),
});
mainContext.add(gridModifier).add(grid);
mainContext.setPerspective(1000);
Using your code, I made a few changes to use the Lightbox render contoller at the time of the click. Not sure what transition you would like for the grid and surface, this should give you options to transition as you like.
Here is a codepen of the example
The code:
var Engine = famous.core.Engine;
var Surface = famous.core.Surface;
var GridLayout = famous.views.GridLayout;
var StateModifier = famous.modifiers.StateModifier;
var Transform = famous.core.Transform;
var RenderNode = famous.core.RenderNode;
var RenderController = famous.views.RenderController;
var Lightbox = famous.views.Lightbox;
var Easing = famous.transitions.Easing;
var mainContext = Engine.createContext();
var grid = new GridLayout({
dimensions: [8, 8],
});
var surfaces = [];
var showing;
grid.sequenceFrom(surfaces);
var cmod = new StateModifier({
origin: [0.5, 0.5],
align: [0.5, 0.5]
});
var controller = new Lightbox({
inTransition: true,
outTransition: false,
overlap: true
});
controller.hide();
function newSurface(id) {
var surface = new Surface({
size: [undefined, undefined],
content: id + 1,
properties: {
backgroundColor: "hsl(" + (id * 70 / 64) + ", 60%, 70%)",
lineHeight: '50px',
textAlign: 'center',
cursor: 'pointer'
}
});
surface._smod = new StateModifier({
size: [420,420],
origin: [0.5, 0.5],
align: [0.5, 0.5]
});
surface._rnode = new RenderNode();
surface._rnode.add(surface._smod).add(surface);
surfaces.push(surface);
surface.on('click', function(context, e) {
if (this === showing) {
controller.hide({ curve:Easing.inElastic, duration: 1000 }, function(){
gridModifier.setTransform(Transform.scale(1,1,1),
{ curve:Easing.outElastic, duration: 1000 });
});
showing = null;
} else {
showing = this;
gridModifier.setTransform(Transform.scale(0.001, 0.001, 0.001),
{ curve:Easing.outCurve, duration: 300 });
cmod.setTransform(Transform.translate(0, 0, 0.0001));
controller.show(this._rnode, { curve:Easing.outElastic, duration: 2400 });
}
}.bind(surface, mainContext));
}
for(var i = 0; i < 64; i++) {
newSurface(i);
}
var gridModifier = new StateModifier({
size: [400, 400],
align: [0.5, 0.5],
origin: [0.5, 0.5]
});
mainContext.add(gridModifier).add(grid);
mainContext.add(cmod).add(controller);
mainContext.setPerspective(1000);
I think the best way is to follow "StateModifier" example that you can find in famo.us university : http://famo.us/university/lessons/#/famous-102/transitionables/2
Do a scale :
// animates x- and y-scale to 1
stateModifier.setTransform(
Transform.scale(1, 1, 1),
{ duration : 2000, curve: Easing.outBack }
);
and then a align [0.5, 0.5] :
var alignModifier = new Modifier({
align: [0.5, 0.5]
});
and if you want background to be minified, you have to apply 'scale' modifier too to make all other surfaces smaller.

Resources