User may upload images via drag'n'drop or select in dialog window. These files may be huge (dimensions and size), so before upload I want to resize with WebGL.
Shaders code was taken from this question, but I see black pixels instead of resized picture
Example code - run and drag pict to Result frame.
(function(){
'use strict';
var gl,
resizeToWidth = 1024;
function init(){
function cancel(e) {
e.preventDefault();
e.dataTransfer.dropEffect = 'copy';
}
document.addEventListener('dragenter', cancel, false);
document.addEventListener('dragover', cancel, false);
document.addEventListener('drop', function(e){
e.preventDefault();
e.stopPropagation();
var reader = new FileReader();
reader.onload = function(e){
var textureImage = new Image();
textureImage.onload = function(){
var ratio = textureImage.width/textureImage.height;
gl.viewportWidth = wrap.canvas.width = resizeToWidth;
gl.viewportHeight = wrap.canvas.height = resizeToWidth/ratio;
wrap.createTexture(textureImage);
wrap.initScene();
wrap.drawScene();
//var domImage = document.createElement("img");
//domImage.src = wrap.canvas.toDataURL('image/jpeg');
//document.body.appendChild(domImage);
//wrap.clear();
}
textureImage.src = e.currentTarget.result;
}
reader.readAsDataURL(e.dataTransfer.files[0]);
}, false);
var wrap = new WebGLWrap();
}
var WebGLWrap = function(){
gl = this.createContext();
this.shaders = new DOMShaders();
this.compileShaders();
this.shaderProgram = this.createShaderProgram();
this.createBuffers();
}
WebGLWrap.prototype = {
constructor: WebGLWrap,
clear: function(){
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
gl.clearColor(1.0, 1.0, 1.0, 1.0);
},
createContext: function(){
if(gl)
return gl;
var canvas = document.createElement('canvas'),
gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
if(!gl)
{
console.log("WebGL doesn't supported or disabled. Install latest version of Chrome, Firefox or Opera");
}
gl.viewportWidth = canvas.width = 50;
gl.viewportHeight = canvas.height = 50;
this.canvas = canvas;
document.body.appendChild(canvas);
return gl;
},
compileShaders: function(){
var shader,
self = this;
[].forEach.call(['vertex', 'fragment'], function(type){
shader = (type == 'vertex') ? gl.createShader(gl.VERTEX_SHADER) : gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(shader, self.shaders[type].code);
gl.compileShader(shader);
if(gl.getShaderParameter(shader, gl.COMPILE_STATUS))
{
self.shaders[type].compiled = shader;
}else{ console.log( gl.getShaderInfoLog(shader) ) }
});
},
createTexture: function(oImage){
this.texture = gl.createTexture();
this.texture.width = oImage.width;
this.texture.height = oImage.height;
gl.bindTexture(gl.TEXTURE_2D, this.texture);
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, oImage);
gl.bindTexture(gl.TEXTURE_2D, null);
},
createShaderProgram: function(){
var program = gl.createProgram();
gl.attachShader(program, this.shaders['vertex'].compiled);
gl.attachShader(program, this.shaders['fragment'].compiled);
gl.linkProgram(program);
gl.useProgram(program);
program.vertexPositionAttribute = gl.getAttribLocation(program, "position");
gl.enableVertexAttribArray(program.vertexPositionAttribute);
program.vertexTexPositionAttribute = gl.getAttribLocation(program, "inputTextureCoordinate");
gl.enableVertexAttribArray(program.vertexTexPositionAttribute);
program.samplerUniformLocation = gl.getUniformLocation(program, "inputImageTexture");
program.texelWidthOffset = gl.getUniformLocation(program, "texelWidthOffset");
program.texelHeightOffset = gl.getUniformLocation(program, "texelHeightOffset");
return program;
},
createBuffers: function(){
this.buffers = {};
this.buffers["vertexPosition"] = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, this.buffers["vertexPosition"])
var vertices = [
-1, -1,
-1, 1,
1, -1,
1, 1
];
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
gl.bindBuffer(gl.ARRAY_BUFFER, null);
this.buffers["vertexTexPosition"] = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, this.buffers["vertexTexPosition"])
var vertices = [
0, 0,
0, 1,
1, 0,
1, 1
];
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
gl.bindBuffer(gl.ARRAY_BUFFER, null);
},
initScene: function(){
gl.bindBuffer(gl.ARRAY_BUFFER, this.buffers["vertexPosition"]);
gl.vertexAttribPointer(this.shaderProgram["vertexPositionAttribute"], 2, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, this.buffers["vertexTexPosition"]);
gl.vertexAttribPointer(this.shaderProgram["vertexTexPositionAttribute"], 2, gl.FLOAT, false, 0, 0);
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, this.texture);
gl.uniform1i(this.shaderProgram["samplerUniformLocation"], 0);
gl.uniform1f(this.shaderProgram["texelWidthOffset"], 1.0/this.texture.width );
gl.uniform1f(this.shaderProgram["texelHeightOffset"], 0 );
},
drawScene: function(){
gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
}
};
var DOMShaders = function (){
this.loadShaders()
}
DOMShaders.prototype.updateShaders = function(elm)
{
switch(elm.type)
{
case "x-shader/x-vertex":
this.vertex = {code: elm.textContent};
break;
case "x-shader/x-fragment":
this.fragment = {code: elm.textContent};
break;
default:
void(0);
}
}
DOMShaders.prototype.loadShaders = function()
{
var shaderElms = document.querySelectorAll('.shader');
for(var i = 0; i < shaderElms.length; i++)
{
this.updateShaders(shaderElms[i]);
}
}
window.addEventListener('load', init, false);
})();
What I do wrong?
Related
In the javascript graphing library, is there a way I can change the line segment color of the line between two adjacent points?
Thanks
You can extend the chart to redraw the segment of your choice with the different color.
Preview
Script
Chart.types.Line.extend({
name: "LineAlt",
draw: function () {
Chart.types.Line.prototype.draw.apply(this, arguments);
var index = 1;
var datasetIndex = 0;
var hasValue = function(item){
return item.value !== null;
},
previousPoint = function (point, collection, index) {
return Chart.helpers.findPreviousWhere(collection, hasValue, index) || point;
};
var ctx = this.chart.ctx;
var dataset = this.datasets[datasetIndex];
var pointsWithValues = Chart.helpers.where(dataset.points, hasValue);
ctx.strokeStyle = 'red';
ctx.lineWidth = 3;
ctx.beginPath();
var point = dataset.points[index];
ctx.moveTo(point.x, point.y);
point = dataset.points[index + 1];
var previous = previousPoint(point, pointsWithValues, index + 1);
ctx.bezierCurveTo(
previous.controlPoints.outer.x,
previous.controlPoints.outer.y,
point.controlPoints.inner.x,
point.controlPoints.inner.y,
point.x,
point.y
);
ctx.stroke();
}
});
and
...
new Chart(ctx).LineAlt(data);
Fiddle - http://jsfiddle.net/021xvuhd/10/
Here's a working example to do this in Charts.js 2
https://jsfiddle.net/egamegadrive16/zjdwr4fh/
var ctx = document.getElementById('myChart').getContext('2d');
//adding custom chart type
Chart.defaults.multicolorLine = Chart.defaults.line;
Chart.controllers.multicolorLine = Chart.controllers.line.extend({
draw: function(ease) {
var
startIndex = 0,
meta = this.getMeta(),
points = meta.data || [],
colors = this.getDataset().colors,
area = this.chart.chartArea,
originalDatasets = meta.dataset._children
.filter(function(data) {
return !isNaN(data._view.y);
});
function _setColor(newColor, meta) {
meta.dataset._view.borderColor = newColor;
}
if (!colors) {
Chart.controllers.line.prototype.draw.call(this, ease);
return;
}
for (var i = 2; i <= colors.length; i++) {
if (colors[i-1] !== colors[i]) {
_setColor(colors[i-1], meta);
meta.dataset._children = originalDatasets.slice(startIndex, i);
meta.dataset.draw();
startIndex = i - 1;
}
}
meta.dataset._children = originalDatasets.slice(startIndex);
meta.dataset.draw();
meta.dataset._children = originalDatasets;
points.forEach(function(point) {
point.draw(area);
});
}
});
var chart = new Chart(ctx, {
// The type of chart we want to create
type: 'multicolorLine',
// The data for our dataset
data: {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: "My First dataset",
borderColor: 'rgb(255, 99, 132)',
data: [0, 10, 5, 2, 20, 30, 45],
//first color is not important
colors: ['', 'red', 'green', 'blue']
}]
},
// Configuration options go here
options: {}
});
source: https://github.com/chartjs/Chart.js/issues/4895#issuecomment-342747042
It's now built into CHart.js 3:
https://www.chartjs.org/docs/latest/samples/line/segments.html
I'm new to Famo.us and I am trying to expand on the Timbre sample app by adding a scrollview to the PageView where the image would be (in the _createBody function). In other words, I'm trying to add a feed similar to Facebook or Tango, etc. I found two pieces of code online that's been working with (links below). I get no errors on the console log, yet the scrollview won't display, so I'm not sure what I am missing. Your guidance is much appreciated (would also love to know if there is a better way). Finally, this is my first post ever on StackOverflow, so please let me know if I can expose my issue in a better fashion.
Links I have been using for guidance:
StackOverflowFamo.us swipe on scrollview
JSFiddle
/*** AppView.js ***/
define(function(require, exports, module) {
var View = require('famous/core/View');
var Surface = require('famous/core/Surface');
var Modifier = require('famous/core/Modifier');
var Transform = require('famous/core/Transform');
var StateModifier = require('famous/modifiers/StateModifier');
var Easing = require('famous/transitions/Easing');
var Transitionable = require('famous/transitions/Transitionable');
var GenericSync = require('famous/inputs/GenericSync');
var MouseSync = require('famous/inputs/MouseSync');
var TouchSync = require('famous/inputs/TouchSync');
GenericSync.register({'mouse': MouseSync, 'touch': TouchSync});
var PageView = require('views/PageView');
var MenuView = require('views/MenuView');
var StripData = require('data/StripData');
function AppView() {
View.apply(this, arguments);
this.menuToggle = false;
this.pageViewPos = new Transitionable(0);
_createPageView.call(this);
_createMenuView.call(this);
_setListeners.call(this);
_handleSwipe.call(this);
}
AppView.prototype = Object.create(View.prototype);
AppView.prototype.constructor = AppView;
AppView.DEFAULT_OPTIONS = {
openPosition: 276,
transition: {
duration: 300,
curve: 'easeOut'
},
posThreshold: 138,
velThreshold: 0.75
};
function _createPageView() {
this.pageView = new PageView();
this.pageModifier = new Modifier({
transform: function() {
return Transform.translate(this.pageViewPos.get(), 0, 0);
}.bind(this)
});
this._add(this.pageModifier).add(this.pageView);
}
function _createMenuView() {
this.menuView = new MenuView({ stripData: StripData });
var menuModifier = new StateModifier({
transform: Transform.behind
});
this.add(menuModifier).add(this.menuView);
}
function _setListeners() {
this.pageView.on('menuToggle', this.toggleMenu.bind(this));
}
function _handleSwipe() {
var sync = new GenericSync(
['mouse', 'touch'],
{direction : GenericSync.DIRECTION_X}
);
this.pageView.pipe(sync);
sync.on('update', function(data) {
var currentPosition = this.pageViewPos.get();
if(currentPosition === 0 && data.velocity > 0) {
this.menuView.animateStrips();
}
this.pageViewPos.set(Math.max(0, currentPosition + data.delta));
}.bind(this));
sync.on('end', (function(data) {
var velocity = data.velocity;
var position = this.pageViewPos.get();
if(this.pageViewPos.get() > this.options.posThreshold) {
if(velocity < -this.options.velThreshold) {
this.slideLeft();
} else {
this.slideRight();
}
} else {
if(velocity > this.options.velThreshold) {
this.slideRight();
} else {
this.slideLeft();
}
}
}).bind(this));
}
AppView.prototype.toggleMenu = function() {
if(this.menuToggle) {
this.slideLeft();
} else {
this.slideRight();
this.menuView.animateStrips();
}
};
AppView.prototype.slideLeft = function() {
this.pageViewPos.set(0, this.options.transition, function() {
this.menuToggle = false;
}.bind(this));
};
AppView.prototype.slideRight = function() {
this.pageViewPos.set(this.options.openPosition, this.options.transition, function() {
this.menuToggle = true;
}.bind(this));
};
module.exports = AppView;
});
/*** PageView.js ***/
define(function(require, exports, module) {
var View = require('famous/core/View');
var Surface = require('famous/core/Surface');
var Transform = require('famous/core/Transform');
var StateModifier = require('famous/modifiers/StateModifier');
var HeaderFooter = require('famous/views/HeaderFooterLayout');
var ImageSurface = require('famous/surfaces/ImageSurface');
var Scrollview = require('famous/views/Scrollview');
function PageView() {
View.apply(this, arguments);
_createBacking.call(this);
_createLayout.call(this);
_createHeader.call(this);
_createBody.call(this);
_setListeners.call(this);
}
PageView.prototype = Object.create(View.prototype);
PageView.prototype.constructor = PageView;
PageView.DEFAULT_OPTIONS = {
headerSize: 44
};
function _createBacking() {
var backing = new Surface({
properties: {
backgroundColor: 'black',
boxShadow: '0 0 20px rgba(0,0,0,0.5)'
}
});
this.add(backing);
}
function _createLayout() {
this.layout = new HeaderFooter({
headerSize: this.options.headerSize
});
var layoutModifier = new StateModifier({
transform: Transform.translate(0, 0, 0.1)
});
this.add(layoutModifier).add(this.layout);
}
function _createHeader() {
var backgroundSurface = new Surface({
properties: {
backgroundColor: 'black'
}
});
this.hamburgerSurface = new ImageSurface({
size: [44, 44],
content : 'img/hamburger.png'
});
var searchSurface = new ImageSurface({
size: [232, 44],
content : 'img/search.png'
});
var iconSurface = new ImageSurface({
size: [44, 44],
content : 'img/icon.png'
});
var backgroundModifier = new StateModifier({
transform : Transform.behind
});
var hamburgerModifier = new StateModifier({
origin: [0, 0.5],
align : [0, 0.5]
});
var searchModifier = new StateModifier({
origin: [0.5, 0.5],
align : [0.5, 0.5]
});
var iconModifier = new StateModifier({
origin: [1, 0.5],
align : [1, 0.5]
});
this.layout.header.add(backgroundModifier).add(backgroundSurface);
this.layout.header.add(hamburgerModifier).add(this.hamburgerSurface);
this.layout.header.add(searchModifier).add(searchSurface);
this.layout.header.add(iconModifier).add(iconSurface);
}
function _createBody() {
var surfaces = [];
this.scrollview = new Scrollview();
var temp;
for (var i = 0; i < 30; i++) {
temp = new Surface({
size: [undefined, 80],
content: 'Surface: ' + (i + 1),
properties: {
textAlign: 'left',
lineHeight: '80px',
borderTop: '1px solid #000',
borderBottom: '1px solid #fff',
backgroundColor: '#ffff00',
fontFamily: 'Arial',
backfaceVisibility: 'visible',
paddingLeft: '10px'
}
});
temp.pipe(this.scrollview);
surfaces.push(temp);
}
this.scrollview.sequenceFrom(surfaces);
this.bodyContent = new Surface({
size: [undefined, undefined],
properties: {
backgroundColor: '#f4f4f4'
}
});
this.layout.content.add(this.bodyContent);
}
function _setListeners() {
this.hamburgerSurface.on('click', function() {
this._eventOutput.emit('menuToggle');
}.bind(this));
//this.bodyContent.pipe(this._eventOutput);
this.scrollview.pipe(this._eventOutput);
}
module.exports = PageView;
});
You need to add this.scrollview to your layout.content element on the page. Put this in place of this.bodyContent. layout.content is the node for the content of the page.
//this.layout.content.add(this.bodyContent);
this.layout.content.add(this.scrollview);
When I set the balls origin to [0.5,0.5] the walls are placed correctly, when i set its transform or origin to any other location the walls move as well?
I have tried to explicitly set the engines origin but that doesn't work either
this code is copy paste able into main.js in the famous starter kit
define(function(require, exports, module) {
var Engine = require('famous/core/Engine');
var Surface = require('famous/core/Surface');
var EventHandler = require('famous/core/EventHandler');
var View = require('famous/core/View');
var Transform = require('famous/core/Transform');
var $ = require('jquery');
var StateModifier = require('famous/modifiers/StateModifier');
var Modifier = require('famous/core/Modifier');
var PhysicsEngine = require('famous/physics/PhysicsEngine');
var Body = require('famous/physics/bodies/Body');
var Circle = require('famous/physics/bodies/Circle');
var Wall = require('famous/physics/constraints/Wall');
var Vector = require('famous/math/Vector');
var context = Engine.createContext();
var handler = new EventHandler();
//{origin:[0.5,0.5]}
var physicsEngine = new PhysicsEngine();
$('#game').on('click', function(event) {
console.log('x '+event.clientX);
console.log('y '+event.clientY)
createBall(event.clientX, event.clientY);
})
var leftWall = new Wall({
normal: [1, 0, 0],
distance: window.innerWidth / 2.0,
restitution: 0.5
});
var rightWall = new Wall({
normal: [-1, 0, 0],
distance: window.innerWidth / 2.0,
restitution: 0.5
});
var topWall = new Wall({
normal: [0, 1, 0],
distance: window.innerHeight / 2.0,
restitution: 0.5
});
console.log(window.innerHeight )
console.log(window.innerWidth )
var bottomWall = new Wall({
normal: [0, -1, 0],
distance: window.innerHeight / 2.0,
restitution: 0.5
});
leftWall = physicsEngine.attach(leftWall,[]);
rightWall = physicsEngine.attach(rightWall,[]);
topWall = physicsEngine.attach(topWall,[]);
bottomWall = physicsEngine.attach(bottomWall,[]);
var balls = []
function createBall(x, y) {
var ball = new Surface({
size: [100, 100],
properties: {
backgroundColor: 'red',
borderRadius: '100px'
}
})
ball.state = new StateModifier({
// transform: Transform.translate(x, y, 0)
});
ball.particle = new Circle({
radius: 50,
position : new Vector(x, y, 0)
});
physicsEngine.addBody(ball.particle);
ball.on("click", function() {
console.log('clicked ball')
ball.particle.setVelocity([1, 1, 0]);
});
context.add(ball.state).add(ball)
Engine.on('prerender', function() {
ball.state.setTransform(ball.particle.getTransform())
});
// balls.push(ball.particle);
//bottomWall = physicsEngine.attach(ball.particle,balls);
physicsEngine.attachTo(leftWall,ball.particle);
physicsEngine.attachTo(rightWall,ball.particle);
physicsEngine.attachTo(topWall,ball.particle);
physicsEngine.attachTo(bottomWall,ball.particle);
}
});
The physics collision and adding of particles is driven by the origin of the physics engine in famo.us, so you would want to set the origin of the physics engine to your render node.
As you can see from the code below or the following link:
jsFiddle Link
The placement of the walls are driven by the origin of the physics engine when they are attached. The particles you attach to the walls are bound by the origin of the physics engine also, so changing their origin is going to have an effect on their collision to the walls.
The example code does not attach a modifier to the circles, but adds them to the particles. I am not sure if you were trying to do something different, but hopefully this answers your question.
define('main', function (require, exports, module) {
var Engine = require('famous/core/Engine');
var Surface = require('famous/core/Surface');
var RenderNode = require('famous/core/RenderNode');
var EventHandler = require('famous/core/EventHandler');
var View = require('famous/core/View');
var Transform = require('famous/core/Transform');
//var $ = require('jquery');
var StateModifier = require('famous/modifiers/StateModifier');
var Modifier = require('famous/core/Modifier');
var PhysicsEngine = require('famous/physics/PhysicsEngine');
var Body = require('famous/physics/bodies/Body');
var Circle = require('famous/physics/bodies/Circle');
var Wall = require('famous/physics/constraints/Wall');
var Vector = require('famous/math/Vector');
var context = Engine.createContext();
var node = new RenderNode();
var physicsOrigin = [0.5, 0.5];
var radius = 50;
context.add(new Modifier({
origin: physicsOrigin
})).add(node);
var handler = new EventHandler();
var physicsEngine = new PhysicsEngine();
node.add(physicsEngine);
console.log(window.innerHeight);
console.log(window.innerWidth);
var dimX = window.innerWidth;
var dimY = window.innerHeight;
Engine.on('click', function (event) {
console.log('x ' + event.clientX);
console.log('y ' + event.clientY)
var x = event.clientX - (dimX * physicsOrigin[0]);
var y = event.clientY - (dimY * physicsOrigin[1]);
createBall(x, y);
});
var leftWall = new Wall({
normal: [1, 0, 0],
distance: Math.round(dimX / 2.0),
restitution: 0.5
});
var rightWall = new Wall({
normal: [-1, 0, 0],
distance: Math.round(dimX / 2.0),
restitution: 0.5
});
var topWall = new Wall({
normal: [0, 1, 0],
distance: Math.round(dimY / 2.0),
restitution: 0.5
});
var bottomWall = new Wall({
normal: [0, -1, 0],
distance: Math.round(dimY / 2.0),
restitution: 0.5
});
var balls = [];
physicsEngine.attach([leftWall, rightWall, topWall, bottomWall], balls);
function createBall(x, y) {
var ball = new Surface({
size: [radius * 2, radius * 2],
properties: {
backgroundColor: 'blue',
borderRadius: (radius * 2) + 'px'
}
})
ball.particle = new Circle({
radius: radius,
position: [x, y, 0]
});
physicsEngine.addBody(ball.particle);
node.add(ball.particle).add(ball)
ball.on("click", function () {
console.log('clicked ball')
ball.setOptions({properties: {backgroundColor: 'red'}});
ball.particle.setVelocity([1, 1, 0]);
});
balls.push(ball.particle);
}
});
If I have a surface that hase conent that includes an input. The input doesn't seem to gain focus on click.
Here is how I include my surface.
var ConfigureView = function() {
this.initialize.apply(this, arguments);
};
_.extend(ConfigureView.prototype, {
template: templates['config'],
initialize: function( options ) {
var position = new Transitionable([0, 0]);]
var sync = new GenericSync({
"mouse" : {},
"touch" : {}
});
this.surface = new Surface({
size : [200, 200],
properties : {background : 'red'},
content: this.template()
});
// now surface's events are piped to `MouseSync`, `TouchSync` and `ScrollSync`
this.surface.pipe(sync);
sync.on('update', function(data){
var currentPosition = position.get();
position.set([
currentPosition[0] + data.delta[0],
currentPosition[1] + data.delta[1]
]);
});
this.positionModifier = new Modifier({
transform : function(){
var currentPosition = position.get();
return Transform.translate(currentPosition[0], currentPosition[1], 0);
}
});
var centerModifier = new Modifier({origin : [0.5, 0.5]});
centerModifier.setTransform(Transform.translate(0,0));
},
addTo: function(context) {
context = Engine.createContext()
context.add(this.positionModifier).add(this.surface);
}
});
module.exports = ConfigureView;
What is necessary to make forms act normally with famo.us?
Or do i just need to have an inner surface that has a different listener?
This is templates['config']:
templates["config"] = Handlebars.template({"compiler":[5,">= 2.0.0"],"main":function(depth0,helpers,partials,data) {
return "<input type=\"text\" id=\"fontSize\" >";
},"useData":true});
What displays is an input I just can't seem to focus on it.
UPDATE
The reason I think I couldn't focus was because I wasn't using an inputSurface and the surface event was being pipe away. Using a scrollView I was able to make it work.
var ConfigureView = function() {
this.initialize.apply(this, arguments);
};
_.extend(ConfigureView.prototype, {
template: templates['config'],
initialize: function( options ) {
this.app = options.app;
var position = new Transitionable([0, 0, 1000]);
this.scrollView = new ScrollView();
var surfaces = [];
this.scrollView.sequenceFrom(surfaces);
// create a sync from the registered SYNC_IDs
// here we define default options for `mouse` and `touch` while
// scrolling sensitivity is scaled down
var sync = new GenericSync({
"mouse" : {},
"touch" : {}
});
this.surface = new Surface({
size : [200, 200],
properties : {background : 'red'},
content: this.template()
});
surfaces.push(this.surface);
this.offsetMod = new Modifier({ origin: [0.2,0,2]});
this.inner = new Surface({
size : [100, 100],
properties : {background : 'gray'},
content: this.template()
});
surfaces.push(this.inner);
// now surface's events are piped to `MouseSync`, `TouchSync` and `ScrollSync`
this.surface.pipe(sync);
this.inputsFontSize = new InputSurface({
classes: ['login-form'],
content: '',
size: [300, 40],
placeholder:'email',
properties: {
autofocus:'autofocus',
maxLength:'5',
textAlign: 'left'
}
});
sync.on('update', function(data){
var currentPosition = position.get();
position.set([
currentPosition[0] + data.delta[0],
currentPosition[1] + data.delta[1]
]);
});
this.positionModifier = new Modifier({
transform : function(){
var currentPosition = position.get();
return Transform.translate(currentPosition[0], currentPosition[1], 0);
}
});
var centerModifier = new Modifier({origin : [0.5, 0.5]});
centerModifier.setTransform(Transform.translate(0,0));//, y, z))
},
addTo: function(context) {
context = Engine.createContext();
context.add(this.positionModifier).add(this.scrollView);
}
});
module.exports = ConfigureView;
I have a raphael circle and I want to attach a mouse event that launches a function. The function is called PlayAudioFile() and is inaccessible to the Raphael.js code block. I don't know how to modify the code below to make it's scope available.
window.onload = function () {
var R = Raphael(0, 0, "200px", "200px"),
r = R.circle(100, 100, 50).attr({fill: "hsb(0, 1, 1)", stroke: "none", opacity: .5}).click(function(){
alert("Wish I was an audio file being triggered instead"); // this needs to launch the playAudioFile() function. That function is not accessible however. So how do I modify playAudioFile()'s scope so that it is?
});
var start = function () {
this.ox = this.attr("cx");
this.oy = this.attr("cy");
this.animate({r: 70, opacity: .25}, 500, ">");
},
move = function (dx, dy) {
this.attr({cx: this.ox + dx, cy: this.oy + dy});
},
up = function () {
this.animate({r: 50, opacity: .5}, 500, ">");
};
R.set(r).drag(move, start, up);
};
var context = new webkitAudioContext(),
savedBuffer;
var nameOfAudioFile = new XMLHttpRequest();
nameOfAudioFile.open('GET', 'A.mp3', true);
nameOfAudioFile.responseType = 'arraybuffer';
nameOfAudioFile.onload = function () {
context.decodeAudioData(nameOfAudioFile.response,
function(incomingBuffer) {
//save the buffer, we'll reuse it
savedBuffer = incomingBuffer;
//once the file has been loaded, we can start listening for click on the div, and use playAudioFile since it no longer requires a buffer to be passed to it
var myDiv= document.getElementById("myDiv");
myDiv.addEventListener("click", playAudioFile , false);
}
);
playAudioFile = function () {
var source = context.createBufferSource();
source.buffer = savedBuffer;
source.connect(context.destination);
source.noteOn(0); // Play sound immediately
};
};
nameOfAudioFile.send();
</script>
<div id="myDiv">This div triggers playAudioFile() when clicked. Good!</div>
<style>
#myDiv {
position:relative;
left:150px;
top:240px;
background-color: green;
width:160px;
height:100px;
}
</style>
Try moving the playAudioFile function outside the onload-listener of nameOfAudioFile. Also, you could wrap the whole thing within the window.onload function to keep it all within that scope.
window.onload = function() {
var context = new webkitAudioContext(),
savedBuffer,
playAudioFile = function() {
var source = context.createBufferSource();
source.buffer = savedBuffer;
source.connect(context.destination);
source.noteOn(0); // Play sound immediately
};
var nameOfAudioFile = new XMLHttpRequest();
nameOfAudioFile.open('GET', 'A.mp3', true);
nameOfAudioFile.responseType = 'arraybuffer';
nameOfAudioFile.onload = function() {
context.decodeAudioData(nameOfAudioFile.response, function(incomingBuffer) {
savedBuffer = incomingBuffer;
var myDiv = document.getElementById("myDiv");
myDiv.addEventListener("click", playAudioFile, false);
//at this point we know that the buffer has loaded and it should be safe to draw the button
var R = Raphael(0, 0, "200px", "200px"),
r = R.circle(100, 100, 50).attr({
fill: "hsb(0, 1, 1)",
stroke: "none",
opacity: .5
}).click(function() {
playAudioFile();
});
var start = function() {
this.ox = this.attr("cx");
this.oy = this.attr("cy");
this.animate({
r: 70,
opacity: .25
}, 500, ">");
},
move = function(dx, dy) {
this.attr({
cx: this.ox + dx,
cy: this.oy + dy
});
},
up = function() {
this.animate({
r: 50,
opacity: .5
}, 500, ">");
};
R.set(r).drag(move, start, up);
});
};
nameOfAudioFile.send();
};