RaphaelJs - Issues with Hovering due to Object - object

Cheers,
for my website I try to spice my CV a little up.
If you hover about an Icon on canvas_2, which I created as an Object, a static shape + dynamic message will appear on canvas_3 (canvas_1 is solely for navigation, which does not matter at this point). However if I hover over the first Object, the second Object, not the first, fires its animation and displays the description.
I set up a fiddle, maybe this will clear things up better than my english.
http://jsfiddle.net/J6h7e/4/
function Achievement(set, rect, circ, symb, label, text, icon)
{
var ach = this;
ach.set = set;
ach.rect = rect;
ach.circ = circ;
ach.symb = symb;
ach.lab = label;
ach.desText = text;
ach.desIcon = icon;
ach.builder = function()
{
ach.cir = canvas_2.path(circ);
ach.sym = canvas_2.path(symb);
ach.set.push(ach.rect, ach.sym, ach.cir);
ach.set.attr({"stroke":"none", "fill":"rgb(238, 238, 238)"});
ach.rect.attr({"opacity":0});
}
ach.hoverSetup = function()
{
ach.set.mouseover(
function(){
ach.set.forEach(function(el){el.animate(el.transform("s1.25"), "bounce")});
achTemplate.attr({"opacity":1});
ach.description.attr({"opacity":1});
}
);
ach.set.mouseout(
function(){ach.set.forEach(function(el){el.animate(el.transform("s1"), "elastic")});
achTemplate.attr({"opacity":0});
ach.description.attr({"opacity":0});
}
)
}
ach.descriptor = function()
{
canvas_3.setStart();
ach.des = canvas_3.text(320, 60, ach.desText);
ach.ico = canvas_3.path(ach.desIcon).attr({"stroke":"none"});
ach.description = canvas_3.setFinish();
ach.description.attr({"font-family":"cabinregular", "font-size":"14px", "fill":"rgb(25,106,141)", "text-anchor":"start", "opacity":0});
}
console.log(ach.set);
return ach;
}
/*Static Content*/
var title = canvas_2.text(200, 20, 'Achievements');
title.attr({"font-family": 'franchiseregular',"font-size": '24','stroke-width': '0','stroke-opacity': '1','fill': 'rgb(238,238,238)'});
var achTemplate = canvas_3.set();
var templ = canvas_3.path("M635.5,57c0,27.615-18.851,50-42.105,50H277.605c-23.253,0-42.105-22.385-42.105-50l0,0 c0-27.613,18.853-50,42.105-50h315.789C616.649,7,635.5,29.387,635.5,57L635.5,57z");templ.attr({"stroke":"none", "fill":"rgb(238,238,238)"});
var templHe = canvas_3.text(410, 20, "Achievement Unlocked");
templHe.attr({"font-family":"cabinsemibold", "font-size":"18px", "fill":"rgb(25, 106, 141)", "font-weight":"bold" });
var tempCir = canvas_3.path("M260.75,55.884c0-0.714,0.04-1.417,0.117-2.111l-10.838-3.522c-0.346,1.824-0.529,3.707-0.529,5.633 c0,8.626,3.644,16.404,9.472,21.875l6.696-9.217C262.614,65.206,260.75,60.762,260.75,55.884z M298.25,55.884 c0,4.877-1.863,9.322-4.918,12.658l6.695,9.217c5.828-5.471,9.473-13.248,9.473-21.875c0-1.926-0.184-3.809-0.531-5.632 l-10.84,3.521C298.21,54.466,298.25,55.169,298.25,55.884z M283.25,37.509c5.387,1.093,9.934,4.495,12.566,9.131l10.84-3.521 c-4.29-9.107-13.024-15.706-23.406-17.003V37.509z M263.184,46.642c2.631-4.634,7.18-8.037,12.566-9.131V26.117 c-10.382,1.297-19.116,7.896-23.404,17.004L263.184,46.642z M287.266,72.954c-2.365,1.078-4.992,1.68-7.766,1.68 c-2.773,0-5.4-0.602-7.766-1.68l-6.698,9.217c4.29,2.365,9.219,3.713,14.463,3.713s10.174-1.348,14.464-3.713L287.266,72.954z");
tempCir.attr({"stroke":"none", "fill":"rgb(25, 106, 141)"});
achTemplate.push(templ, templHe, tempCir);
achTemplate.attr({"opacity":0});
var tooltip = canvas_3.path("M34.308,44c-3.472,0-6.737,1.352-9.192,3.808c-2.456,2.455-3.808,5.721-3.808,9.192s1.352,6.737,3.808,9.192 C27.57,68.648,30.836,70,34.308,70s6.737-1.352,9.192-3.808c2.456-2.455,3.808-5.721,3.808-9.192s-1.352-6.737-3.808-9.192 C41.045,45.352,37.779,44,34.308,44z M34.308,41L34.308,41c8.837,0,16,7.163,16,16s-7.163,16-16,16s-16-7.163-16-16 S25.471,41,34.308,41z M32.308,63h4v4h-4V63z M32.308,47h4v12h-4V47z");
tooltip.attr({"stroke":"none", "fill":"rgb(238, 238, 238)", "title":"Hover over the Symbols to get more Information"});
/*Berlin Achievement */
var ber = canvas_2.set();
var selBe = canvas_2.rect(89.466, 109, 60.001, 60);
var berlin = Achievement
(
ber,
selBe,
"M100.92,138.885c0-0.714,0.039-1.417,0.117-2.111L90.2,133.251c-0.347,1.824-0.529,3.707-0.529,5.633 c0,8.626,3.644,16.404,9.472,21.875l6.696-9.217C102.784,148.207,100.92,143.763,100.92,138.885z M138.42,138.885 c0,4.877-1.863,9.322-4.918,12.658l6.695,9.217c5.828-5.471,9.473-13.248,9.473-21.875c0-1.926-0.184-3.809-0.531-5.632 l-10.84,3.521C138.381,137.467,138.42,138.169,138.42,138.885z M123.42,120.51c5.387,1.093,9.934,4.495,12.566,9.131l10.84-3.521 c-4.289-9.107-13.023-15.706-23.406-17.003V120.51z M103.354,129.642c2.631-4.634,7.18-8.037,12.566-9.131v-11.395 c-10.383,1.297-19.116,7.896-23.404,17.004L103.354,129.642z M127.436,155.955c-2.365,1.078-4.992,1.68-7.766,1.68 s-5.4-0.602-7.766-1.68l-6.699,9.217c4.291,2.365,9.22,3.713,14.463,3.713c5.246,0,10.176-1.348,14.465-3.713L127.436,155.955z",
"M119.67,126.938c-4.143,0-7.5,3.357-7.5,7.5c0,7.5,7.5,16.5,7.5,16.5s7.5-9,7.5-16.5 C127.17,130.295,123.813,126.938,119.67,126.938z M119.67,139.033c-2.537,0-4.594-2.057-4.594-4.594s2.057-4.594,4.594-4.594 s4.594,2.057,4.594,4.594S122.208,139.033,119.67,139.033z M116.765,134.438c0,1.605,1.301,2.906,2.906,2.906 c1.604,0,2.905-1.301,2.905-2.906s-1.301-2.906-2.905-2.906C118.065,131.533,116.765,132.833,116.765,134.438z",
"The Passenger",
"250G - The Passenger \n Moved to Berlin \n Unlocked on 09/08/2004",
"M279.764,44.938c-4.143,0-7.5,3.357-7.5,7.5c0,7.5,7.5,16.5,7.5,16.5s7.5-9,7.5-16.5 C287.264,48.295,283.906,44.938,279.764,44.938z M279.764,57.031c-2.537,0-4.594-2.056-4.594-4.593s2.057-4.594,4.594-4.594 s4.594,2.057,4.594,4.594S282.301,57.031,279.764,57.031z M276.858,52.438c0,1.605,1.301,2.906,2.906,2.906 c1.605,0,2.906-1.301,2.906-2.906s-1.301-2.906-2.906-2.906C278.159,49.532,276.858,50.833,276.858,52.438z"
);
berlin.builder();
berlin.hoverSetup();
berlin.descriptor();
/*Python Achievement */
var py = canvas_2.set();
var selPy = canvas_2.rect(89.795, 362.5, 60, 60);
var python = Achievement
(
py,
selPy,
"M101.045,392.384c0-0.713,0.04-1.416,0.117-2.109l-10.839-3.521c-0.347,1.824-0.528,3.707-0.528,5.633 c0,8.627,3.645,16.405,9.473,21.876l6.695-9.217C102.91,401.706,101.045,397.262,101.045,392.384z M138.545,392.384 c0,4.878-1.863,9.322-4.918,12.659l6.695,9.217c5.828-5.471,9.473-13.249,9.473-21.876c0-1.926-0.184-3.809-0.531-5.631 l-10.84,3.521C138.506,390.966,138.545,391.669,138.545,392.384z M123.545,374.009c5.387,1.094,9.934,4.496,12.566,9.132 l10.84-3.521c-4.289-9.107-13.023-15.707-23.406-17.004V374.009z M103.48,383.142c2.631-4.635,7.18-8.037,12.564-9.131v-11.395 c-10.382,1.297-19.115,7.896-23.402,17.004L103.48,383.142z M127.561,409.455c-2.363,1.078-4.99,1.68-7.766,1.68 c-2.771,0-5.398-0.602-7.767-1.68l-6.697,9.217c4.29,2.365,9.22,3.713,14.463,3.713c5.245,0,10.175-1.348,14.464-3.713 L127.561,409.455z",
"M127.295,390.938h-1.5v-4.5c0-3.313-2.688-6-6-6s-6,2.688-6,6v4.5h-1.5c-0.824,0-1.5,0.678-1.5,1.5v10.5 c0,0.825,0.676,1.501,1.5,1.501h15c0.824,0,1.5-0.676,1.5-1.501v-10.5C128.795,391.614,128.119,390.938,127.295,390.938z M119.795,399.938c-0.828,0-1.5-0.671-1.5-1.5c0-0.828,0.672-1.5,1.5-1.5c0.83,0,1.5,0.672,1.5,1.5 C121.295,399.268,120.625,399.938,119.795,399.938z M122.795,390.938h-6v-4.5c0-1.652,1.348-3,3-3c1.654,0,3,1.348,3,3V390.938z",
"Rattlesnake",
"250G - Rattlesnake \n Mastering Python \n Not yet Unlocked",
"M287.264,54.5h-1.5V50c0-3.313-2.688-6-6-6c-3.313,0-6,2.687-6,6v4.5h-1.5c-0.824,0-1.5,0.676-1.5,1.5v10.5 c0,0.824,0.676,1.5,1.5,1.5h15c0.824,0,1.5-0.676,1.5-1.5V56C288.764,55.176,288.088,54.5,287.264,54.5z M279.764,63.5 c-0.829,0-1.5-0.671-1.5-1.5s0.671-1.5,1.5-1.5s1.5,0.671,1.5,1.5S280.593,63.5,279.764,63.5z M282.764,54.5h-6V50 c0-1.654,1.346-3,3-3c1.654,0,3,1.346,3,3V54.5z"
);
python.builder();
python.hoverSetup();
python.descriptor();
}

You have missed the new keyword when creating new instance of the Achievement object.
like:
var berlin = new Achievement();
var python = new Achievement();
http://jsfiddle.net/J6h7e/5/
BTW: Nice animation :)

Related

How to center continued text using PdfKit?

I have this code:
const PDFDocument = require("pdfkit");
const QRCode = require("qrcode");
const fs = require("fs");
const exec = async () => {
const doc = new PDFDocument({ layout: "landscape" });
doc.pipe(fs.createWriteStream("output.pdf"));
for (let pageNumber = 1; pageNumber <= 1000; pageNumber++) {
const url = await QRCode.toDataURL("I am a url!");
doc
.image(url, 10, 100, {
width: 420,
height: 420,
align: "center",
valign: "center",
})
doc
.font("Helvetica")
.fontSize(50)
.fillColor("#000")
.text(`Item `, 465, 200, { continued: true })
.fontSize(55)
.font("Courier-Bold")
.fillColor("#1b83c5")
.text(`${pageNumber}`);
doc
.font("Helvetica-Bold")
.fontSize(40)
.fillColor("#000")
.text("Order and Pay", 420, 320);
doc.addPage();
}
doc.end();
};
exec();
Which would produce something like this:
It looks centered and all, but as pages increase it will no longer be centered since the numbers are fixed.
I saw in the docs that there's an align property, but the docs didn't explain how to handle continued text.
Any working examples?
Maybe it's a little late, but I found a solution battling with the same problem:
First you need to create a constant with the width of the container you want to center your text in: (this value you have to calculate or invent, but it's easy to do that)
const containerWidth = 100 // as an example
Then, you need to create a variable that contains a plain string that contains all the text you want to center, in your example:
var appendedText = `Item ${pageNumber}`
To finish, you need to use pdf-kit's function: widthOfString, and add the text in the document as follows:
const xOffset = 465 // The original X offset value
doc
.text(`Item `, xOffset + (containerWidth / 2) - (doc.widthOfString(appendedText) / 2), 200, { continued: true })
.text(`${pageNumber}`);
Removed the text styling lines for clarity, but you have to add them later.

Pixi.js v5 - apply alpha to displacement map

I'm scaling a displacement map on click but would like that map to fade away once it reaches almost full scale. The idea is that the filter should be non-existent after a couple of seconds.
const app = new PIXI.Application({
view: document.querySelector("#canvas"),
width: 512,
height: 512
});
const logo = PIXI.Sprite.fromImage("https://unsplash.it/600");
const displacement = PIXI.Sprite.fromImage("https://images.unsplash.com/photo-1541701494587-cb58502866ab?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&w=1000&q=80");
const filter = new PIXI.filters.DisplacementFilter(displacement);
logo.anchor.set(0.5);
logo.position.set(256);
logo.interactive = true;
displacement.anchor.set(0.5);
displacement.position.set(256);
displacement.scale.set(0.05)
displacement.alpha = 1
app.stage.filterArea = app.screen;
app.stage.filters = [filter];
app.stage.addChild(logo, displacement);
app.ticker.add(function() {
displacement.scale.x += 0.05
displacement.scale.y += 0.05
if (displacement.scale.x > 10) app.ticker.stop()
});
logo.on('mousedown', function() {
displacement.scale.set(0.05)
app.ticker.start()
});
Here's what I have so far:
https://codepen.io/mariojankovic/pen/pojjNae?editors=0111
I've only just started looking at Pixi but I think you want to use the scale property of the displacement filter. This value says how far to shift. Reducing this value to 0 will lessen its effect to none.
https://pixijs.download/dev/docs/PIXI.filters.DisplacementFilter.html
https://pixijs.download/dev/docs/PIXI.filters.DisplacementFilter.html#scale
The way it works is it uses the values of the displacement map to look
up the correct pixels to output. This means it's not technically
moving the original. Instead, it's starting at the output and asking
"which pixel from the original goes here". For example, if a
displacement map pixel has red = 1 and the filter scale is 20, this
filter will output the pixel approximately 20 pixels to the right of
the original.
https://codepen.io/PAEz/pen/BaoREwv
const app = new PIXI.Application({
view: document.querySelector("#canvas"),
width: 512,
height: 512
});
const logo = PIXI.Sprite.fromImage("https://unsplash.it/600");
const displacement = PIXI.Sprite.fromImage(
"https://images.unsplash.com/photo-1541701494587-cb58502866ab?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&w=1000&q=80"
);
const filter = new PIXI.filters.DisplacementFilter(displacement);
logo.anchor.set(0.5);
logo.position.set(256);
logo.interactive = true;
displacement.anchor.set(0.5);
displacement.position.set(256);
displacement.scale.set(0.0);
displacement.alpha = 1;
app.stage.filterArea = app.screen;
app.stage.filters = [filter];
app.stage.addChild(logo, displacement);
const displacementScaleFrom = 0.05;
const displacementScaleTo = 10 ;
const displacementStep = 0.05;
const filterScaleFrom = 20;// the default value for the filter is 20
const filterStep = filterScaleFrom / ((displacementScaleTo-displacementScaleFrom) / displacementStep);
app.ticker.add(function () {
displacement.scale.x += displacementStep;
displacement.scale.y += displacementStep;
filter.scale.x -= filterStep;
filter.scale.y -= filterStep;
if (displacement.scale.x >= displacementScaleTo) {
app.ticker.stop();
filter.scale.x = 0;
filter.scale.y = 0;
}
});
logo.on("mousedown", function () {
displacement.scale.set(displacementScaleFrom);
filter.scale.x = filterScaleFrom;
filter.scale.y = filterScaleFrom;
app.ticker.start();
});

Loading a collada file with Vertex Colors using three.js

I'm trying to load a dae file using three.js, but I can't get the material to show. I can't find any examples that use a dae file to load vertex colors that are in the file itself. I can get it to load at threejs.org/editor by setting the material to MeshBasicMaterial and the property Vertex Colors to Vertex Colors. I tried to replicate that in code but I don't think I quite understand how. Here is my loader function...
loader.load( 'objects/chair.dae', function ( collada ) {
//dummy1.dae
var dae = collada.scene;
var skin = collada.skins[ 0 ];
console.log(collada.scene);
//collada.dae.materials[0] = collada.scene.children[0].children[0].material;
//dae.material = collada.scene.children[0].children[0].material;
//var material = collada.scene.children[0].children[0].material;
var material = new THREE.MeshBasicMaterial({
vertexColors: THREE.VertexColors
});
collada.scene.position.set(0,0,0);//x,z,y- if you think in blender dimensions ;)
collada.scene.scale.set(15.0, 15.0, 15.0);
var mesh = new THREE.Mesh(collada, material);
scene.add(mesh);
//scene.add(collada.scene);
var axes = new THREE.AxisHelper(50);
axes.position = dae.position;
scene.add(axes);
var gridXZ = new THREE.GridHelper(100, 10);
gridXZ.setColors( new THREE.Color(0x8f8f8f), new THREE.Color(0x8f8f8f) );
gridXZ.position.set(0,0,0 );
scene.add(gridXZ);
});
This is producing an error.
As for the code, basically you have to change the material of the mesh in the Collada object. Something like:
loader.load(
// resource URL
'models/example.dae',
// Function when resource is loaded
function ( collada ) {
var dae = collada.scene;
// CORRECT FOR IMPORTER
// collada object with only vertex color are not correctly loaded
dae.traverse( function(child) {
if (child instanceof THREE.Mesh) {
child.material = new THREE.MeshBasicMaterial( { vertexColors: true } );
}
});
dae.position.set(0,0,0);
dae.scale.set(10, 10, 10);
scene.add(dae);
animate();
},
// Function called when download progresses
function ( xhr ) {
console.log( (xhr.loaded / xhr.total * 100) + '% loaded' );
}
);

how to use fabricjs for synchronizing data between a and b client browers

how can use fabricjs to sync pencilbrush data between a client and b client.
now i can use socket.io do that common shaps but pencilbrush can't do
my example code
client a --send
canvas.on('object:modified', function(options){
console.info("object modified",options)
socket.emit('js_object_redraw', {id:data.target.id,object:data.target});
},false);
client b --recieve
socket.on('client_js_object_redraw', function (data) {
console.info("client_js_object_redraw:",data)
console.info("data.target.type",data.object.type)
var ele = canvas.getObjects()
for (var i=0;i<ele.length;i++) {
var cur_object = ele[i]
if (data.id == cur_object.id){
canvas.remove(cur_object);
draw_object_by_type(data)
}
}
});
function draw_object_by_type(data){
if(data.object.type=="rect"){
draw_rect(data);
}else if(data.object.type=="line"){
draw_line(data);
} else if(data.object.type=="triangle"){
draw_triangle(data);
}
......
}
function draw_rect(data){
var id = data.id;
var object = data.object
var rect = new fabric.Rect({
id:id,
left : object.left,
top :object.top,
width : 60,
height : 70,
scaleX: object.scaleX,
scaleY: object.scaleY,
angle: object.angle,
fill : object.fill
});
canvas.add(rect);
return rect;
}
nodejs server:
socket.on('js_object_redraw', function (data) {
socket.broadcast.emit('client_js_object_redraw',data)
});
=================================================================
pencilBrush
I can do it syc data
like :
when i draw line i emit event to b
but i can't earse the line.
when i clear line
like:
var ctx = canvas.getContext();
ctx.clearRect(x, y, 50, 50);
the next draw sharp ,the have remove line will show the canvas
how can i do that ,sync data between a and b client and can remove the sharp.
thanks,very much
RacerJs is good option for Synchronize data between multiple clients here is complete example https://github.com/codeparty/racer

Titanium: Error trying to play a sound when tapping a row in a table?

I'm making a rather simple app that displays a table where each row contains an English word and the corresponding Polish word. When a row is pressed it should play a sound clip of the word expressed. However, I cannot make it work, even though I've tried to troubleshoot it with all that Google has to offer. Would appreciate if someone could point out the flaw...
var win = Titanium.UI.currentWindow;
var data =[];
var CustomData = [
{ file:'001', english:'Do you?', polish:'Czy masz?', fav:false },
{ file:'002', english:'How long?', polish:'Jak d?ugo?', fav:false },
{ file:'003', english:'Is it?', polish:'Czy?', fav:false },
];
var section = Ti.UI.createTableViewSection();
data.push(section);
for (var i=0; i<CustomData.length; i++) {
var row = Ti.UI.createTableViewRow({layout : 'vertical', height:'auto'});
var item = Ti.UI.createLabel({
color:'#000',
text:CustomData[i].english,
font:{fontSize:12, fontWeight:'bold'},
top:3,
left:10,
right:30,
height:'auto'
});
row.add(item);
var cost = Ti.UI.createLabel({
color:'#444',
text:CustomData[i].polish,
font:{fontSize:12},
top:0,
left:15,
right:30,
bottom:5,
height:'auto'
});
row.add(cost);
row.filter = CustomData[i].english;
section.add(row);
};
var tableview = Titanium.UI.createTableView({
data:data, search:search, searchHidden:false, filterAttribute: 'filter' });
win.add(tableview);
tableview.addEventListener('click', function(e)
{
var sound = Titanium.Media.createSound();
sound.url = '../sound/' + e.rowData.file + '.mp3';
sound.play();
if (e.rowData.test)
{
var win = Titanium.UI.createWindow({
url:e.rowData.test,
title:e.rowData.title
});
Titanium.UI.currentTab.open(win,{animated:true});
}
});
Just a shot in the dark, but are you sure you can set the URL after the sound object is created? Have you tried:
Titanium.Media.createSound({url:'../sound/' + e.rowData.file + '.mp3'});
Aside from that, are you sure the relative URL is evaluated from where you think? Maybe try it with an absolute URL just to be sure.

Resources