Pixi Js, CanvasRenderer error - pixi.js

I use pixi.js v 3.0.0
My simple code is
(function () {
document.addEventListener('DOMContentLoaded', function () {
var width = screen.availWidth;
var height = screen.availHeight;
var renderer = PIXI.CanvasRenderer(width, height, {
backgroundColor : 0x1099bb
});
document.body.appendChild(renderer.view);
var stage = new PIXI.Container();
var texture = PIXI.Texture.fromImage('asset/bunny.png');
var bunny = new PIXI.Sprite(texture);
bunny.anchor.x = 0.5;
bunny.anchor.y = 0.5;
bunny.position.x = 200;
bunny.position.y = 150;
stage.addChild(bunny);
animate();
function animate() {
requestAnimationFrame(animate);
bunny.rotation += 0.1;
renderer.render(stage);
}
}, false);
}
());
But i get: TypeError: this.initPlugins is not a function if use CanvasRenderer but it works in other cases

Just add new keyword when creating the CanvasRenderer.

Related

Any one now how to convert qr-code to file png format node [duplicate]

Im trying to make drawing app where you can draw something on canvas and save your result as an image on the server by clicking "save" button. You can also put another image as background for your drawing. The problem is that when I put an image to the canvas using ctx.drawImage() I can't save the canvas as an image because nothing happens. Everything works ok until I use ctx.drawImage(). Why I can't save canvas as an image with another image in it?
My ajax code:
// it works until I use ctx.drawImage()
$.ajax({
type: "POST",
url: "save.php",
data: {image: dataURL},
success: function()
{
alert('saved');
}
});
Code for putting another image as background:
//var ctx = can.getContext('2d');
var img = new Image;
ctx.drawImage (img, 0, 0);
My PHP code:
<?php
$dataURL = $_POST["image"];
$parts = explode(',', $dataURL);
$data = $parts[1];
$data = base64_decode($data);
$fp = fopen('test.png', 'w');
fwrite($fp, $data);
fclose($fp);
?>
This is the entire javascript code
$(document).ready (function()
{
var color = $("#color").val();
$("#size").val("10");
var mouse = 0;
var can = document.getElementById("canny");
var ctx = can.getContext('2d');
var offsetX = 158;
var offsetY = 200;
var img = new Image;
var url = "http://i.imgur.com/fmAoxZ0.jpg";
img.src = url;
function setBackground()
{
ctx.drawImage (img, 0, 0);
}
function setOpacity(newValue)
{
$("#canny").css ("opacity", newValue * 0.01);
$("#txt-opacity").html(newValue + "%");
}
$("body").mousedown(function(event)
{
color = $("#color").val();
var cordX = event.clientX - offsetX;
var cordY = event.clientY - offsetY;
var size = $("#size").val();
ctx.beginPath();
ctx.arc(cordX,cordY,size,0,2*Math.PI);
ctx.fillStyle = color;
ctx.fill();
document.getElementById("coords").innerHTML = "x: " + cordX + " y: " + cordY;
mouse = 1;
$("body").mousemove(function(event)
{
if (mouse == 1)
{
var cordX = event.clientX - offsetX;
var cordY = event.clientY - offsetY;
var size = $("#size").val();
ctx.beginPath();
ctx.arc(cordX,cordY,size,0,2*Math.PI);
ctx.fillStyle = color;
ctx.fill();
$("body").mouseup(function()
{
mouse = 0;
});
}
});
mouse = 1;
});
$("#opacity").change (function()
{
setOpacity(this.value);
});
$("#opacity").trigger("change");
$("#red").click (function()
{
$("#color").val("#FF3636");
$(this).css ("border-color", "darkorange");
$("#blue").css ("border-color", "black");
$("#lime").css ("border-color", "black");
$("#yellow").css ("border-color", "black");
});
$("#blue").click (function()
{
$("#color").val("#0080FF");
$(this).css ("border-color", "darkorange");
$("#red").css ("border-color", "black");
$("#lime").css ("border-color", "black");
$("#yellow").css ("border-color", "black");
});
$("#lime").click (function()
{
$("#color").val("#8CFF00");
$(this).css ("border-color", "darkorange");
$("#red").css ("border-color", "black");
$("#blue").css ("border-color", "black");
$("#yellow").css ("border-color", "black");
});
$("#yellow").click (function()
{
$("#color").val("#FFF01F");
$(this).css ("border-color", "darkorange");
$("#red").css ("border-color", "black");
$("#blue").css ("border-color", "black");
$("#lime").css ("border-color", "black");
});
$("#btn-clear").click(function()
{
if (confirm ("Are you sure to clear your image?"))
{
ctx.clearRect(0, 0, can.width, can.height);
}
});
$("#btn-save").click (function()
{
var dataURL = can.toDataURL();
$.ajax({
type: "POST",
url: "save.php",
data: {image: dataURL},
success: function()
{
alert('saved');
}
});
});
$("#fill").click (function()
{
$("#canny").css ("background-color", color);
});
$('input[type=radio][name=bgselect]').change (function ()
{
if (this.value == "image")
{
setBackground();
$("#url").css ("visibility", "visible");
img.src = url;
} else
{
$('#canny').css('background-image', 'none');
$("#url").css ("visibility", "hidden");
}
});
$("#url").change(function()
{
url = $(this).val();
setBackground();
});
});
Your problem is be with canvas.toDataURL which is disabled if you draw cross-domain images to your canvas. If you open your browser console using F12 you will see the security error.
Since you're image host (imgur.com) has enabled cross-domain access to your image, you can comply with cross-domain security by adding img.crossOrigin='anonymous' to your img object.
var img = new Image;
img.crossOrigin='anonymous';
var url = "http://i.imgur.com/fmAoxZ0.jpg";
img.src = url;

Lasso tool in html5 canvas - replacing the clipTo function with clipPath

The code shown below is from this post. It works fine when using fabric.js/1.4.0, but when I update fabric.js to 2.4.3, it fails to run. The issue is that the clipTo funtion has been replaced by a new function called clipPath. Does anyone know how to update this code so it works with clipPath? I've gone through the docs for clipPath and have been searching Google and Stackoverflow for almost 2 days, but I'm still lost.
var canvas = document.getElementById('c');
var ctx = canvas.getContext('2d');
var img = document.createElement('IMG');
img.onload = function() {
var OwnCanv = new fabric.Canvas('c', {
isDrawingMode: true
});
var imgInstance = new fabric.Image(img, {
left: 0,
top: 0,
});
OwnCanv.add(imgInstance);
OwnCanv.freeDrawingBrush.color = "purple"
OwnCanv.freeDrawingBrush.width = 4
OwnCanv.on('path:created', function(options) {
var path = options.path;
OwnCanv.isDrawingMode = false;
OwnCanv.remove(imgInstance);
OwnCanv.remove(path);
OwnCanv.clipTo = function(ctx) {
path.render(ctx);
};
OwnCanv.add(imgInstance);
});
}
img.src = "http://upload.wikimedia.org/wikipedia/commons/3/33/Jbassette4.jpg?uselang=fi";
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.1/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.4.0/fabric.min.js"></script>
<canvas id="c" width="500" height="500"></canvas>
Ok, so the path, right after being created is already cached.
What you need to do is set the fill to a color that is not null, using the 'set' method.
Then set the path as clipPath for the canvas, or the Object itself.
If you want to set it just for the object, you need to recalculate its correct position.
var canvas = document.getElementById('c');
var ctx = canvas.getContext('2d');
var img = document.createElement('IMG');
img.onload = function() {
var OwnCanv = new fabric.Canvas('c', {
isDrawingMode: true
});
var imgInstance = new fabric.Image(img, {
left: 0,
top: 0,
});
OwnCanv.add(imgInstance);
OwnCanv.controlsAboveOverlay = true;
OwnCanv.freeDrawingBrush.color = "purple"
OwnCanv.freeDrawingBrush.width = 4
OwnCanv.on('path:created', function(options) {
var path = options.path;
path.set('fill', 'black');
console.log(path)
OwnCanv.isDrawingMode = false;
OwnCanv.remove(path);
OwnCanv.clipPath = path;
});
}
img.src = "http://upload.wikimedia.org/wikipedia/commons/3/33/Jbassette4.jpg?uselang=fi";
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.1/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.4.6/fabric.min.js"></script>
<canvas id="c" width="500" height="500"></canvas>
You need to have objectCaching on false on the path.
Check here:https://jsfiddle.net/jw6rLx5f/2/
var canvas = document.getElementById('c');
var ctx = canvas.getContext('2d');
var img = document.createElement('IMG');
img.onload = function() {
var OwnCanv = new fabric.Canvas('c', {
isDrawingMode: true
});
var imgInstance = new fabric.Image(img, {
left: 0,
top: 0,
});
OwnCanv.add(imgInstance);
OwnCanv.freeDrawingBrush.color = "purple"
OwnCanv.freeDrawingBrush.width = 4
OwnCanv.on('path:created', function(options) {
var path = options.path;
path.objectCaching= false;
OwnCanv.isDrawingMode = false;
OwnCanv.remove(imgInstance);
OwnCanv.remove(path);
OwnCanv.clipTo = function(ctx) {
ctx.save();
path.render(ctx);
ctx.restore();
};
OwnCanv.add(imgInstance);
});
}
img.src = "http://upload.wikimedia.org/wikipedia/commons/3/33/Jbassette4.jpg?uselang=fi";
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.4.6/fabric.js"></script>
<canvas id="c" width="500" height="500"></canvas>

Electron desktopCapturer to Web API frequency all 0s

==== SOLVED ====
To be 100% honest I'm not sure what I did, but I have a fully working audio bar visualizer based on desktop audio. I went back to the original codepen (link below) I started working off of and edited everything as needed to accept a media stream, and it works.
Full Code
const {desktopCapturer} = require('electron')
desktopCapturer.getSources({types: ['window', 'screen']}, (error, sources) => {
if (error) throw error
for (let i = 0; i < sources.length; ++i) {
if (sources[i].name === 'Entire screen') {
navigator.mediaDevices.getUserMedia({
audio: { mandatory : { chromeMediaSource: 'desktop' }},
video: { mandatory : { chromeMediaSource: 'desktop' }}
})
.then((stream) => handleStream(stream))
return
}
}
})
function handleStream (stream)
{
const context = new AudioContext()
let src = context.createMediaStreamSource(stream)
let analyser = context.createAnalyser()
let canvas = document.getElementById("canvas")
canvas.width = window.innerWidth
canvas.height = window.innerHeight
let ctx = canvas.getContext("2d")
src.connect(analyser)
analyser.fftSize = 256
let bufferLength = analyser.frequencyBinCount
let dataArray = new Uint8Array(bufferLength)
let WIDTH = canvas.width
let HEIGHT = canvas.height
let barWidth = (WIDTH / bufferLength) * 2.5
let barHeight
let x = 0
function renderFrame()
{
requestAnimationFrame(renderFrame)
x = 0
analyser.getByteFrequencyData(dataArray)
ctx.fillStyle = "#000"
ctx.fillRect(0, 0, WIDTH, HEIGHT)
for (let i = 0; i < bufferLength; i++)
{
barHeight = dataArray[i]
let r = barHeight + (25 * (i / bufferLength))
var g = 250 * (i/bufferLength)
var b = 50
ctx.fillStyle = `rgb(${r}, ${g}, ${b})`
ctx.fillRect(x, HEIGHT - barHeight, barWidth, barHeight)
x += barWidth + 1
}
}
renderFrame()
}
Codepen I used as a starting point
https://codepen.io/nfj525/pen/rVBaab
Original Post
I'm working on setting up a desktop visualizer that will graph the users desktop audio.
desktopCapture appears to be grabbing the media as sending it to a video tag displays the stream, along with an echo of the media. Since I only need the audio, I'm setting the mediaStraem to an AudioContext MediaStreamSource, which also appears to be working as I get an audio echo if I connect the analyser to the ctx destination. The issue I'm running into is when I try to get the frequency data its returning an array of only 0s. Below is my current code
const {desktopCapturer} = require('electron')
desktopCapturer.getSources({types: ['window', 'screen']}, (error, sources) => {
if (error) throw error
for (let i = 0; i < sources.length; ++i) {
if (sources[i].name === 'Entire screen') {
navigator.mediaDevices.getUserMedia({
audio: {
mandatory : {
chromeMediaSource: 'desktop'
}
},
video: {
mandatory: {
chromeMediaSource: 'desktop',
}
}
})
.then((stream) => handleStream(stream))
return
}
}
})
function handleStream (stream) {
let audioCtx = new AudioContext();
let source = audioCtx.createMediaStreamSource(stream);
let analyser = audioCtx.createAnalyser()
//uncommenting results in echo, but still all 0s
//analyser.connect(audioCtx.destination)
analyser.fftSize = 256
let bufferLength = analyser.frequencyBinCount
let dataArray = new Uint8Array(bufferLength)
console.log(dataArray)
}
===== EDIT =====
I've been able to get this working; kind of but am still running into a slight issue.
1) I had connect the source and the analyzer with
source.connect(analyser)
2) Had to fill the dataArray with time domain with
getByteTimeDomainData
3) Outstanding issue is when there is no media playing the dataArray is filled with values of 126, 127, & 128 making the bars "dance" at almost full height.
4) The FPS also seems extremely fast, but have some plans to fix that
Current somewhat working code :
const {desktopCapturer} = require('electron')
desktopCapturer.getSources({types: ['window', 'screen']}, (error, sources) => {
if (error) throw error
for (let i = 0; i < sources.length; ++i) {
if (sources[i].name === 'Entire screen') {
navigator.mediaDevices.getUserMedia({
audio: {
mandatory : {
chromeMediaSource: 'desktop'
}
},
video: {
mandatory: {
chromeMediaSource: 'desktop',
}
}
})
.then((stream) => handleStream(stream))
return
}
}
})
function handleStream (stream) {
const audioCtx = new AudioContext()
let source = audioCtx.createMediaStreamSource(stream)
let analyser = audioCtx.createAnalyser()
source.connect(analyser) //Had To Connect Source To Analyser
analyser.fftSize = 128
let bufferLength = analyser.frequencyBinCount
let dataArray = new Uint8Array(bufferLength)
let canvas = document.getElementById("canvas")
canvas.width = window.innerWidth
canvas.height = window.innerHeight
let canvasCtx = canvas.getContext("2d")
let WIDTH = canvas.width;
let HEIGHT = canvas.height;
let barWidth = (WIDTH / bufferLength);
let barHeight;
let x = 0;
function draw() {
var drawVisual = requestAnimationFrame(draw)
analyser.getByteTimeDomainData(dataArray) //added to the draw to fill the dataArray
canvasCtx.fillStyle = "#000";
canvasCtx.fillRect(0, 0, WIDTH, HEIGHT);
var x = 0;
for (let i = 0; i < bufferLength; i++) {
barHeight = dataArray[i];
let r = 50
let g = 250
let b = 50
canvasCtx.fillStyle = `rgb(${r}, ${g}, ${b})`
canvasCtx.fillRect(x, HEIGHT - barHeight, barWidth, barHeight);
x += barWidth + 1;
}
}
draw()
}

GetCursorPos Node FFI - How to get pointer return by ref

I wrote following code to set keyboard cursor position. But get garbage. Any clue, what am I missing?
var ffi = require('ffi');
var ref = require('ref');
var Struct = require('ref-struct');
var point = Struct({
'x': 'long',
'y': 'long'
});
var user32 = ffi.Library('user32.dll', {
GetCaretPos:['bool',[locPtr]]
});
var pbuf = new point();
caretpos = user32.GetCaretPos(pbuf);
console.log(":",pbuf.x );
Next, I tried the following, but that doesn't work as well.
var ffi = require('ffi');
var ref = require('ref');
var Struct = require('ref-struct');
var voidPtr = ref.refType(ref.types.void);
var user32 = ffi.Library('user32.dll', {
GetCaretPos:['bool',[voidPtr]]
});
var pbuf = new Buffer(2);
caretpos = user32.GetCaretPos(pbuf);
var cpos =(new Uint8Array(pbuf));
console.log(">",cpos ); //Doesn't work **> Uint8Array [ 0, 0, 0, 0 ]**
As the article heading states "GetCursorPos in Node FFI" and return pointer x,y
The code below works for me, its a hack to get the x,y pointer.
var ffi = require('ffi');
var repbuffer = new Buffer(16); // holder for windows structures
var user32 = ffi.Library('user32.dll', {
'GetCursorPos':['bool',['pointer']]
});
//Show mouse cords at console every sec
setInterval( function() { getmousepos();}, 1000);
function getmousepos(){
var p = user32.GetCursorPos(repbuffer);
var x= repbuffer[0]+ (repbuffer[1]*256);
var y= repbuffer[4]+(repbuffer[5]*256);
console.log(x + " " + y);
}
What worked for me:
var PointStruct = Struct({
x: ffi.types.long,
y: ffi.types.long,
});
var user32 = ffi.Library("user32", {
GetCursorPos: ["bool", [ref.refType(PointStruct)]],
SetCursorPos: ["long", ["long", "long"]],
});
export function GetMousePos() {
let mousePosBuffer = ref.alloc(PointStruct);
let success = user32.GetCursorPos(mousePosBuffer);
let mousePos = mousePosBuffer["deref"]() as {x: number, y: number};
return new Vector2i(mousePos.x, mousePos.y);
}
export function SetMousePos(x: number, y: number) {
user32.SetCursorPos(x, y);
}

Immovable property not working in phaser

Here is my code regarding tilesprite & a player, player should not pass through tilesprite but unfortunately my code is not working, i tried all ways but couldn't achieve the desired result, i don't know why tile2.body.immovable=true; flag not working.
var main = {
preload: function () {
this.game.load.image('ground', 'images/ground.jpg');
this.game.load.image('bg', 'images/gabg.jpg');
this.game.load.atlasJSONHash('mover', 'images/sheet.png', 'images/sprites.json');
},
create: function () {
this.game.physics.startSystem(Phaser.Physics.ARCADE);
cursor = this.game.input.keyboard.createCursorKeys();
tile1 = game.add.tileSprite(0, 10, 1365, 582, 'bg');
tile2 = game.add.tileSprite(0, 590, 1366, 91, 'ground');
player = this.game.add.sprite(50, 550, 'mover');
player.frame = 0;
player.anchor.setTo(0.5, 0.5);
while (i < 11) {
anim.push(i)
i++;
}
player.animations.add('move', anim, 20, true);
this.game.physics.arcade.enable(player);
this.game.physics.arcade.enable(tile2);
tile2.body.immovable = true;
tile2.body.allowGravity = false;
player.body.gravity.y = 800;
},
update: function () {
this.game.physics.arcade.collide(tile2, player);
tile1.tilePosition.x += -1;
tile2.tilePosition.x += -4;
this.move();
},
move: function () {
if (cursor.up.isDown) {
player.body.velocity.y = -200;
player.animations.stop('move');
}
else {
player.animations.play('move');
}
},
};
var game = new Phaser.Game(1366, 768, Phaser.CANVAS, 'gamediv');
this.game.state.add('main', main);
this.game.state.start('main');
var anim = [];
var cursor, i=0;
var tile1;
var tile2;
var player;
Which version of Phaser are you using? Could it be related to this bug in 2.3.0?
http://www.html5gamedevs.com/topic/13856-problem-with-collide-method-from-physics-arcade-in-different-versions-of-phaser/?p=79032

Resources