I am developing an educational game for children (D&D, colors, shapes, numbers, etc) and I am using KineticJS for that purpose. It runs fine on Ipad 4 and Iphone 5, but on Android devices it runs with a very low framerate (Galaxy Tab 2 and Galaxy S2). I tried to compile the app with Cocoon JS to enable canvas acceleration, but it gets stuck on launch screeen (with phonegap build it runs fine).
Do I have to make any changes in the Kinetic source code to build on CocoonJS? Are there any alternatives to improve Kinetic performance on android devices?
Cocoonjs cannot render the parent container (its a div). You need to overwrite the prototype of Kinetic.
Kinetic.Stage.prototype._buildDOM = function() {
this.content = this.attrs.container;
this.hitCanvas = new Kinetic.Canvas(0, 0, true);
this.bufferCanvas = new Kinetic.SceneCanvas({
pixelRatio: 1
});
this.bufferHitCanvas = new Kinetic.HitCanvas();
this._resizeDOM();
};
Kinetic.Stage.prototype._getContentPosition = function() {
var rect = this.content.getBoundingClientRect ? this.content.getBoundingClientRect() : { top : 0, left : 0 };
return { top: rect.top, left: rect.left };
};
Then build your main stage as this.
this.stage = new Kinetic.Stage({width: 960, height: 500, container: document.body});
Related
I am using open layers 6 lib for map rendering and events.
my application needed same like this example http://viglino.github.io/ol-ext/examples/layer/map.geoimage.html i.e. Example have ol.source.GeoImage..
I have tried
I am displaying raster images on map using this sample code is
const url = imagurl;
const extent = [0, 0, imageData.width, imageData.height];
const projection = new Projection({
code: 'xkcd-image',
units: 'pixels',
extent,
});
const imageLayer = new ImageLayer({
source: new Static({
url,
projection,
imageExtent: extent,
}),
});
and i am using affine transformation lib and returns scaling, rotation and transformation..
its giving the values
scaling : 327.805670381418,327.805670381418
rotation : -0.1310210334156003
transformation : 7179251.8557908312,6022627.228704552
i need to add this code into ol-6 static image source
source: new ol.source.GeoImage(
{ image,
imageCenter: transformation,
imageScale: scaling,
imageRotate: rotation,
//projection: pixelProjectio
})
suggest or help on this.. thanks in advance.. and save my days..
I am trying to create a function in the Angular system which will produce an image of the map using html2canvas
The following is the current function:
window.emapComponent.service.getMap('mapApi').then((map) => {
html2canvas(document.getElementById("mapApi"), { useCORS: true }).then(function (canvas) {
canvas.screenshotDataURI = canvas.toDataURL("image/jpg", 0.5);
canvas.toBlob(function (blob) {
saveAs(blob, oRequest.fileName)
});
});
})
What happens is that in the system itself, as soon as I drag the map with the mouse, the photo comes out weird (file attached)-
I noticed in the elements of html that although I see the objects of the layers adjusted to the map, in practice the div itself is dragged from place to place and this is what I get in the picture
I would be happy to help with this
Background
I'm using Cesium to run a simulation while capturing images with Viewer.canvas.toDataURL. The simulation has some action in it, and I would like the map imagery to be completely loaded when the action starts. However, for the first few renders, the imagery is always very low detail.
I only want to capture images at 15fps, so I render at most 15fps, for the sake of efficiency. The problem is that imagery starts low-detail and only updates when I render. It takes around 75 renders for the high-detail imagery to load, meaning that the first ~5 seconds of output images are rendered with low-detail imagery.
Question
I would like to reduce the number of output images with low-detail imagery to less than 15, ideally 0.
How can I
a) pre-load the imagery so that it's completely loaded by the time I start rendering
or
b) use the time in between renders to load the imagery, so that I minimize the number of frames with low-detail imagery?
Or maybe there is another solution I haven't thought of yet.
Things I've tried
1) I've tried restricting the area of the imagery provider, to load fewer images. This causes no discernible change, and in fact it does not cause any change to Viewer.imageryLayers._layers[0]._imageryProvider.rectangle.
var Viewer = new Cesium.Viewer('cesiumContainer', {
imageryProvider: Cesium.BingMapsImageryProvider({
url: 'https://dev.virtualearth.net',
rectangle: Cesium.Rectangle.fromDegrees(
Params.Lon - 5, Params.Lat - 5, Params.Lon + 5, Params.Lat - 5)
})
2) I've tried raising the minimumLevel of the imagery provider, hoping that would prevent it from loading the low-detail imagery at all. Again, this doesn't fix the problem and Viewer.imageryLayers._layers[0]._imageryProvider.minimumLevel is unaffected, always 0.
var Viewer = new Cesium.Viewer('cesiumContainer', {
imageryProvider: Cesium.BingMapsImageryProvider({
url: 'https://dev.virtualearth.net',
minimumLevel: 15
})
});
Minimal working example
var Viewer = new Cesium.Viewer('cesiumContainer')
Viewer.useDefaultRenderLoop = false;
var CameraTarget = new Cesium.ConstantPositionProperty(
new Cesium.Cartesian3(
-1673357.9867530654,
-4597650.657420824,
4077993.9927027463
)
);
var CameraOffset = new Cesium.ConstantPositionProperty(
new Cesium.Cartesian3(20, 2, 15)
);
var RenderInterval = 1 / 15; // seconds
var TimeDelta = 0;
var LastRenderTime = 0;
function ScreenCapture()
{
console.log('capture');
}
function Render()
{
var CurrentTime = Viewer.clock.currentTime.secondsOfDay;
var TimeDelta = CurrentTime - LastRenderTime;
if (TimeDelta > RenderInterval)
{
Viewer.camera.lookAt(
CameraTarget.getValue(Viewer.clock.currentTime),
CameraOffset.getValue(Viewer.clock.currentTime)
);
Viewer.render();
LastRenderTime = CurrentTime;
}
else
{
Viewer.clock.tick();
}
Cesium.requestAnimationFrame(Render);
}
Cesium.requestAnimationFrame(Render);
I use spin.js for showing a spinner when loading a new page. Because IE had problems with animating a gif I use this library. Now I found out that it doesn't work on iOS. The spinner is not showing up at all. Tested with:
iPhone with iOS 6.1.3
iPad with iOS 5.1.1
It is working on every browser for Windows (even Safari for Windows).
Header:
<script type="text/javascript" src="../js/spin.min.js"></script>
before closing body:
<div id ="center" style="position:fixed;top:50%;left:50%"></div>
<script>
var opts = {
lines: 13, // The number of lines to draw
length: 8, // The length of each line
width: 4, // The line thickness
radius: 11, // The radius of the inner circle
corners: 1, // Corner roundness (0..1)
rotate: 0, // The rotation offset
direction: 1, // 1: clockwise, -1: counterclockwise
color: '#000', // #rgb or #rrggbb or array of colors
speed: 1, // Rounds per second
trail: 60, // Afterglow percentage
shadow: false, // Whether to render a shadow
hwaccel: false, // Whether to use hardware acceleration
className: 'spinner', // The CSS class to assign to the spinner
zIndex: 2e9, // The z-index (defaults to 2000000000)
top: 'auto', // Top position relative to parent in px
left: 'auto' // Left position relative to parent in px
};
var target = document.getElementById('center');
var spinner = new Spinner(opts);
$("#select-place input").click(function(){
spinner.spin(target);
});
$(window).bind("load", function() {
spinner.stop();
});
</script>
I tried to use another element. Here it works. The problem is position:fixed. I read that iOS 5 does support this. How do I center the spinner in the middle of the screen even on iOS? The page is not expliciitely build for mobile devices. It's mainly a desktop version but it should work for iOS too.
Because the other solution didn't worked and I won't use a framework I came up with a JS solution. Simply calculate the middle of the screen with JS:
jQuery.fn.center = function () {
this.css("position","absolute");
this.css("top", Math.max(0, (($(window).height() - $(this).outerHeight()) / 2) +
$(window).scrollTop()) + "px");
this.css("left", Math.max(0, (($(window).width() - $(this).outerWidth()) / 2) +
$(window).scrollLeft()) + "px");
return this;
}
$('#center').center();
Taken from the answer from Tony in this post.
One disadvantage: The user can scroll away from the spinner. You'd need something which adapts on scrolling as e.g. shown in Fixed positioning in Mobile Safari.
I would like to implement a swipe gesture to replace the current Next/Prev-buttons in my web app. I figure I'll use either jQuery Mobile, QuoJS or Hammer.js to recognize the swipe gestures.
But how can I go about implementing the swipe animation (similar to this) to go with the gestures?
I'm not flipping between images as in the example, but html sections mapping onto Backbone Model Views.
This finally "solved" it. I'm using jQuery-UI with a slide effect, but it's not looking as good as I had hoped, I want it to look more like on iOS using Obj-C. But it will have to do.
var handleSwipeEvents = function() {
$(function() {
$('#myId').on('swipeleft', swipeHandler);
$('#myId').on('swiperight', swipeHandler);
function swipeHandler(event) {
function slideEffect(swipeLeft, duration) {
var slideOutOptions = {"direction" : swipeLeft ? "left": "right", "mode" : "hide"};
$('#myId').effect("slide", slideOutOptions, duration, function() { // slide out old data
var slideInOptions = {"direction" : swipeLeft ? "right" : "left", "mode" : "show"};
$('#myId').effect("slide", slideInOptions, duration); // slide in new data
// Alter contents of element
});
}
var swipeLeft = (event.type === "swipeleft");
slideEffect(swipeLeft, 300);
}
});
};
I have a feeling one can achieve better results using CSS3 and transition, but I haven't succeeded with that.