Socket.io - dragging DIV by multiple users not working - html

I'm trying to use this on my webpage. But when I'm opening the webpage in two different webbrowsers, and when I drag the div, it doesn't update on both, just the one i'm dragging in. Below is the code I'm using. Why is this not working?
Below is index.html in my http://mywebsite.com/myProject/
<!DOCTYPE html>
<html>
<head>
<script src="http://code.jquery.com/jquery-1.8.3.js"></script>
<script src="http://code.jquery.com/ui/1.10.0/jquery-ui.js"></script>
<script src="socket.io.js"></script>
<script>
$(document).ready(function () {
var socket = io("http://mywebsite.com/myProject/");
socket.on('update_position', function (data) {
var x = data.x;
var y = data.y;
// jquery code to move div here
$("#left").val(x);
$("#top").val(y);
$("#mydiv").css({
left: x + "px",
top: y + "px"
});
});
$("#mydiv").draggable({
drag: function (event, ui) {
var coord = $(this).position();
$("#left").val(coord.left);
$("#top").val(coord.top);
socket.emit('receive_position', {
x: coord.left,
y: coord.top
});
}
});
});
</script>
<style>
.dstyle
{
position: absolute;
width: 50px; height: 50px;
background: #ffb; padding: 5px;
border: 2px solid #999;
}
</style>
</head>
<body>
X: <input type="text" id="left"/>
Y: <input type="text" id="top"/>
<div id="mydiv" class="dstyle">drag me</div>
</body>
And here is the server.js below
var app = require('http').createServer(handler)
, io = require('socket.io').listen(app)
, fs = require('fs')
app.listen(3000);
function handler (req, res) {
fs.readFile(__dirname + '/index.html',
function (err, data) {
if (err) {
res.writeHead(500);
return res.end('Error loading index.html');
}
res.writeHead(200);
res.end(data);
});
}
var lastPosition = { x: 0, y: 0 }; // whatever default data
io.sockets.on('connection', function (socket) {
socket.emit('update_position', lastPosition);
socket.on('receive_position', function (data) {
lastPosition = data;
socket.broadcast.emit('update_position', data); // send `data` to all other clients
});
});

Problem solved! The problem was that my webhosting did not support Node JS, so now I am using glitch.com which has free hosting supporting Node JS

Related

Resize canvas element based on window change using VueJS

I am trying to resize a canvas element to the width of the window using VueJS. I've seen many examples of this working with vanilla JS, but for whatever reason, with VueJS I can't get the canvas content to re-render.
An example is attached. The example is modified from the vanilla JS version from here: http://ameijer.nl/2011/08/resizable-html5-canvas/
https://codepen.io/bastula/pen/yZXowo
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<title>Canvas Test</title>
</head>
<body>
<div id="app">
<canvas id="image-canvas" ref="imagecanvas" v-bind:width="width" v-bind:height="height" style="
background-color: #000;">
</canvas>
</div>
</body>
</html>
<script type="text/javascript" src="https://unpkg.com/vue"></script>
<script>
const app = new Vue({
el: '#app',
data: function () {
return {
height: 512,
width: 512,
margin: 20,
};
},
mounted() {
window.addEventListener('resize', this.handleResize);
this.handleResize();
},
computed: {
canvas: function () {
return this.$refs.imagecanvas;
},
ctx: function () {
return this.canvas.getContext('2d');
}
},
methods: {
handleResize: function () {
// Calculate new canvas size based on window
this.height = window.innerHeight - this.margin;
this.width = window.innerWidth - this.margin;
this.drawText();
},
drawText: function () {
// Redraw & reposition content
var resizeText = 'Canvas width: ' + this.canvas.width + 'px';
this.ctx.textAlign = 'center';
this.ctx.fillStyle = '#fff';
this.ctx.fillText(resizeText, 200, 200);
}
},
beforeDestroy() {
window.removeEventListener('resize', this.handleResize);
}
})
</script>
Solved here: https://forum.vuejs.org/t/resize-canvas-element-based-on-window-change-using-vuejs/55497/2?u=bastula
The solution is to use: nextTick.
So instead of this.drawText() in the handleResize method it should be:
this.$nextTick(() => {
this.drawText();
})
Updated working CodePen can be found here.

canvas is throw error of tainted after LoadFromJson

I am using fabric js version 1.7.22
when image set in a repetitive manner in a rectangle of fabric js, at
the first time it will be loaded and saved into JSON using toJSON()
and save an image using todataUrl() method, but when cal canvas a loadFromJson method at that time, this canvas not savable, because it throws tainted canvas error.
Please help me,
I already set crossOrigin in a pattern but it not working. and not
added in canvas JSON.
I have made one Fiddle For Generate Issue :
[http://jsfiddle.net/Mark_1998/kt387vLc/1/][1]
Steps to generate issue :
click on 'set pattern'
then click on 'save canvas'
then click on 'reload canvas' // load canvas from JSON
then click on 'save canvas' // cause issue of tainted canvas
This issue is fixed in new version of fabricjs already. If you are still using 1.7.20 the override fabric.Pattern.prototype.toObject and fabric.Pattern.prototype.initialize, find code in snippet.
var canvas = new fabric.Canvas('canvas', {
height: 500,
width: 500,
});
canvas.backgroundColor = '#ff0000';
canvas.renderAll();
var canvasJSON = {};
document.getElementById('setPat').addEventListener('click', function() {
fabric.util.loadImage('https://cdn.dribbble.com/assets/icon-backtotop-1b04df73090f6b0f3192a3b71874ca3b3cc19dff16adc6cf365cd0c75897f6c0.png', function(image) {
var pattern = new fabric.Pattern({
source: image,
repeat: 'repeat',
crossOrigin: 'Anonymous'
});
var patternObject = new fabric.Rect({
left: 0,
top: 0,
height: canvas.height,
width: canvas.width,
angle: 0,
fill: pattern,
objectCaching: false
})
canvas.add(patternObject);
}, null, {
crossOrigin: 'Anonymous'
});
})
document.getElementById('saveCanvas').addEventListener('click', function() {
console.log('save canvas');
canvasJSON = canvas.toJSON();
var image = canvas.toDataURL("image/png", {
crossOrigin: 'Anonymous'
}); // don't remove this, i need it as thumbnail.
//console.log('canvas.Json', canvasJSON);
//console.log('image', image);
canvas.clear();
canvas.backgroundColor = '#ff0000';
canvas.renderAll();
});
document.getElementById('reloadCanvas').addEventListener('click', function() {
console.log('save canvas');
canvas.loadFromJSON(canvasJSON, function() {
canvas.set({
crossOrigin: 'Anonymous'
})
});
console.log('canvas.Json', canvasJSON);
});
//cross origin was not added in toObject JSON
fabric.Pattern.prototype.toObject = (function(toObject) {
return function() {
return fabric.util.object.extend(toObject.call(this), {
crossOrigin: this.crossOrigin,
patternTransform: this.patternTransform ? this.patternTransform.concat() : null
});
};
})(fabric.Pattern.prototype.toObject);
//cross origin was not added while creating image
fabric.Pattern.prototype.initialize = function(options, callback) {
options || (options = {});
this.id = fabric.Object.__uid++;
this.setOptions(options);
if (!options.source || (options.source && typeof options.source !== 'string')) {
callback && callback(this);
return;
}
// function string
if (typeof fabric.util.getFunctionBody(options.source) !== 'undefined') {
this.source = new Function(fabric.util.getFunctionBody(options.source));
callback && callback(this);
} else {
// img src string
var _this = this;
this.source = fabric.util.createImage();
fabric.util.loadImage(options.source, function(img) {
_this.source = img;
callback && callback(_this);
}, null, this.crossOrigin);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.20/fabric.js"></script>
<button id="setPat">
Set pattern
</button>
<button id="saveCanvas">
Save canvas
</button>
<button id="reloadCanvas">
Reload CAnvas
</button>
<canvas id="canvas"></canvas>

Wistia javascript api change video source

I am having trouble understanding their api.
First, not sure why havent they sticked to iframe embed method (and api appearance) for consistency like youtube and vimeo have been doing for years.
So after a lot of digging, I have this to change video source. I am still not sure if this is the best method to embed video?
When I use replaceWith the problem is that events ("play" in this example) are not heard any more.
//head
<script src="//fast.wistia.com/assets/external/E-v1.js" async></script>
<script type="text/javascript">
jQuery(document).ready(function($) {
var video;
window._wq = window._wq || [];
_wq.push({
id: '479268413a',
options: {
autoPlay:true
},
onReady: function(v) {
video = v;
video.bind("play", function(){
console.log("play");
})
}
});
$('#btn-next').on('click', function(){
video.replaceWith(
'5bbw8l7kl5', {
autoPlay:true
});
});
});
</script>
//body
<div class="wistia_embed wistia_async_479268413a"></div>
I'm late to this question, but If you are looking for method that doesn't require you to have all images loaded as suggested by Kiran, you can push your config again after your do replaceWith.
const applyConfig = (id) => {
window._wq = window._wq || [];
_wq.push({
id,
options: {
autoPlay:true
},
onReady: function(v) {
video = v;
v.bind("play", function(){
console.log("play");
})
}
});
}
$('#btn-next').on('click', function(){
video.replaceWith(id);
applyConfig(id);
});
What you should do is have all the videos on your page and then show and hide based on click event. (Note that the videos will come asynchronously from wistia. So no need to worry about performance here)
Please check the demo below.
$(".wistia-trigger").click(function(){
var vid = $(this).attr("data-video-id");
$(".wistia_embed").hide();
$(".wistia_embed.wistia_async_"+vid).show();
window._wq = window._wq || [];
// pause all videos and move time to zero
_wq.push({ id: "_all", onReady: function(video) {
video.pause();
video.time(0);
}});
// start playing current video
_wq.push({ id: vid, onReady: function(video) {
video.play();
}});
});
.wistia_embed {
display: none;
width: 200px;
height: 200px;
float: left;
}
.wistia-trigger {
float: left;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//fast.wistia.com/assets/external/E-v1.js" async></script>
<div class="wistia_embed wistia_async_479268413a"></div>
<div class="wistia_embed wistia_async_5bbw8l7kl5"></div>
<button class="wistia-trigger" data-video-id="479268413a">
play 479268413a
</button>
<button class="wistia-trigger" data-video-id="5bbw8l7kl5">
play 5bbw8l7kl5
</button>

I want to use ng-contextmenu on my html page for providing different menu items. But my JS class is not getting called.

This is my html class, I have used one example from net for understanding how it's works.
<form>
<div ng-controller="ListController">
<div>
<strong>Gold: </strong>
{{player.gold}}
</div>
<div class="list-group">
<a href="#"
class="list-group-item"
ng-repeat="item in items"
context-menu="menuOptions">
<span class="badge">{{item.cost}}</span>
{{item.name}}
</a>
</div>
</div>
</form>
This is controller :
controller('ListController', ['$scope',
function ($scope) {
$scope.player = {
gold: 100
};
$scope.items = [
{ name: 'Small Health Potion', cost: 4 },
{ name: 'Small Mana Potion', cost: 5 },
{ name: 'Iron Short Sword', cost: 12 }
];
$scope.menuOptions = [
['Buy', function ($itemScope) {
$scope.player.gold -= $itemScope.item.cost;
}],
null,
['Sell', function ($itemScope) {
$scope.player.gold += $itemScope.item.cost;
}]
];
}
]);
This is my JS file, which is being used for contextmenu:
var app = angular.module("contextMenu",[]);
app.directive('contextMenu', function ($parse) {
var renderContextMenu = function ($scope, event, options) {
if (!$) { var $ = angular.element; }
$(event.currentTarget).addClass('context');
var $contextMenu = $('<div>');
$contextMenu.addClass('dropdown clearfix');
var $ul = $('<ul>');
$ul.addClass('dropdown-menu');
$ul.attr({ 'role': 'menu' });
$ul.css({
display: 'block',
position: 'absolute',
left: event.pageX + 'px',
top: event.pageY + 'px'
});
angular.forEach(options, function (item, i) {
var $li = $('<li>');
if (item === null) {
$li.addClass('divider');
} else {
$a = $('<a>');
$a.attr({ tabindex: '-1', href: '#' });
$a.text(typeof item[0] == 'string' ? item[0] : item[0].call($scope, $scope));
$li.append($a);
$li.on('click', function ($event) {
$event.preventDefault();
$scope.$apply(function () {
$(event.currentTarget).removeClass('context');
$contextMenu.remove();
item[1].call($scope, $scope);
});
});
}
$ul.append($li);
});
$contextMenu.append($ul);
var height = Math.max(
document.body.scrollHeight, document.documentElement.scrollHeight,
document.body.offsetHeight, document.documentElement.offsetHeight,
document.body.clientHeight, document.documentElement.clientHeight
);
$contextMenu.css({
width: '100%',
height: height + 'px',
position: 'absolute',
top: 0,
left: 0,
zIndex: 9999
});
$(document).find('body').append($contextMenu);
$contextMenu.on("mousedown", function (e) {
if ($(e.target).hasClass('dropdown')) {
$(event.currentTarget).removeClass('context');
$contextMenu.remove();
}
}).on('contextmenu', function (event) {
$(event.currentTarget).removeClass('context');
event.preventDefault();
$contextMenu.remove();
});
};
return function ($scope, element, attrs) {
element.on('contextmenu', function (event) {
$scope.$apply(function () {
event.preventDefault();
var options = $scope.$eval(attrs.contextMenu);
if (options instanceof Array) {
renderContextMenu($scope, event, options);
} else {
throw '"' + attrs.contextMenu + '" not an array';
}
});
});
};
});
But this code is not working for me. My debug point never comes on contextmenu js file. And I am getting default window menu on right click.
Can anyone please suggest what I am doing wrong or missing in this. It would be a great help.
First you have to create a master app.js file to define your modules something like below. The file needs to be loaded first.
(function () {
var module = angular.module('app', [
'contextMenu',
'menu'
]);
})();
Now the file which holds controller needs to be something like below.
(function () {
var module = angular.module('menu');
module.controller('ListController', [
'$scope'
function ($scope) {
//Your controller code goes here
}]);
})();
Your html needs to be something like below.
<body ng-app="app">
//Your html goes here
</body>
Your js files needs to be added in below order.
Angularjs
app.js
menu.js
That's all i can say for now.

Creating Waypoints using Bing Maps API

I'm creating a program that would allow users to save a route to a database - however, that's against the terms for Bing Maps, so I am allowing waypoints to be created and saved. I'm not quite sure how to start doing that. I thought I knew how to create the waypoints - but it's not working I'm using Visual Studio - VB.NET/ASP.NET. Would it be recommended to put it in through HTML or Visual Basic? HTML is where all the other Bing coding is located.
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<script type="text/javascript" src="http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0"></script>
<script type="text/javascript">
var map = null;
var directionsManager;
var directionsErrorEventObj;
var directionsUpdatedEventObj;
function getMap() {
map = new Microsoft.Maps.Map(document.getElementById('myMap'), { credentials: 'AohjORMDA3Vf0mCtDaEsnVHlza-E9AQMlGa0fKhH-6cvoT09Wjhc2RVzCpKG9HbP' });
}
function createDirectionsManager() {
var displayMessage;
if (!directionsManager) {
directionsManager = new Microsoft.Maps.Directions.DirectionsManager(map);
displayMessage = 'Directions Module loaded\n';
displayMessage += 'Directions Manager loaded';
}
alert(displayMessage);
directionsManager.resetDirections();
directionsErrorEventObj = Microsoft.Maps.Events.addHandler(directionsManager, 'directionsError', function (arg) { alert(arg.message) });
directionsUpdatedEventObj = Microsoft.Maps.Events.addHandler(directionsManager, 'directionsUpdated', function () { alert('Directions updated') });
}
function createDrivingRoute() {
if (!directionsManager) { createDirectionsManager(); }
directionsManager.resetDirections();
// Set Route Mode to driving
directionsManager.setRequestOptions({ routeMode: Microsoft.Maps.Directions.RouteMode.driving });
var startWaypoint = new Microsoft.Maps.Directions.Waypoint({ address: 'Bismarck, ND' });
directionsManager.addWaypoint(startWaypoint);
var destinationWaypoint = new Microsoft.Maps.Directions.Waypoint({ address: document.getElementById('hometown').value });
directionsManager.addWaypoint(destinationWaypoint);
// Set the element in which the itinerary will be rendered
directionsManager.setRenderOptions({ itineraryContainer: document.getElementById('directionsItinerary') });
alert('Calculating directions...');
directionsManager.calculateDirections();
}
function createDirections() {
if (!directionsManager) {
Microsoft.Maps.loadModule('Microsoft.Maps.Directions', { callback: createDrivingRoute });
}
else {
createDrivingRoute();
}
}
function hometown_onclick() {
}
This is what I have as of right now. This is the code I need to put in for a waypoint - when I have tried putting it in, the directions did not show up:
function addWaypoint() {
if (!directionsManager) { createDirectionsManager(); }
if (directionsManager.getAllWaypoints().length < 2) {
directionsManager.resetDirections();
var startWaypoint = new Microsoft.Maps.Directions.Waypoint({ address: 'Bismarck, ND' });
directionsManager.addWaypoint(startWaypoint);
var destinationWaypoint = new Microsoft.Maps.Directions.Waypoint({ address: document.getElementById('hometown').value });
directionsManager.addWaypoint(destinationWaypoint);
}
// Insert a waypoint
directionsManager.addWaypoint(new Microsoft.Maps.Directions.Waypoint({ address: 'Mandan, ND' });
// Set the element in which the itinerary will be rendered
directionsManager.setRenderOptions({ itineraryContainer: document.getElementById('directionsItinerary') });
displayAlert('Calculating directions...');
directionsManager.calculateDirections();
}
if (!directionsManager) {
Microsoft.Maps.loadModule('Microsoft.Maps.Directions', { callback: addWaypoint });
}
else {
addWaypoint();
}
Let's start with this problem. How can I fix this?
I found the answer. The waypoint will load automatically once the form is loaded.
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<script type="text/javascript" src="http://ecn.dev.virtualearth.net/mapcontrol /mapcontrol.ashx?v=7.0"></script>
<script type="text/javascript">
var map = null;
var directionsManager;
var directionsErrorEventObj;
var directionsUpdatedEventObj;
function getMap() {
map = new Microsoft.Maps.Map(document.getElementById('myMap'), { credentials: 'AohjORMDA3Vf0mCtDaEsnVHlza-E9AQMlGa0fKhH-6cvoT09Wjhc2RVzCpKG9HbP' });
}
function createDirectionsManager() {
var displayMessage;
if (!directionsManager) {
directionsManager = new Microsoft.Maps.Directions.DirectionsManager(map);
displayMessage = 'Directions Module loaded\n';
displayMessage += 'Directions Manager loaded';
}
alert(displayMessage);
directionsManager.resetDirections();
directionsErrorEventObj = Microsoft.Maps.Events.addHandler(directionsManager, 'directionsError', function (arg) { alert(arg.message) });
directionsUpdatedEventObj = Microsoft.Maps.Events.addHandler(directionsManager, 'directionsUpdated', function () { alert('Directions updated') });
}
function createDrivingRoute() {
if (!directionsManager) { createDirectionsManager(); }
directionsManager.resetDirections();
// Set Route Mode to driving
{
directionsManager.setRequestOptions({ routeMode: Microsoft.Maps.Directions.RouteMode.driving });
var startWaypoint = new Microsoft.Maps.Directions.Waypoint({ address: '7500 University Dr., Bismarck, ND' });
directionsManager.addWaypoint(startWaypoint);
var destinationWaypoint = new Microsoft.Maps.Directions.Waypoint({ address: document.getElementById('hometown').value });
directionsManager.addWaypoint(destinationWaypoint);
// Set the element in which the itinerary will be rendered
directionsManager.setRenderOptions({ itineraryContainer: document.getElementById('directionsItinerary') });
alert('Calculating directions...');
directionsManager.calculateDirections();
}
// Insert a waypoint
directionsManager.addWaypoint(new Microsoft.Maps.Directions.Waypoint({ address: 'Bismarck, ND'}), 1);
// Set the element in which the itinerary will be rendered
directionsManager.setRenderOptions({ itineraryContainer: document.getElementById('directionsItinerary') });
alert('Calculating directions...');
directionsManager.calculateDirections();
}
function createDirections() {
if (!directionsManager) {
Microsoft.Maps.loadModule('Microsoft.Maps.Directions', { callback: createDrivingRoute });
}
else {
createDrivingRoute();
}
}