Three.js touch intersects on mobile - mobile

I'e seen this problem mentioned here, however this solution (e.touches[0].pageX and e.touches[0].pageY (instead of e.clientX and e.clientY) isn't working for me.
The hotspots are being selected if you touch them about 10 times, and luckily hit the magic spot, or sometimes if you hit somewhere randomly nearby they're hit, otherwise nothing.
My code:
mouse.x = ( event.touches[0].pageX / window.innerWidth ) ;
mouse.y = - ( event.touches[0].pageX / window.innerHeight );
// This is the mouse clicks that do work
//mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
//mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
var vector = new THREE.Vector3( mouse.x, mouse.y, 1 );
projector.unprojectVector( vector, camera );
var ray = new THREE.Raycaster( camera.position, vector.sub( camera.position ).normalize() );
var intersects = ray.intersectObjects( targetList, true );
if ( intersects.length > 0)
hotspotClick(intersects[ 0 ].object);
EDIT
I'm making a bit of progress with this
mouse.x = ( event.touches[0].pageX / window.innerWidth ) * 0.1;
mouse.y = ( event.touches[0].pageY / window.innerHeight ) * 0.1;
However it seems to either be clicking anywhere near the mesh activates it, or you have to press in a certain spot somewhere in the middle of it. So I assume that multiplier is out.
X seems to be OK, Y seems to be the problem.
Can anyone help?

I have tested it on an iPad with both Chrome and Safari and on Android with Chrome.
document.body.appendChild(renderer.domElement);
document.addEventListener('touchend', onDocumentTouchEnd, false);
function onDocumentTouchEnd(event) {
event.preventDefault();
mouse.x = (event.changedTouches[0].clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.changedTouches[0].clientY / window.innerHeight) * 2 + 1;
raycaster.setFromCamera(mouse, camera);
const intersects = raycaster.intersectObjects(yourObject3D);
}
It started to work well after appending renderer.domElement.
Before I was using event.Touches with mixed results.

This worked
mouse.x = +(event.targetTouches[0].pageX / window.innerWidth) * 2 +-1;
mouse.y = -(event.targetTouches[0].pageY / window.innerHeight) * 2 +
1;
window.innerwidth has to be window.innerWidth!

Use below code to get correct intersects
event.preventDefault();
var rect = Canvas_Instance.getBoundingClientRect();
mouse.x = + ( (event.targetTouches[ 0 ].pageX - rect.left) / rect.width ) * 2 - 1;
mouse.y = - ( (event.targetTouches[ 0 ].pageY - rect.top) / rect.height ) * 2 + 1;

Related

Inviter of undefined

It says no inviter as an error, and when I can't find the inviter, I want it to send a message saying he logged in with the Url or unknown. What should I do?Normal users do not have a problem when they come with an invitation, but they give such an error when they log in with the Url.
Error: (node:244) UnhandledPromiseRejectionWarning: TypeError: Cannot
read property 'in viter' of undefined
at C:\Users\Administrator\Desktop\1951 Moderation + Registrar + Stats\bot.js :276:63
const invites = {};
const wait = require("util").promisify(setTimeout);
client.on("ready", () => {
wait(1000);
client.guilds.cache.forEach(g => {
g.fetchInvites().then(guildInvites => {
invites[g.id] = guildInvites;
});
});
});
client.on("guildMemberAdd", member => {
member.setNickname("• İsim ' Yaş");
member.setNickname("• İsim ' Yaş");
member.roles.add(ayarlar.kayıtsızRol)
member.roles.add(ayarlar.kayıtsızRol)
if (member.user.bot) return;
member.guild.fetchInvites().then(async guildInvites => {
const ei = invites[member.guild.id];
invites[member.guild.id] = guildInvites;
const invite = await guildInvites.find(
i => (ei.get(i.code) == null ? i.uses - 1 : ei.get(i.code).uses) < i.uses
);
const daveteden = member.guild.members.cache.get(invite.inviter.id);
db.add(`davet_${invite.inviter.id}_${member.guild.id}`, +1);
db.set(`bunudavet_${member.id}`, invite.inviter.id);
let davetsayiv2 = await db.fetch(
`davet_${invite.inviter.id}_${member.guild.id}`
);
let davetsayi;
if (!davetsayiv2) davetsayi = 0;
else
davetsayi = await db.fetch(
`davet_${invite.inviter.id}_${member.guild.id}`
);
let date = moment(member.user.createdAt)
const startedAt = Date.parse(date);
var msecs = Math.abs(new Date() - startedAt);
const years = Math.floor(msecs / (1000 * 60 * 60 * 24 * 365));
msecs -= years * 1000 * 60 * 60 * 24 * 365;
const months = Math.floor(msecs / (1000 * 60 * 60 * 24 * 30));
msecs -= months * 1000 * 60 * 60 * 24 * 30;
const weeks = Math.floor(msecs / (1000 * 60 * 60 * 24 * 7));
msecs -= weeks * 1000 * 60 * 60 * 24 * 7;
const days = Math.floor(msecs / (1000 * 60 * 60 * 24));
msecs -= days * 1000 * 60 * 60 * 24;
const hours = Math.floor(msecs / (1000 * 60 * 60));
msecs -= hours * 1000 * 60 * 60;
const mins = Math.floor((msecs / (1000 * 60)));
msecs -= mins * 1000 * 60;
const secs = Math.floor(msecs / 1000);
msecs -= secs * 1000;
var string = "";
if (years > 0) string += `${years} yıl ${months} ay`
else if (months > 0) string += `${months} ay ${weeks > 0 ? weeks+" hafta" : ""}`
else if (weeks > 0) string += `${weeks} hafta ${days > 0 ? days+" gün" : ""}`
else if (days > 0) string += `${days} gün ${hours > 0 ? hours+" saat" : ""}`
else if (hours > 0) string += `${hours} saat ${mins > 0 ? mins+" dakika" : ""}`
else if (mins > 0) string += `${mins} dakika ${secs > 0 ? secs+" saniye" : ""}`
else if (secs > 0) string += `${secs} saniye`
string = string.trim();
let guild = member.client.guilds.cache.get(ayarlar.SunucuID)
let log = guild.channels.cache.get(ayarlar.hosgeldinKanal);
let endAt = member.user.createdAt
let gün = moment(new Date(endAt).toISOString()).format('DD')
let ay = moment(new Date(endAt).toISOString()).format('MM').replace("01", "Ocak").replace("02", "Şubat").replace("03", "Mart").replace("04", "Nisan").replace("05", "Mayıs").replace("06", "Haziran").replace("07", "Temmuz").replace("08", "Ağustos").replace("09", "Eylül").replace("10", "Ekim").replace("11", "Kasım").replace("12", "Aralık")
let yıl = moment(new Date(endAt).toISOString()).format('YYYY')
let saat = moment(new Date(endAt).toISOString()).format('HH:mm')
let kuruluş = `${gün} ${ay} ${yıl} ${saat}`;
log.send(`
> :tada: **Adalet #1951** Sunucumuza hoş geldin ${member} seninle birlikte **${member.guild.memberCount}** üyeye ulaştık!
> ** **
> Hesabın **${kuruluş} (${string})** önce oluşturulmuş.
> ** **
> Sunucu kurallarımız <#896409238274965525> kanalında yazıyor sunucu kurallarına uymazsan cezalandırılırsın!
> ** **
> **Davet eden:** ${daveteden} \`${davetsayi}.\` davetini gerçekleştirdi.`)
})});
client.on("guildMemberRemove", async member => {
let davetçi = await db.fetch(`bunudavet_${member.id}`);
const daveteden = member.guild.members.cache.get(davetçi);
db.add(`davet_${davetçi}_${member.guild.id}`, -1);
})

Let the user decide how many items in a page

Context
We have a table with 155 elements,
I want to build this field on every pages,
'Showing result [from starting item - to item number X ] of itemTotal'
StartingItem = 1 -----> at page 1
ItemNumberX = the user can see the next 25 items
this is the actual pages filter
These are data that I actually have
const minShowData = currentPage === 1 ? 1 : (currentPage - 1) * itemsPerPage;
const itemsAtCurrentPage = currentPage * itemsPerPage;
const maxShowData =
totalCount > itemsAtCurrentPage ? itemsAtCurrentPage : totalCount;
const showElement = [5, 10, 20, 25, 50]; ----> this is the old pagination
we have the data itemsPerPage through a reducer, and represent how many items we will see in page, in the second field risultati per pagina is set to 2.
this is how the variable showElement appear
there is a way with these data to made a filter like
Showing results [1-25, 26-50, 51-75 ...] of 155 ?
I don't need the code to build the component, just understand if there is a way to build the computation inside the field
so you have
const itemsPerPage = 25; //this you can set to be user alterable if you want
const itemsTotal = 155; //this you'd use a function to go get the number of items.
const pageIncrements[];
for (let pageNumber = 1; pageNumber <= itemsTotal / itemsPerPage; pageNumber++) {
pageIncrements += [((pageNumber - 1) * (itemsPerPage) + 1)) + " - " + (pageNumber * itemsPerPage)]
}
if (itemsTotal % itemsPerPage > 0) {
pageIncrements += [(itemsTotal - (itemsTotal % itemsPerPage)) + " - " + itemsTotal]
}
Sorry, haven't worked with react syntax, but the logic should be right.

React: How do I create an array from an API object and then select one element randomly for a value?

Do you know how I could make an array of the x,y coordinates and then select one randomly to place in a value?
<g id="lines">
{data.sites.map((item, i) => {
let findX = (180 + item.attributes.address.Longitude) * (1552 / 360);
let findY = (90 - item.attributes.address.Latitude) * (818/ 180);
let randoXY = findX + ',' findY (and randomly selects one of the X, Y values);
return (
<path key={i + i + '--'} id={'line' + (i + 1)} class="cls-3" d={'M' + findX + ','
+ findY +'L' + randoXY} />
)
})}
</g>
Create an array that will contains some random points:
let arr = [0,1,2,3,4,5,6,7,8,9];
Then Use Math.random() to select a random index, make sure index always lies within the length of the array (always multiply the value of Math.random() by the length of the array by this way it will never be greater than the length) then convert the value to integer by using Math.floor().
Use this to select random x and y values from the array:
<g id="lines">
{data.sites.map((item, i) => {
let findX = (180 + item.attributes.address.Longitude) * (1552 / 360);
let findY = (90 - item.attributes.address.Latitude) * (818/ 180);
let x = a[Math.floor(Math.random() * 10)];
let y = a[Math.floor(Math.random() * 10)];
return (
<path
key={i + i + '--'}
id={'line' + (i + 1)}
class="cls-3"
d={`M${findX}, ${findY}L${x},${y}`} />
)})
}
</g>

Extracting the actual playing video area (i.e without the black bars) in videogular

Is there a way to extract the actual playing video area (e.g x,y,width,height) inside the videogular player?
by "actual playing video", i mean the part between the black bars (in cases when the videogular container has different aspect ratio than the video itself).
Thanks
I'm the creator of Videogular.
You can extract that information from the API.mediaElement property.
I recommend you to extract the info on the onUpdateTime callback, since you will receive the video object dimensions when the video metadata is loaded. For example:
this.onUpdateTime = function (currentTime, totalTime) {
this.currentTime = currentTime;
this.totalTime = totalTime;
var containerWidth = this.API.mediaElement[0].offsetWidth;
var containerHeight = this.API.mediaElement[0].offsetHeight;
var videoWidth = this.API.mediaElement[0].videoWidth;
var videoHeight = this.API.mediaElement[0].videoHeight;
console.log(containerWidth);
console.log(containerHeight);
console.log(videoWidth);
console.log(videoHeight);
var calcVideoHeight = videoHeight * containerWidth / videoWidth;
var videoY = (containerHeight - calcVideoHeight) / 2;
console.log(calcVideoHeight);
console.log(videoY);
console.log("actual playing area");
console.log("x: " + this.API.mediaElement[0].offsetLeft +
" | y: " + videoY +
" | videoWidth: " + containerWidth +
" | videoHeight: " + calcVideoHeight);
};

Script to export layer coordinates to excel

I have found a script that export my layers coordinates form photoshop CS5 to XML
I hope somebody here can help me to edit that script to record coordinates to xls file?
Also if is possible to have each coordinates on separate row will be great.
Below is script I want to modify to do what I need.
//
// This script exports extended layer.bounds information to [psd_file_name].xml
// by pattesdours
//
function docCheck() {
// ensure that there is at least one document open
if (!documents.length) {
alert('There are no documents open.');
return; // quit
}
}
docCheck();
var originalRulerUnits = preferences.rulerUnits;
preferences.rulerUnits = Units.PIXELS;
var docRef = activeDocument;
var docWidth = docRef.width.value;
var docHeight = docRef.height.value;
var mySourceFilePath = activeDocument.fullName.path + "/";
// Code to get layer index / descriptor
//
cTID = function(s) { return app.charIDToTypeID(s); };
sTID = function(s) { return app.stringIDToTypeID(s); };
function getLayerDescriptor (doc, layer) {
var ref = new ActionReference();
ref.putEnumerated(cTID("Lyr "), cTID("Ordn"), cTID("Trgt"));
return executeActionGet(ref)
};
function getLayerID(doc, layer) {
var d = getLayerDescriptor(doc, layer);
return d.getInteger(cTID('LyrI'));
};
var stackorder = 0;
// function from Xbytor to traverse all layers
traverseLayers = function(doc, ftn, reverse) {
function _traverse(doc, layers, ftn, reverse) {
var ok = true;
for (var i = 1; i <= layers.length && ok != false; i++) {
var index = (reverse == true) ? layers.length-i : i - 1;
var layer = layers[index];
if (layer.typename == "LayerSet") {
ok = _traverse(doc, layer.layers, ftn, reverse);
} else {
stackorder = stackorder + 1;
ok = ftn(doc, layer, stackorder);
}
}
return ok;
};
return _traverse(doc, doc.layers, ftn, reverse);
};
// create a string to hold the data
var str ="";
// class using a contructor
function cLayer(doc, layer) {
//this.layerID = Stdlib.getLayerID(doc, layer);
this.layerID = getLayerID(doc, layer);
//alert("layer ID: " + this.layerID);
this.layerWidth = layer.bounds[2].value - layer.bounds[0].value;
this.layerHeight = layer.bounds[3].value - layer.bounds[1].value;
// these return object coordinates relative to canvas
this.upperLeftX = layer.bounds[0].value;
this.upperLeftY = layer.bounds[1].value;
this.upperCenterX = this.layerWidth / 2 + layer.bounds[0].value;
this.upperCenterY = layer.bounds[1].value;
this.upperRightX = layer.bounds[2].value;
this.upperRightY = layer.bounds[1].value;
this.middleLeftX = layer.bounds[0].value;
this.middleLeftY = this.layerHeight / 2 + layer.bounds[1].value;
this.middleCenterX = this.layerWidth / 2 + layer.bounds[0].value;
this.middleCenterY = this.layerHeight / 2 + layer.bounds[1].value;
this.middleRightX = layer.bounds[2].value;
this.middleRightY = this.layerHeight / 2 + layer.bounds[1].value;
this.lowerLeftX = layer.bounds[0].value;
this.lowerLeftY = layer.bounds[3].value;
this.lowerCenterX = this.layerWidth / 2 + layer.bounds[0].value;
this.lowerCenterY = layer.bounds[3].value;
this.lowerRightX = layer.bounds[2].value;
this.lowerRightY = layer.bounds[3].value;
// I'm adding these for easier editing of flash symbol transformation point (outputs a 'x, y' format)
// because I like to assign shortcut keys that use the numeric pad keyboard, like such:
// 7 8 9
// 4 5 6
// 1 2 3
//
this.leftBottom = this.lowerLeftX + ", " + this.lowerLeftY;
this.bottomCenter = this.lowerCenterX + ", " + this.lowerCenterY;
this.rightBottom = this.lowerRightX + ", " + this.lowerRightY;
this.leftCenter = this.middleLeftX + ", " + this.middleLeftY;
this.center = this.middleCenterX + ", " + this.middleCenterY;
this.rightCenter = this.middleRightX + ", " + this.middleRightY;
this.leftTop = this.upperLeftX + ", " + this.upperLeftY;
this.topCenter = this.upperCenterX + ", " + this.upperCenterY;
this.rightTop = this.upperRightX + ", " + this.upperRightY;
// these return object coordinates relative to layer bounds
this.relUpperLeftX = layer.bounds[1].value - layer.bounds[1].value;
this.relUpperLeftY = layer.bounds[0].value - layer.bounds[0].value;
this.relUpperCenterX = this.layerWidth / 2;
this.relUpperCenterY = layer.bounds[0].value - layer.bounds[0].value;
this.relUpperRightX = this.layerWidth;
this.relUpperRightY = layer.bounds[0].value - layer.bounds[0].value;
this.relMiddleLeftX = layer.bounds[1].value - layer.bounds[1].value;
this.relMiddleLeftY = this.layerHeight / 2;
this.relMiddleCenterX = this.layerWidth / 2;
this.relMiddleCenterY = this.layerHeight / 2;
this.relMiddleRightX = this.layerWidth;
this.relMiddleRightY = this.layerHeight / 2;
this.relLowerLeftX = layer.bounds[1].value - layer.bounds[1].value;
this.relLowerLeftY = this.layerHeight;
this.relLowerCenterX = this.layerWidth / 2;
this.relLowerCenterY = this.layerHeight / 2;
this.relLowerRightY = this.layerHeight;
this.relLowerRightX = this.layerWidth;
this.relLowerRightY = this.layerHeight;
return this;
}
// add header line
//str = "<psd filename=\"" + docRef.name + "\" path=\"" + mySourceFilePath + "\" width=\"" + docWidth + "\" height=\"" + docHeight + "\">\n";
// now a function to collect the data
function exportBounds(doc, layer, i) {
var isVisible = layer.visible;
var layerData = cLayer(doc, layer);
// if(isVisible){
// Layer object main coordinates relative to its active pixels
var str2 = leftTop // this is the
// + "\" layerwidth=\"" + layerData.layerWidth
// + "\" layerheight=\"" + layerData.layerHeight
// + "\" transformpoint=\"" + "center" + "\">" // hard-coding 'center' as the default transformation point
+"\" \"" + layer.name + ".png" + "</layer>\n" // I have to put some content here otherwise sometimes tags are ignored
str += str2.toString();
};
//};
// call X's function using the one above
traverseLayers(app.activeDocument, exportBounds, true);
// Use this to export XML file to same directory where PSD file is located
var mySourceFilePath = activeDocument.fullName.path + "/";
// create a reference to a file for output
var csvFile = new File(mySourceFilePath.toString().match(/([^\.]+)/)[1] + app.activeDocument.name.match(/([^\.]+)/)[1] + ".xls");
// open the file, write the data, then close the file
csvFile.open('w');
csvFile.writeln(str + "</psd>");
csvFile.close();
preferences.rulerUnits = originalRulerUnits;
// Confirm that operation has completed
alert("Operation Complete!" + "\n" + "Layer coordinates were successfully exported to:" + "\n" + "\n" + mySourceFilePath.toString().match(/([^\.]+)/)[1] + app.activeDocument.name.match(/([^\.]+)/)[1] + ".xml");
Change
var str2 = leftTop // this is the
// + "\" layerwidth=\"" + layerData.layerWidth
// + "\" layerheight=\"" + layerData.layerHeight
// + "\" transformpoint=\"" + "center" + "\">" // hard-coding 'center' as the default transformation point
+"\" \"" + layer.name + ".png" + "</layer>\n" // I have to put some content here otherwise sometimes tags are ignored
str += str2.toString();
to
var str2 = leftTop + ","+ layer.name + "\n"
str += str2.toString();
and
var csvFile = new File(mySourceFilePath.toString().match(/([^\.]+)/)[1] + app.activeDocument.name.match(/([^\.]+)/)[1] + ".xls");
to
var csvFile = new File(mySourceFilePath.toString().match(/([^\.]+)/)[1] + app.activeDocument.name.match(/([^\.]+)/)[1] + ".csv");
This works great for me!

Resources