i am creating an Ionic App to rotate an image of Car by 360 degrees. I want to rotate the object with different image files of same object (eg Car)
Here is the Example of car that I want to implement in my app.
i tried by using Gesture, loading different images on Gesture onMove.
But its not working properly.
Is there any cordova package is available? or any other way to achieve this?
My Ionic info:
Ionic CLI : 5.4.16
Ionic Framework : #ionic/angular 5.2.3
onSwipe(e) {
let count = 0;
let direction = '';
if (e.deltaX > 0) {
direction = 'R';
count = Math.round(parseInt(e.deltaX) / 10);
} else { // left
// console.log('Left');
direction = 'L';
count = Math.round(parseInt(e.deltaX) / 10);
}
this.ref.detectChanges();
this.imageChange(count, direction);
}
i tried using the sample from the JSFiddle and modify it to use gestureController. Maybe not the best solution. but it works
//your.html
<div (click)="createGesture()">
<img src="https://res.cloudinary.com/dewn0wy2s/image/upload/v1592668487/360/{{delta}}.png">
</div>
//your.component.ts
delta:number = 1;
constructor(
private gestureCtrl: GestureController,
private el: ElementRef
) { }
public createGesture() {
const gesture = this.gestureCtrl.create({
gestureName: 'rotateGesture',
el: this.el.nativeElement,
onStart: ($event) => {
console.log("onStart")
},
onMove: ($event) => {
if ($event.deltaX < 0) {
this.delta = this.delta == 0? 51 : this.delta - 1
} else {
this.delta = this.delta == 51? 0 : this.delta + 1
}
console.log("onMove", this.delta, $event)
},
onEnd: ($event) => {
console.log("onEnd", $event)
},
}, true);
gesture.enable();
}
Related
i need help with my Chart.js interactivity. When I click on the label, I need to return the column(index) number at which I clicked.
I tried to use getElementsAtEvent but it only work if I click directly at chart.
This http://jsfiddle.net/yxz2sjam/ is pretty much what I am looking for but getPointsAtEvent is no longer available in the new versions.
canvas.onclick = function (evt) {
var points = chart.getPointsAtEvent(evt);
alert(chart.datasets[0].points.indexOf(points[0]));
};
I also found this http://jsfiddle.net/1Lngmtz7/ but it isn't working with bar chart.
var ctx = document.getElementById("myChart").getContext("2d");
var myRadarChart = new Chart(ctx, {
type: 'radar',
data: data
})
$('#myChart').click(function (e) {
var helpers = Chart.helpers;
var eventPosition = helpers.getRelativePosition(e, myRadarChart.chart);
var mouseX = eventPosition.x;
var mouseY = eventPosition.y;
var activePoints = [];
helpers.each(myRadarChart.scale.ticks, function (label, index) {
for (var i = this.getValueCount() - 1; i >= 0; i--) {
var pointLabelPosition = this.getPointPosition(i, this.getDistanceFromCenterForValue(this.options.reverse ? this.min : this.max) + 5);
var pointLabelFontSize = helpers.getValueOrDefault(this.options.pointLabels.fontSize, Chart.defaults.global.defaultFontSize);
var pointLabeFontStyle = helpers.getValueOrDefault(this.options.pointLabels.fontStyle, Chart.defaults.global.defaultFontStyle);
var pointLabeFontFamily = helpers.getValueOrDefault(this.options.pointLabels.fontFamily, Chart.defaults.global.defaultFontFamily);
var pointLabeFont = helpers.fontString(pointLabelFontSize, pointLabeFontStyle, pointLabeFontFamily);
ctx.font = pointLabeFont;
var labelsCount = this.pointLabels.length,
halfLabelsCount = this.pointLabels.length / 2,
quarterLabelsCount = halfLabelsCount / 2,
upperHalf = (i < quarterLabelsCount || i > labelsCount - quarterLabelsCount),
exactQuarter = (i === quarterLabelsCount || i === labelsCount - quarterLabelsCount);
var width = ctx.measureText(this.pointLabels[i]).width;
var height = pointLabelFontSize;
var x, y;
if (i === 0 || i === halfLabelsCount)
x = pointLabelPosition.x - width / 2;
else if (i < halfLabelsCount)
x = pointLabelPosition.x;
else
x = pointLabelPosition.x - width;
if (exactQuarter)
y = pointLabelPosition.y - height / 2;
else if (upperHalf)
y = pointLabelPosition.y - height;
else
y = pointLabelPosition.y
if ((mouseY >= y && mouseY <= y + height) && (mouseX >= x && mouseX <= x + width))
activePoints.push({ index: i, label: this.pointLabels[i] });
}
}, myRadarChart.scale);
var firstPoint = activePoints[0];
if (firstPoint !== undefined) {
alert(firstPoint.index + ': ' + firstPoint.label);
}
});
Thank for response.
I solve the problem with
document.getElementById("chart").onclick = function(e)
{
var activeElement = weatherMainChart.lastTooltipActive;
console.log(activeElement[0]._index);
};
this solution register clicks on chart and label, then I restricted it with e.layerY to register only clicks on label section.
document.getElementById("chart").onclick = function(e)
{
var activeElement = weatherMainChart.lastTooltipActive;
if(e.layerY > 843 && e.layerY < 866 && activeElement[0] !== undefined)
console.log(activeElement[0]._index);
};
If you add a click handler through the onClick option you can use the following code using the getElementsAtEventForMode() call:
function handleClick(evt) {
var col;
switch(chartType) {
case "horizontalBar":
this.getElementsAtEventForMode(evt, "y", 1).forEach(function(item) { col = item._index });
break;
case "bar":
this.getElementsAtEventForMode(evt, "x", 1).forEach(function(item) { col = item._index });
break;
}
if (!col) {
return;
}
alert("Column " + col + " was selected");
};
You'll probably need to add extra switch checks for other chart types but I'm sure you get the idea.
Using version 2.4.0, i created an onClick Event, and inside it
var activeIndex = localChart.tooltip._lastActive[0]._index;
var clickCoordinates = Chart.helpers.getRelativePosition(e, localChart.chart);
if (clickCoordinates.y >= 530) { //custom value, depends on chart style,size, etc
alert("clicked on " + localChart.data.labels[activeIndex]);
}
I Solved this problem with single or multiple label click you will be find using true/false
First you need to set your chartJs Id click
below code SessionChart = Your ChartJs ID e.g. ("myChart") I was replace it for my Id
document.getElementById("SessionChart").onclick = function (evt) {
var meta = SubscriberSessionChart.getDatasetMeta(0);
if (meta.$filler.chart.legend.legendItems[0].text.toLowerCase() "sessions")
{
if (meta.$filler.chart.legend.legendItems[0].hidden) {
sessionHidden = true;
}
}
}
here "sessions" = first label text
meta.$filler.chart.legend.legendItems[0].text.toLowerCase() = is your first label
from Array so you can get multiple label's click here true / false
if (meta.$filler.chart.legend.legendItems[0].hidden) = your label is not active then
you will get hidden true otherwise you will get false if not tick on label
by default label tick hidden is false in chart js
I've used chart js library for make pie chart. I want to display tooltips always. I've done this. I've attached screenshot.
But now the tooltips are overlapped . How to solve this?
This is my code
myPieChart = new Chart(pie_chart).Pie(data_results.comp.pie, {
tooltipTemplate: "<%= value %> %",
scaleFontSize: 14,
scaleFontColor: "#333",
tooltipFillColor: "rgba(0,0,0,0)",
onAnimationComplete: function()
{
this.showTooltip(this.segments, true);
},
tooltipEvents: [],
tooltipFontColor: "#000",
});
I want to change tooltip position if already one present in that position.
Actually to detect overlapping tooltips is very difficult.
I solved it in the end by deactivating the color in the toolbox, reducing the size of the tooltip, moving the tooltip closer to the outer border and hiding all tooltips, which represent less than 2%. Example looks like that:
I used for that the following code:
Chart.Tooltip.positioners.outer = function(elements) {
if (!elements.length) {
return false;
}
var i, len;
var x = 0;
var y = 0;
for (i = 0, len = elements.length; i < len; ++i) {
var el = elements[i];
if (el && el.hasValue()) {
var elPosX = el._view.x+0.95*el._view.outerRadius*Math.cos((el._view.endAngle-el._view.startAngle)/2+el._view.startAngle);
var elPosY = el._view.y+0.95*el._view.outerRadius*Math.sin((el._view.endAngle-el._view.startAngle)/2+el._view.startAngle);
if (x < elPosX) {
x = elPosX;
}
if (y < elPosY) {
y = elPosY;
}
}
}
return {
x: Math.round(x),
y: Math.round(y)
};
},
Chart.pluginService.register({
beforeRender: function (chart) {
if (chart.config.options.showAllTooltips) {
// create an array of tooltips
// we can't use the chart tooltip because there is only one tooltip per chart
chart.pluginTooltips = [];
chart.config.data.datasets.forEach(function (dataset, i) {
chart.getDatasetMeta(i).data.forEach(function (sector, j) {
if ((sector._view.endAngle-sector._view.startAngle) > 2*Math.PI*0.02) {
chart.pluginTooltips.push(
new Chart.Tooltip({
_chart: chart.chart,
_chartInstance: chart,
_data: chart.data,
_options: chart.options.tooltips,
_active: [sector]
}, chart)
);
}
});
});
// turn off normal tooltips
chart.options.tooltips.enabled = false;
}
},
afterDraw: function (chart, easing) {
if (chart.config.options.showAllTooltips) {
// we don't want the permanent tooltips to animate, so don't do anything till the animation runs atleast once
if (!chart.allTooltipsOnce) {
if (easing !== 1)
return;
chart.allTooltipsOnce = true;
}
// turn on tooltips
chart.options.tooltips.enabled = true;
Chart.helpers.each(chart.pluginTooltips, function (tooltip) {
tooltip.initialize();
tooltip._options.position = "outer";
tooltip._options.displayColors = false;
tooltip._options.bodyFontSize = tooltip._chart.height*0.025;
tooltip._options.yPadding = tooltip._options.bodyFontSize*0.30;
tooltip._options.xPadding = tooltip._options.bodyFontSize*0.30;
tooltip._options.caretSize = tooltip._options.bodyFontSize*0.5;
tooltip._options.cornerRadius = tooltip._options.bodyFontSize*0.50;
tooltip.update();
// we don't actually need this since we are not animating tooltips
tooltip.pivot();
tooltip.transition(easing).draw();
});
chart.options.tooltips.enabled = false;
}
}
});
I am developing an iOS app with Smartface App Studio. I need to implement an search with auto complete. Can any suggest to achieve this.
Ex: If user typing "Ho" then list of places starts with "Ho" like "Holland", "Hong Kong" need to show as suggestions(while typing).
I tried with pick() and label on page. But that is working as dropdown.
Thanks in advance.
After alot work around, i made my autocomplete functinlity. Here is the code.
function PrepareAutoComplete(page, pageName) {
try {
var label_for_repeatbox = new SMF.UI.Label({
height : '100%',
width : '100%',
horizontalGap : 10,
left : '0%',
top : '0%',
fontColor : SMF.UI.Color.black,
backgroundTransparent : true
});
var rBox = new SMF.UI.RepeatBox({
name : 'rptDestinations',
width : '100%',
height : '90%',
left : Pages.PlacesToGo.edtBoxSelectDestination.left,
top : Pages.PlacesToGo.edtBoxSelectDestination.top + Pages.PlacesToGo.edtBoxSelectDestination.height + 1,
borderWidth : 1,
dataSource : [],
showScrollbar : true,
onRowRender : function onRowRender(e) {
this.controls[0].text = e.rowData;
},
itemTemplate : {
height : '10%'
}
});
label_for_repeatbox.onTouchEnded = function (e) {
alert(this.text);
}
rBox.useActiveItem = true;
rBox.visible = false;
rBox.itemTemplate.add(label_for_repeatbox);
Pages.PlacesToGo.edtBoxSelectDestination.onChange = function (e) {
if (this.text.length > 1 && isFirstTime == false) {
var search_key = this.text.toLowerCase();
var results = [];
for (var i = 0; i < Sources.length; i++) {
if (Sources[i].toLowerCase().indexOf(search_key) == 0) {
results.push(Sources.[i]);
}
}
rBox.dataSource = results;
rBox.refresh();
page.remove(rBox);
page.add(rBox);
rBox.visible = true;
}
}
Pages.PlacesToGo.edtBoxSelectDestination.onExit = function () {
rBox.dataSource = [];
rBox.refresh();
rBox.visible = false;
}
page.add(rBox);
} catch (ex) {
log(ex);
}
}
I am creating an interactive map for a non profit association "Friends of Knox Mountain Park" but I am getting trouble with the Google Earth view.
I've been searching on the web for weeks and none of the solutions I found works for me. Can someone take a look of the code and let me know what I should do to include Google Earth View in the map? Thanks in advance.
The online project: http://www.virtualbc.ca/knoxmountain/
And this is the javascript file (mapa2.js) containing the google map's code:
google.load('earth', '1');
var map;
var googleEarth;
var gmarkers = [];
var iconShadow = new google.maps.MarkerImage('icons/shadow.png',
new google.maps.Size(46, 42),
new google.maps.Point(0,0),
new google.maps.Point(13, 42));
var sites = [
['Apex Trail - Shelter',49.91174271, -119.48507050, 4, '<img src="images/apex_point_high.jpg">','magenta','14'],
['Apex Trail',49.91286999, -119.48413424, 3, '<img src="images/apex_point_low.jpg">','lemon','1'],
['Gordon Trail',49.91971281, -119.47954356, 2, '<img src="images/apex_point_low.jpg">','lemon','1'],
['Paul Tomb Bay',49.92555541, -119.47710250, 1, '<img src="images/tomb_bay.jpg">','lemon','1']
];
var infowindow = null;
var overlay;
// Used to make Google Map quard coords to MapCruncher/BingMaps quard coords
function TileToQuadKey ( x, y, zoom)
{
var quad = "";
for (var i = zoom; i > 0; i--)
{
var mask = 1 << (i - 1);
var cell = 0;
if ((x & mask) != 0)
cell++;
if ((y & mask) != 0)
cell += 2;
quad += cell;
}
return quad;
}
function init() {
var centerMap = new google.maps.LatLng(49.909671, -119.482241);
var myOptions = {
zoom: 10,
center: centerMap,
mapTypeId: google.maps.MapTypeId.SATELLITE
}
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
// Create the tile layers
// ASTER Tile Layer
myASTEROptions = {
getTileUrl : function (a,b) {
return "http://www.virtualbc.ca/knoxmountain/map/" + TileToQuadKey(a.x,a.y,b) + ".png";
},
isPng: true,
opacity: 1.0,
tileSize: new google.maps.Size(256,256),
name: "ASTER",
minZoom:13,
maxZoom:20
}
ASTERMapType = new google.maps.ImageMapType( myASTEROptions );
map.overlayMapTypes.insertAt(0, ASTERMapType);
// Aerial Tile Layer
myAerialOptions = {
getTileUrl : function (a,b) {
return "http://www.virtualbc.ca/knoxmountain/map/" + TileToQuadKey(a.x,a.y,b) + ".png";
},
isPng: true,
opacity: 1.0,
tileSize: new google.maps.Size(256,256),
name: "Aerial",
minZoom:15,
maxZoom:21
}
AerialMapType = new google.maps.ImageMapType( myAerialOptions );
map.overlayMapTypes.insertAt(1, AerialMapType);
var panorama = new google.maps.StreetViewPanorama(map.getDiv());
panorama.setVisible(false);
panorama.set('enableCloseButton', true);
map.setStreetView(panorama);
panorama.setPosition(centerMap);
setMarkers(map, sites);
setZoom(map, sites);
infowindow = new google.maps.InfoWindow({
content: "Loading..."
});
googleEarth = new GoogleEarth(map);
google.maps.event.addListenerOnce(map, 'tilesloaded', addOverlays);
}
/*
This functions sets the markers (array)
*/
function setMarkers(map, markers) {
for (var i = 0; i < markers.length; i++) {
var site = markers[i];
var siteLatLng = new google.maps.LatLng(site[1], site[2]);
var marker = new google.maps.Marker({
position: siteLatLng,
map: map,
title: site[0],
zIndex: site[3],
html: site[4],
// Markers drop on the map
animation: google.maps.Animation.DROP,
icon: 'http://www.virtualbc.ca/knoxmountain/icons/icon.png',
shadow: iconShadow
});
gmarkers.push(marker);
google.maps.event.addListener(marker, "click", function () {
infowindow.setContent(this.html);
infowindow.open(map, this);
});
}
}
/*
Set the zoom to fit comfortably all the markers in the map
*/
function setZoom(map, markers) {
var boundbox = new google.maps.LatLngBounds();
for ( var i = 0; i < markers.length; i++ )
{
boundbox.extend(new google.maps.LatLng(markers[i][1], markers[i][2]));
}
map.setCenter(boundbox.getCenter());
map.fitBounds(boundbox);
}
// This function picks up the click and opens the corresponding info window
function myclick(i) {
google.maps.event.trigger(gmarkers[i-1], "click");
}
google.maps.event.addDomListener(window, 'load', init);
The first issue I notice with your site is you are linking to http://www.virtualbc.ca/src/googleearth-compiled.js which does not exist.
I'm having some problems with the Photo Gallery view in Titanium Appcelerator (iPhone app). I don't really have any example code at the moment to share because I'm at a loss for exactly how this is supposed to function.
I just want to call my server for a list of images, and show these images in a grid as thumbnails that can be viewed in full screen, like you would normally expect from a phone photo gallery.
In all the example code I've looked at, it talks about saving photos to the phone. I don't really have to save however many event photos for how ever many tents all on the phone before displaying, do I?
How would I go about looping over a list of URLs to show in a grid, in a standard system way?
Thanks in advance for the help.
var newsFeed = Titanium.Facebook.requestWithGraphPath('me/feed', {}, 'GET', function(e) {
if (e.success) {
var videoObjs = new Array();
var result = (JSON.parse(e.result)).data;
for(var c = 0; c < result.length;c++) {
if(result[c].type == 'video') {
var vid = result[c].source.substring((result[c].source.indexOf("/v/"))+3, (result[c].source.indexOf('?')));
vidInfo = {
vGuid:vid,
thumb:"http://img.youtube.com/vi/"+vid+"/0.jpg",
descr:result[c].name
};
videoObjs.push(vidInfo);
}
}
updateTable(videoObjs);
buildCoverFlow(videoObjs);
buildDashboard(videoObjs);
} else if (e.error) {
alert(e.error);
} else {
alert('Unknown response');
}
});
var tableData = [];
var colorSet = [
"#D44646",
"#46D463",
"#46D4BE",
"#C2D446",
"#D446D5",
"#4575D5",
"#E39127",
"#879181",
"#E291D4"
];
var cellWidth = 240;
var cellHeight = 180;
var xSpacer = 12;
var ySpacer = 20;
var xGrid = 3;
var yGrid = parseInt(videoObjs.length / 3);
thumbProps = {
xSpace : xSpacer,
cellH : cellHeight,
cellW : cellWidth
}
for (var y=0; y<yGrid; y++) {
var thisRow = Ti.UI.createTableViewRow({
className: "grid",
layout: "horizontal",
height: cellHeight+(2*ySpacer),
selectedBackgroundColor:"red",
backgroundColor:"black"
});
for (var x=0; x<xGrid; x++) {
var index = x + xGrid * y;
var videoObj = videoObjs[index];
var thisView = createPlayerThumb(videoObj, thumbProps);
thisRow.add(thisView);
}
tableData.push(thisRow);
}
tableview.data = tableData;
tableview.separatorColor = 'black';
galWin.add(tableview);
tableview.addEventListener("click", function(e) {
if(e.source.objName) {
Ti.API.info("---> " + e.source.objName+e.source.objIndex + " was clicked!");
}
});
}
That's code I wrote for building an array of youtube thumbnails from a given facebook feed for the iPad. Should be a good start.