Cordova radio stream spectrum analyzer iOS\Android - android

I have a problem with radio stream spectrum analyzer in iOS\Android.
My HTML:
<canvas id="canvas" width="512" height="100"></canvas>
<div id="playStream">Play</div>
<div id="stopStream">Stop</div>
And my javascript code:
window.onload = function () {
var ctx = document.getElementById("canvas").getContext("2d");
var audioContext = new(window.AudioContext || window.webkitAudioContext || window.mozAudioContext || window.msAudioContext)();
var analyser = audioContext.createAnalyser();
analyser.fftSize = 512;
analyser.connect(audioContext.destination);
var frequencyBins = new Uint8Array(analyser.frequencyBinCount);
var filter = audioContext.createBiquadFilter();
filter.type = "highpass";
filter.frequency.value = 0.0001;
filter.connect(analyser);
window.audio = new Audio('http://noasrv.caster.fm:10099/128mp3_autodj');
audio.crossOrigin = 'anonymous';
var audioSrc = audioContext.createMediaElementSource(audio);
audioSrc.connect(analyser);
audioSrc.connect(filter);
var osc = audioContext.createOscillator();
osc.connect(filter);
var WIDTH = 512;
var HEIGHT = 100;
var value, h, w;
function draw() {
ctx.clearRect(0, 0, WIDTH, HEIGHT);
for (var i = 0; i < frequencyBins.length; i++) {
value = frequencyBins[i];
h = HEIGHT * (value / 255);
w = WIDTH / frequencyBins.length;
ctx.fillRect(i * w, HEIGHT - 1, w, -h);
}
};
function animate() {
analyser.getByteFrequencyData(frequencyBins);
//console.log(frequencyBins);
draw();
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
playStream.addEventListener('click', function(){
audio.play();
}, false)
stopStream.addEventListener('click', function(){
audio.pause();
}, false)
};
And here is an example: http://jsfiddle.net/a2ZL9/46/.
This code works fine in browsers, but when I build android app it's doesn't work. Audio playing, but there is no animation of spectrum analyzer.
Can somebody help me with this problem?

Related

"THREE.WebGLRenderer: A WebGL context could not be created. Reason: Failed to create a WebGL2 context" error in Angular Studio

I'm new to Angular-Ionic and I created my first App with THREE js, now. When I run it in Firefox or Chrome, I don't get any erros at all. But when I run it with Android Studio I get a lot of errors.
Examples:
Could not create a WebGL context, VENDOR = 0xffff, DEVICE = 0xffff, GL_VENDOR = Google (NVIDIA Corporation), GL_RENDERER = Android Emulator OpenGL ES Translator (NVIDIA GeForce MX350/PCIe/SSE2), GL_VERSION = 526.98, Sandboxed = no, Optimus = no, AMD switchable = no, Reset notification strategy = 0x8252, ErrorMessage = bindToCurrentThread failed:
glDrawElements: framebuffer incomplete (check)
Shader Error 1280 - VALIDATE_STATUS false
Failed to create a WebGL2 context.
in Angular Studio
in Firefox
my home.page.ts (and I know, it's not a clean code):
import { Component, ElementRef, HostListener, ViewChild } from '#angular/core';
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { Water } from 'three/examples/jsm/objects/Water';
import { Sky } from 'three/examples/jsm/objects/Sky';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
#Component({
selector: 'app-home',
templateUrl: 'home.page.html',
styleUrls: ['home.page.scss'],
})
export class HomePage {
steps = 1000
target = 10000
progress = this.steps / this.target
#ViewChild('canvas') container!: ElementRef;
protected scene
protected camera
protected renderer
protected controls
protected pmremGenerator
constructor() {
this.scene = new THREE.Scene()
this.camera = new THREE.PerspectiveCamera(55, window.innerWidth / window.innerHeight, 1, 20000);
this.renderer = new THREE.WebGLRenderer({antialias: true})
this.controls = new OrbitControls(this.camera, this.renderer.domElement);
this.pmremGenerator = new THREE.PMREMGenerator(this.renderer)
}
ngAfterViewInit() {
this.renderer.setPixelRatio(window.devicePixelRatio);
this.renderer.setSize(window.innerWidth, window.innerHeight);
this.renderer.toneMapping = THREE.ACESFilmicToneMapping;
this.container.nativeElement.appendChild(this.renderer.domElement);
this.camera.position.set(0, 0, -1000);
this.renderer.shadowMap.enabled = true;
this.controls.maxPolarAngle = Math.PI * 0.46;
this.controls.minDistance = 10.0;
this.controls.maxDistance = 200.0;
this.controls.update();
this.controls.update();
let sun = new THREE.Vector3();
const waterGeometry = new THREE.PlaneGeometry(10000, 10000);
let water = new Water(
waterGeometry,
{
textureWidth: 1024,
textureHeight: 1024,
waterNormals: new THREE.TextureLoader().load('../../assets/textures/waternormals.jpg', function (texture) {
texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
}),
sunDirection: new THREE.Vector3(),
sunColor: 0xffffff,
waterColor: 0x001e0f,
distortionScale: 3.7,
fog: true
}
);
water.rotation.x = - Math.PI / 2;
this.scene.add(water);
const sky = new Sky();
sky.scale.setScalar(10000);
this.scene.add(sky);
const skyUniforms = sky.material.uniforms;
skyUniforms['turbidity'].value = 5;
skyUniforms['rayleigh'].value = 0.1;
skyUniforms['mieCoefficient'].value = 0.006;
skyUniforms['mieDirectionalG'].value = 0.55;
let renderTarget;
let cylinderGeo = new THREE.CylinderGeometry(50, 50, 10, 100)
let cylinderMat = new THREE.MeshStandardMaterial({
metalness: 0,
roughness: 1
})
let cylinder = new THREE.Mesh(cylinderGeo, cylinderMat)
this.scene.add(cylinder)
cylinder.position.set(0, -3, 0)
cylinder.receiveShadow = true
const loader = new GLTFLoader;
loader.load(
'assets/Wohnhaus.glb',
(object) => {
this.scene.add(object.scene);
object.scene.position.set(0, 2, 0)
object.scene.scale.set(10,10,10)
}
)
this.updateSun(sky, water, sun, renderTarget);
this.animate(water)
}
animate(water: Water) {
requestAnimationFrame(() => { this.animate(water) })
this.controls.update()
water.material.uniforms['time'].value += 1.0 / 60.0;
this.renderer.render(this.scene, this.camera)
}
#HostListener('window:resize', ['$event'])
onResize() {
this.renderer.setSize(window.innerWidth, window.innerHeight);
this.camera.aspect = window.innerWidth / window.innerHeight;
this.camera.updateProjectionMatrix();
this.renderer.render(this.scene, this.camera);
}
updateSun(sky: Sky, water: Water, sun: THREE.Vector3, renderTarget: any) {
const parameters = {
elevation: 10,
azimuth: 90
};
const phi = THREE.MathUtils.degToRad(90 - parameters.elevation);
const theta = THREE.MathUtils.degToRad(parameters.azimuth);
sun.setFromSphericalCoords(1, phi, theta);
sky.material.uniforms['sunPosition'].value.copy(sun);
water.material.uniforms['sunDirection'].value.copy(sun).normalize();
sky.castShadow = true
water.castShadow = true
if (renderTarget !== undefined) renderTarget.dispose();
renderTarget = this.pmremGenerator.fromScene(this.scene);
this.scene.environment = renderTarget.texture;
}
}
I already tried different Android Versions and Phones and I always have the same problems.
Update
I have changed WEBGLRenderer to WEBGL1Renderer. In my Code I removed the commented code. Now I don't get any Errors at all. I can see the cylinder now, but not the GLTFModel.
let cylinderGeo = new THREE.CylinderGeometry(50, 50, 10, 100)
/*let cylinderMat = new THREE.MeshStandardMaterial({
metalness: 0,
roughness: 1
})*/
let cylinder = new THREE.Mesh(cylinderGeo)
this.scene.add(cylinder)
cylinder.position.set(0, -3, 0)
const loader = new GLTFLoader;
loader.load(
'assets/Wohnhaus.glb',
(object) => {
this.scene.add(object.scene);
object.scene.position.set(0, 2, 0)
object.scene.scale.set(10, 10, 10)
}
)

3D Model not loading on android device

I have a page on my(very very recent only 2days old) website that contains a 3D model. The model was made in Blender, and was exported in the .glb format using glTF-Blender-IO by the KhronosGroup. It is uploaded with the THREE.GLTFLoader. Everything works perfectly fine on desktop and on iOS devices, however not on Android devices. The model simply does not show up. The error I get reads as follows:
Three.WebGlShader: Shader couldn't compile
Three.WebGlProgram: shader error:1282 35715 false
gl.getProgramInfoLog invalid shaders WARNING:0:1:'GL_OES_standard_derivatives':extension is not supported
'use strict';
window.onload = function() {
main();
}
function main() {
var canvas = document.querySelector('#canvasExpo58');
var renderer = new THREE.WebGLRenderer({canvas, antialias:true, alpha:true});
var fov = 45;
var aspect = window.innerWidth/window.innerHeight;
var near = 1;
var far = 1000;
var camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
camera.position.set(10, 2, 5); //Zou moeten de initiƫle positie van de camera zijn bij opstarten: dus wat je als eerste ziet vooraleer je de muis beweegt
var controls = new THREE.OrbitControls(camera, canvas);
controls.target.set(10, 25, 10);
controls.update();
var scene = new THREE.Scene();
scene.background = renderer.setClearColor(0x000000, 0); //Deze geeft, samen met de alpha:true in de WebGLRenderer, een transparante achtergrond
{
var light1 = new THREE.DirectionalLight(new THREE.Color(0xFFFFFF), 0.8);
light1.position.set(-5, -5, 25);
scene.add(light1);
scene.add(light1.target);
}
{
var light2 = new THREE.DirectionalLight(new THREE.Color(0xFFFFFF), 1);
light2.position.set(-40, -10, 4);
scene.add(light2);
scene.add(light2.target);
}
{
var light3 = new THREE.AmbientLight(new THREE.Color(0xCBC9D3), 0.9);
scene.add(light3);
scene.add(light3.target);
}
{
var loader = new THREE.GLTFLoader();
loader.load(
'images/Dressoir.glb',
(gltf) => {
var root = gltf.scene;
scene.add(root);
var box = new THREE.Box3().setFromObject(root);
var boxSize = box.getSize(new THREE.Vector3()).length();
var boxCenter = box.getCenter(new THREE.Vector3());
//frameArea(boxSize * 0.5, boxSize, boxCenter, camera);
controls.maxDistance = boxSize * 10;
controls.target.copy(boxCenter);
controls.update();
}
);
}
function resizeRendererToDisplaySize(renderer) {
var canvas = renderer.domElement;
var width = canvas.clientWidth;
var height = canvas.clientHeight;
var needResize = canvas.width !== width || canvas.height !== height;
if (needResize) {
renderer.setSize(width, height, false);
}
return needResize;
}
function render() {
if (resizeRendererToDisplaySize(renderer)) {
var canvas = renderer.domElement;
camera.aspect = canvas.clientWidth/canvas.clientHeight;
camera.updateProjectionMatrix();
}
renderer.render(scene, camera);
requestAnimationFrame(render);
}
requestAnimationFrame(render);
}
Webpage of the Live Server
I have tried searching the web for an answer, but found nothing relevant.

d3js map displays incorrectly in mobile chrome

I am relatively new to d3js, and trying to create a visualization of my quartet's concert schedule using a map. My first attempt works great in a desktop chrome browser and desktop safari browser.
On my android device in mobile chrome, the map renders the entire globe incorrectly except for the United States.
http://test.chiaraquartet.net/topo/index.html
Any insight into what I am doing wrong/if there is a bug in d3 would be appreciated.
Here is the code in question:
var center = [90, -38.7],
ratio = window.devicePixelRatio || 1,
graticule = d3.geo.graticule(),
width = 500,
height = 500,
degrees = 180 / Math.PI,
projection = d3.geo.orthographic()
.scale(height / 2 - 1)
.rotate(center)
.translate([width / 2, height / 2])
.clipAngle(90)
.precision(.1)
var graticule = d3.geo.graticule()()
// Round to integer pixels for speed, and set pixel ratio.
function roundRatioContext(context) {
return {
moveTo: function(x, y) { context.moveTo(Math.round(x * ratio), Math.round(y * ratio)); },
lineTo: function(x, y) { context.lineTo(Math.round(x * ratio), Math.round(y * ratio)); },
closePath: function() { context.closePath(); }
};
}
var canvas = d3.select("body").append("canvas")
.attr("width", width * ratio)
.attr("height", height * ratio)
.style("width", width + "px")
.style("height", height + "px")
var c = canvas.node().getContext("2d");
var path = d3.geo.path()
.projection(projection)
.context(roundRatioContext(c));
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append('g')
var textbox = d3.select("body").append("div")
.style('position', 'absolute')
.attr('class', 'popup')
.classed('hidden', true)
var sphere = svg.append("path")
.datum({type: "Sphere"})
.attr("id", "sphere")
.attr("d", path)
var runner = queue()
.defer(d3.json, 'world.json')
.defer(d3.xhr('/concertrpc.php')
.header('content-type', 'application/json')
.post, JSON.stringify({
params: [],
id: 1
}))
.await(function(error, world, info) {
if (error) return console.error(error);
var features = topojson.feature(world, world.objects.states)
var countries = topojson.feature(world, world.objects.countries)
console.log(world)
var concerts = JSON.parse(info.responseText)
if (concerts.error) {
console.log(concerts.error)
return
}
concerts = concerts.result.concerts
console.log(concerts)
var globe = {type: "Sphere"},
graticule = d3.geo.graticule()(),
countries = topojson.feature(world, world.objects.countries),
states = topojson.feature(world, world.objects.states),
country_borders = topojson.mesh(world, world.objects.countries, function(a, b) { return a !== b }),
state_borders = topojson.mesh(world, world.objects.states, function(a, b) { return a.id !== b.id }),
temp_context
temp_context = path.context()
path.context(null)
svg.selectAll('.concert')
.data(concerts, function(d) { return d.properties.id })
.enter().append("path")
.attr('class', 'concert')
.attr('d', path)
.on('mouseover', concertMouseover)
.on('mouseout', function(d) {
textbox.classed('hidden', true)
})
path.context(temp_context)
d3.select('body').append('div').append('button')
.attr('type', 'button')
.text('This season')
.on('click', function() {
getConcertData('This season')
})
var zoom = d3.geo.zoom()
.projection(projection)
.duration(function(S) { return 2000 * Math.sqrt(S); }) // assume ease="quad-in-out"
.scaleExtent([height / 2 - 1, Infinity])
.on("zoom", function() {
projection.clipAngle(Math.asin(Math.min(1, .5 * Math.sqrt(width * width + height * height) / projection.scale())) * degrees);
c.clearRect(0, 0, width * ratio, height * ratio);
c.strokeStyle = "#999", c.lineWidth = .25 * ratio, c.beginPath(), path(graticule), c.stroke();
c.fillStyle = "#69d2e7", c.beginPath(), path(countries), c.fill();
c.fillStyle = "#00f", c.beginPath(), path(states), c.fill();
c.strokeStyle = "#fff", c.lineWidth = .5 * ratio, c.beginPath(), path(country_borders), c.stroke();
c.strokeStyle = "#fff", c.lineWidth = .5 * ratio, c.beginPath(), path(state_borders), c.stroke();
c.strokeStyle = "#000", c.lineWidth = .5 * ratio, c.beginPath(), path(globe), c.stroke();
temp_context = path.context()
path.context(null)
svg.selectAll("path").attr("d",path);
path.context(temp_context)
})
//.on("zoomend", transition);
canvas
.call(zoom)
.call(zoom.event);
sphere
.call(zoom)
function transition() {
zoomBounds(projection, states.features[30]);
canvas.transition()
.ease("quad-in-out")
.duration(2000) // see https://github.com/mbostock/d3/pull/2045
.call(zoom.projection(projection).event);
}
function zoomBounds(projection, o) {
var centroid = d3.geo.centroid(o),
clip = projection.clipExtent();
projection
.rotate([-centroid[0], -centroid[1]])
.clipExtent(null)
.scale(1)
.translate([0, 0]);
var b = path.bounds(o),
k = Math.min(1000, .45 / Math.max(Math.max(Math.abs(b[1][0]), Math.abs(b[0][0])) / width, Math.max(Math.abs(b[1][1]), Math.abs(b[0][1])) / height));
projection
.clipExtent(clip)
.scale(k)
.translate([width / 2, height / 2]);
}
})
function concertMouseover(d) {
var loc = projection(d3.select(this).datum().geometry.coordinates)
textbox.style('top', loc[1] + "px")
textbox.style('left', loc[0] + 15 + "px")
textbox.text(d.properties.title)
textbox.classed('hidden', false)
}
function getConcertData(request) {
d3.xhr('/concertrpc.php')
.header('content-type', 'application/json')
.post(JSON.stringify({
params: [request],
id: 1
}), function(error, info) {
var concerts = JSON.parse(info.responseText)
if (concerts.error) {
console.log(concerts.error)
return
}
var c = svg.selectAll('.concert')
.data(concerts.result.concerts, function(d) { return d.properties.id })
c.transition()
.style('opacity', '1')
c.enter()
.append('path')
.attr('class', 'concert')
.attr('d', path)
.on('mouseover', concertMouseover)
.on('mouseout', function(d) {
textbox.classed('hidden', true)
})
c.exit().transition()
.duration(1000)
.style('opacity', '0')
.remove()
})
}
I'm not sure what was causing the problem, but the culprit was in the topojson file generated by my attempts to combine a map of the countries of the world with a map of the states of the USA. I found a different map of the world to use, and now the map displays the same way on both the phone and the desktop.

Uncaught typeError cannot call method 'remove children' of undefined and Uncaught typeError cannot read property 'children' of undefined

I am doing project in android phonegap application using kineticjs and html5
I got 3 errors don't know what is the exact problem
Uncaught typeError cannot call method 'remove children' of undefined at file:///android_assest/www/index.html
Uncaught typeError cannot read property 'children' of undefined at file:///android_assest/www/index.html
Uncaught referenceError kinetic is not defined at file:///android_assest/www/index.html
I google it but cudn't find the answer so any help would be greatful
function clearCanvas() {
layer.removeChildren();
layer.draw();
haveBackground = false;
}
function downloadCanvas() {
var canvas = stage.children[0].canvas;
var oImgPNG = Canvas2Image.saveAsPNG(canvas, true);
document.body.appendChild(oImgPNG);
}
<img alt="" src="res/drawable-hdpi/design15.png" id="gabby" onClick="addClickedImage('gabby ')"/><br />
above those snippets in which i am getting error.Thanks in advance
Here is the script of my programm
<script type="text/javascript" src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.3.1.js"></script>
<script type="text/javascript" src="assets/www/base64.js"></script>
<script type="text/javascript" src="assets/www/canvas2image.js"></script>
<script type="text/javascript">
debugger;
var stage;
var layer;
var selected;
var wasSelected;
var haveBackground; // first dragged image sets stage size
/*
* Set up canvas stage and layer
*/
function initCanvas(id) {
stage = new Kinetic.Stage({
container: id,
width: 150,
height: 50
});
layer = new Kinetic.Layer();
stage.add(layer);
stage.draw();
}
/*
* Clear canvas, start again
*/
function clearCanvas() {
layer.removeChildren();
layer.draw();
haveBackground = false;
}
/*
* Download canvas
*/
function downloadCanvas() {
var canvas = stage.children[0].canvas;
var oImgPNG = Canvas2Image.saveAsPNG(canvas, true);
document.body.appendChild(oImgPNG);
}
/*
* Upload File
*/
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('#blah')
.attr('src', e.target.result)
.width(20)
.height(20);
};
reader.readAsDataURL(input.files[0]);
}
}
/*
* Resize
*/
function resize(group, activeAnchor) {
var tl = group.get(".tl")[0];
var tr = group.get(".tr")[0]; group
var br = group.get(".br")[0];
var bl = group.get(".bl")[0];
var handle = group.get(".handle")[0];
var ghost = group.get(".ghost")[0];
var flip = group.get(".flip")[0];
var image = group.get(".image")[0];
switch (activeAnchor.attrs.name) {
case "tl":
bl.setPosition(tl.attrs.x, br.attrs.y);
tr.setPosition(br.attrs.x, tl.attrs.y);
break;
case "tr":
br.setPosition(tr.attrs.x, bl.attrs.y);
tl.setPosition(bl.attrs.x, tr.attrs.y);
break;
case "bl":
br.setPosition(tr.attrs.x, bl.attrs.y);
tl.setPosition(bl.attrs.x, tr.attrs.y);
break;
case "br":
bl.setPosition(tl.attrs.x, br.attrs.y);
tr.setPosition(br.attrs.x, tl.attrs.y);
break;
}
handle.setPosition((tr.attrs.x + tl.attrs.x) / 2, tl.attrs.y - 20);
ghost.setPosition(handle.getPosition());
flip.setPosition((tr.attrs.x + tl.attrs.x) / 2, bl.attrs.y + 20);
image.setPosition(tl.attrs.x, tl.attrs.y);
image.attrs.width = tr.attrs.x - tl.attrs.x;
image.attrs.height = bl.attrs.y - tl.attrs.y;
}
/*
* Rotate
*/
function rotate(group) {
var c = group.getAbsolutePosition();
var p0 = { x: c.x, y: c.y - 50 };
var p1 = stage.getUserPosition();
var p0c = Math.sqrt(Math.pow(c.x - p0.x, 2) + Math.pow(c.y - p0.y, 2)); // p0->c (b)
var p1c = Math.sqrt(Math.pow(c.x - p1.x, 2) + Math.pow(c.y - p1.y, 2)); // p1->c (a)
var p0p1 = Math.sqrt(Math.pow(p1.x - p0.x, 2) + Math.pow(p1.y - p0.y, 2)); // p0->p1 (c)
var deg = Math.acos((p1c * p1c + p0c * p0c - p0p1 * p0p1) / (2 * p1c * p0c));
// fix for negative rotation
if (p1.x < c.x) {
deg = (360 * (Math.PI / 180)) - deg;
}
group.setRotation(deg);
}
/*
* Flip
*/
function flip(group) {
group.attrs.scale.x = group.attrs.scale.x * -1;
}
/*
* Fix center offset (due to resizing from a corner)
*/
function fixCenterOffset(group) {
var image = group.get(".image")[0]
var currentOffset = group.getCenterOffset();
var currentPosition = group.getPosition();
var newOffset = { x: image.attrs.width / 2, y: image.attrs.height / 2 };
var newPosition = {
x: currentPosition.x - (currentOffset.x - newOffset.x),
y: currentPosition.y - (currentOffset.y - newOffset.y)
}
group.setCenterOffset(newOffset);
group.setPosition(newPosition);
layer.draw();
}
/*
* Prepare background image
*/
function prepareBackground(img) {
var maxWidth = 200;
var maxHeight = 100;
if (img.width > maxWidth) {
img.height = (maxWidth / img.width) * img.height;
img.width = maxWidth;
}
if (img.height > maxHeight) {
img.width = (maxHeight / img.height) * img.width;
img.height = maxHeight;
}
return img;
}
/*
* Add an image plus anchors to the canvas using group
*/
function initImage(img, type) {
if (type == "background") {
var kimggroup = initBackgroundImage(img);
} else {
var kimggroup = initNormalImage(img);
}
layer.add(kimggroup);
stage.add(layer);
// Draw the img
stage.draw();
}
/*
* Add background image
*/
function initBackgroundImage(img) {
var img = prepareBackground(img);
stage.setSize(img.width, img.height);
var kimggroup = new Kinetic.Group({
x: 0,
y: 0,
draggable: false
});
// Make the img and add it to the group
var kimg = new Kinetic.Image({
x: 0,
y: 0,
image: img,
width: img.width,
height: img.height,
name: "image"
});
kimggroup.add(kimg);
return kimggroup;
}
/*
* Add normal image
*/
function initNormalImage(img) {
var kimggroup = new Kinetic.Group({
x: stage.attrs.width / 2,
y: stage.attrs.height / 2,
draggable: true,
centerOffset: [img.width / 2, img.height / 2]
});
// Make the img and add it to the group
var kimg = new Kinetic.Image({
x: 0,
y: 0,
image: img,
width: img.width,
height: img.height,
name: "image"
});
kimggroup.add(kimg);
// Add anchors for resizing and rotation
addAnchor(kimggroup, 0, 0, "tl");
addAnchor(kimggroup, img.width, 0, "tr");
addAnchor(kimggroup, img.width, img.height, "br");
addAnchor(kimggroup, 0, img.height, "bl");
addAnchor(kimggroup, img.width / 2, -20, "handle");
addAnchor(kimggroup, img.width / 2, -20, "ghost");
addAnchor(kimggroup, img.width / 2, img.height + 20, "flip");
// On click make the image selected
kimggroup.on("mousedown", function () {
wasSelected = selected;
selected = this;
updateSelected();
this.moveToTop();
stage.draw();
});
kimg.on("mouseover", function () {
document.body.style.cursor = "move";
});
kimg.on("mouseout", function () {
document.body.style.cursor = "default";
});
// Double click to remove
kimg.on("dblclick dbltap", function () {
layer.remove(kimggroup);
layer.draw();
});
return kimggroup;
}
/*
* Create anchor and add to group
*/
function addAnchor(group, x, y, name) {
var config = {
x: x,
y: y,
stroke: "#666",
fill: "#ddd",
strokeWidth: 2,
radius: 4,
name: name,
draggable: true
}
switch (name) {
case "handle":
config.draggable = false;
var anchor = addRotateAnchor(group, config);
break;
case "ghost":
config.stroke = "#666";
var anchor = addRotateGhostAnchor(group, config);
break;
case "flip":
config.stroke = "#666";
config.draggable = false;
var anchor = addFlipAnchor(group, config);
break;
default:
var anchor = addResizeAnchor(group, config);
break;
}
anchor.hide();
group.add(anchor);
}
/*
* Set up resize anchor
*/
function addResizeAnchor(group, config) {
var anchor = new Kinetic.Circle(config);
anchor.on("dragmove", function () {
resize(group, this);
layer.draw();
});
anchor.on("mousedown touchstart", function () {
group.draggable(false);
this.moveToTop();
});
anchor.on("dragend", function () {
fixCenterOffset(group);
group.draggable(true);
layer.draw();
});
anchor.on("mouseover", function () {
var layer = this.getLayer();
document.body.style.cursor = "pointer";
this.setStrokeWidth(3);
layer.draw();
});
anchor.on("mouseout", function () {
var layer = this.getLayer();
document.body.style.cursor = "default";
this.setStrokeWidth(2);
layer.draw();
});
return anchor;
}
/*
* Set up rotation anchor
*/
function addRotateAnchor(group, config) {
var anchor = new Kinetic.Circle(config);
anchor.on("mouseover", function () {
var layer = this.getLayer();
document.body.style.cursor = "pointer";
this.setStrokeWidth(3);
layer.draw();
});
anchor.on("mouseout", function () {
var layer = this.getLayer();
document.body.style.cursor = "default";
this.setStrokeWidth(2);
layer.draw();
});
return anchor;
}
/*
* Set up rotation ghost anchor
*/
function addRotateGhostAnchor(group, config) {
var anchor = new Kinetic.Circle(config);
anchor.on("dragmove", function () {
rotate(group);
layer.draw();
});
anchor.on("mousedown touchstart", function () {
group.draggable(false);
this.moveToTop();
});
anchor.on("dragend", function () {
var handle = group.get(".handle")[0];
this.setPosition(handle.getPosition());
group.draggable(true);
layer.draw();
});
anchor.on("mouseover", function () {
var layer = this.getLayer();
document.body.style.cursor = "pointer";
this.setStrokeWidth(3);
layer.draw();
});
anchor.on("mouseout", function () {
var layer = this.getLayer();
document.body.style.cursor = "default";
this.setStrokeWidth(2);
layer.draw();
});
return anchor;
}
/*
* Set up flip anchor
*/
function addFlipAnchor(group, config) {
var anchor = new Kinetic.Circle(config);
anchor.on("mousedown touchstart", function () {
flip(group);
layer.draw();
});
anchor.on("mouseover", function () {
var layer = this.getLayer();
document.body.style.cursor = "pointer";
this.setStrokeWidth(3);
layer.draw();
});
anchor.on("mouseout", function () {
var layer = this.getLayer();
document.body.style.cursor = "default";
this.setStrokeWidth(2);
layer.draw();
});
return anchor;
}
/*
* Show anchors only when group selected
*/
function updateSelected() {
// Deselect the old img if there was any
if (wasSelected) {
wasSelected.get(".tl")[0].hide();
wasSelected.get(".tr")[0].hide();
wasSelected.get(".br")[0].hide();
wasSelected.get(".bl")[0].hide();
wasSelected.get(".handle")[0].hide();
wasSelected.get(".ghost")[0].hide();
wasSelected.get(".flip")[0].hide();
}
// Select the new image
selected.get(".tl")[0].show();
selected.get(".tr")[0].show();
selected.get(".br")[0].show();
selected.get(".bl")[0].show();
selected.get(".handle")[0].show();
selected.get(".ghost")[0].show();
selected.get(".flip")[0].show();
}
/*
* Add clicked images to the canvas
*/
function addClickedImage(name) {
var img = document.getElementById(name);
initImage(img, "normal");
}
/*
* Listen for images dragged into canvas and add them
*/
function setupDragAndDrop() {
stage.content.addEventListener("dragover", function (evt) {
evt.preventDefault();
}, false);
// Handle dropped image file - only Firefox and Google Chrome
stage.content.addEventListener("drop", function (evt) {
dragImg = new Image();
var files = evt.dataTransfer.files;
if (files.length > 0) {
var file = files[0];
if (typeof FileReader !== "undefined" && file.type.indexOf("image") != -1) {
var reader = new FileReader();
reader.onload = function (evt) {
dragImg.src = evt.target.result;
};
reader.readAsDataURL(file);
dragImg.onload = function () {
if (!haveBackground) {
haveBackground = true;
var type = "background";
} else {
var type = "normal";
}
initImage(this, type);
}
}
}
evt.preventDefault();
}, false);
}
window.onload = function () {
initCanvas("container");
setupDragAndDrop();
};
</script>
More details:
since you cannot 'remove children' of undefined, your layer is not being defined somewhere (or is removed or overwritten).
Make sure you have this somewhere:
var layer = new Kinetic.Layer();
not being able to access children means the same for your stage. but simply put since 'kinetic' is not defined somewhere you are either not including the Kinetic.4.3.0.1.JS in your sources, or you are declaring it incorrectly.
Make sure you have the kinetic.js file referenced somewhere, like in either the or tags:
<script src='http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.3.1.js'></script>
or link to a hard copy in your project
<script src='../kinetic-v4.3.1.js'></script> // in this example it is located one directory up, but you could put it anywhere really.
It's scoping issue.
Your variable layer is not accessible from function clearCanvas().
Not ideal, but it works by defining the variable first, then use it later like the following;
<script>
var layer;
$( function() {
layer = new Kinetic.Layer();
.....
});
</script>
so does the same apply to your variable 'stage'
--- edited after your comment ---
<script>
var layer, script, stage;
function initCanvas(id) {
stage = new Kinetic.Stage({ container: id, width: 150, height: 50 });
layer = new Kinetic.Layer();
stage.add(layer);
stage.draw();
}
</script>
if you defined 'stage = something' inside function it works like 'var stage=something'.
so if you want to access stage and layer outside of function, you defined it outside of your function.

three.js - webgl and canvas rendering performance issue

I've created a 3d scene with below code.
<!DOCTYPE html>
<html lang="en">
<head>
<title>3d Model using HTML5 and three.js</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
font-family: Monospace;
background-color: #f0f0f0;
margin: 0px;
overflow: hidden;
}
</style>
</head>
<body>
<script src="three.min.js" type="text/javascript"></script>
<script src="Curve.js" type="text/javascript"></script>
<script src="TubeGeometry.js" type="text/javascript"></script>
<script src="Stats.js" type="text/javascript"></script>
<script src="Detector.js" type="text/javascript"></script>
<script>
// variables
var container, stats;
var camera, scene, renderer, splineCamera, cameraHelper, cameraEye;
var text, plane, tube, tubeMesh, parent;
var targetRotation = 0;
var targetRotationOnMouseDown = 0;
var mouseX = 0;
var mouseXOnMouseDown = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
var binormal = new THREE.Vector3();
var normal = new THREE.Vector3();
init();
animate();
function init(){
// container
container = document.createElement( 'div' );
document.body.appendChild( container );
// info div
info = document.createElement( 'div' );
info.style.position = 'absolute';
info.style.top = '10px';
info.style.width = '100%';
info.style.textAlign = 'center';
//info.innerHTML = 'Drag to spin the cylinder<br/> You can identify cylinder face by clicking on it.</br>';
container.appendChild( info );
// camera
camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.set(30,10,10);
//camera.up = new THREE.Vector3( 0, 1, 1 );
// scene
scene = new THREE.Scene();
camera.lookAt(scene.position);
// light
scene.add( new THREE.AmbientLight( 0x404040 ) );
light = new THREE.DirectionalLight( 0xffffff );
light.position.set( 0, 1, 0 );
scene.add( light );
// CONTROLS
controls = new THREE.TrackballControls( camera );
// Grid
geometry = new THREE.Geometry();
geometry.vertices.push( new THREE.Vector3( - 500, 0, 0 ) );
geometry.vertices.push( new THREE.Vector3( 500, 0, 0 ) );
for ( var i = 0; i <= 20; i ++ ) {
line = new THREE.Line( geometry, new THREE.LineBasicMaterial( { color: 0x000000, opacity: 0.2 } ) );
line.position.z = ( i * 50 ) - 500;
scene.add( line );
line = new THREE.Line( geometry, new THREE.LineBasicMaterial( { color: 0x000000, opacity: 0.2 } ) );
line.position.x = ( i * 50 ) - 500;
line.rotation.y = 90 * Math.PI / 180;
scene.add( line );
}
// extrudePath, Helix Curve
extrudePath = new THREE.SplineCurve3([
new THREE.Vector3(0, 10, 10),
new THREE.Vector3(10, 0, 10),
new THREE.Vector3(10, 0, 0)
]);
console.log(extrudePath);
// Tube Geometry
var segments = 50;
var closed = false;
var debug = true;
var radiusSegments = 12;
//alert('hello');
var tube = new THREE.TubeGeometry(extrudePath, segments, 2, radiusSegments, closed, debug);
// Tube Mesh
tubeMesh = THREE.SceneUtils.createMultiMaterialObject( tube, [
new THREE.MeshLambertMaterial({
color: 0xff00ff,
opacity: tube.debug ? 0.2 : 0.8,
transparent: true
}),
new THREE.MeshBasicMaterial({
color: 0x000000,
opacity: 0.5,
wireframe: true
})]);
parent = new THREE.Object3D();
parent.position.y = 100;
if ( tube.debug ) tubeMesh.add( tube.debug );
//parent.add( tubeMesh );
scene.add( tubeMesh );
// projector
projector = new THREE.Projector();
// renderer
//renderer = new THREE.CanvasRenderer();
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
// stats
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
container.appendChild( stats.domElement );
document.addEventListener( 'mousedown', onDocumentMouseDown, false );
document.addEventListener( 'mouseover', onDocumentMouseOver, false );
document.addEventListener( 'touchstart', onDocumentTouchStart, false );
document.addEventListener( 'touchmove', onDocumentTouchMove, false );
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize() {
camera.left = window.innerWidth / - 2;
camera.right = window.innerWidth / 2;
camera.top = window.innerHeight / 2;
camera.bottom = window.innerHeight / - 2;
camera.aspect = window.innerWidth / window.innerHeight;
//camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function onDocumentMouseDown( event ) {
event.preventDefault();
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
document.addEventListener( 'mouseup', onDocumentMouseUp, false );
document.addEventListener( 'mouseout', onDocumentMouseOut, false );
mouseXOnMouseDown = event.clientX - windowHalfX;
targetRotationOnMouseDown = targetRotation;
}
function onDocumentMouseMove( event ) {
mouseX = event.clientX - windowHalfX;
targetRotation = targetRotationOnMouseDown + ( mouseX - mouseXOnMouseDown ) * 0.02;
}
function onDocumentMouseUp( event ) {
document.removeEventListener( 'mousemove', onDocumentMouseMove, false );
document.removeEventListener( 'mouseup', onDocumentMouseUp, false );
document.removeEventListener( 'mouseout', onDocumentMouseOut, false );
}
function onDocumentMouseOut( event ) {
document.removeEventListener( 'mousemove', onDocumentMouseMove, false );
document.removeEventListener( 'mouseup', onDocumentMouseUp, false );
document.removeEventListener( 'mouseout', onDocumentMouseOut, false );
}
function onDocumentMouseOver( event ) {
document.removeEventListener( 'mousemove', onDocumentMouseMove, false );
document.removeEventListener( 'mouseup', onDocumentMouseUp, false );
document.removeEventListener( 'mouseout', onDocumentMouseOut, false );
}
function onDocumentTouchStart( event ) {
if ( event.touches.length === 1 ) {
event.preventDefault();
mouseXOnMouseDown = event.touches[ 0 ].pageX - windowHalfX;
targetRotationOnMouseDown = targetRotation;
}
}
function onDocumentTouchMove( event ) {
if ( event.touches.length === 1 ) {
event.preventDefault();
mouseX = event.touches[ 0 ].pageX - windowHalfX;
targetRotation = targetRotationOnMouseDown + ( mouseX - mouseXOnMouseDown ) * 0.05;
}
}
function animate() {
requestAnimationFrame( animate );
render();
update();
}
function update()
{
controls.update();
stats.update();
}
function render() {
tubeMesh.rotation.y += ( targetRotation - tubeMesh.rotation.y ) * 0.15;
camera.updateMatrixWorld();
renderer.render( scene, camera );
}
</script>
</body>
</html>
Now when I change rendering from WebGL to Canvas, the FPS drops down to 1-2 FPS from 56-57 FPS on mobile browser. Native browser does not display anything on page and in Opera page becomes too slow for operations. How do I make page operations fast with Canvas rendering or how do I enable webgl rendering on mobile browsers ?
canvas renderer is software mode only, that means no GPU acceleration, the CPU has to do all the hard work that's why your fps drop.
AFAIK not every mobile browser is able to use webgl renderer yet, you could give opera mobile a try it's capable of webgl.
One way to speed up canvas rendering is to reduce the number of segments used in TubeGeometry

Categories

Resources