Vehicle Spinner move faster when moving mouse faster - vue.js

How can I speed up the rotation speed in the below script. Currently the movement is calculated like so:
handleMove($event) {
if (this.isMoving && this.isDragging) {
const positions = {
x: $event.pageX || $event.touches[0].pageX,
y: $event.pageY || $event.touches[0].pageY
}
this.changeFrame(positions);
this.lastX = positions.x;
this.lastY = positions.y;
}
},
changeFrame(positions) {
this.speedController += 1;
if ((this.speedController < this.speed)) {
return;
}
if (this.speedController > this.speed) {
this.speedController = 0;
}
if (positions.x > this.lastX) {
if (this.frame >= 0 && this.frame < this.images.length) {
this.frame += 1;
} else if (this.loop) {
this.frame = 1;
}
} else if (positions.x < this.lastX) {
if (this.frame >= 0 && this.frame - 1 > 0) {
this.frame -= 1;
} else if (this.loop) {
this.frame = this.images.length;
}
}
}
I have tried to change section where it increases the the frame number, to this.frame += positions.x - this.lastX however I then get the following error:
[Vue warn]: You may have an infinite update loop in a component render function.
What is the best way to do this? You can see the script running here.
Edit
I have updated the script, however it is really glitchy! Use the link for a live example.
changeFrame(positions) {
const diff = positions.x - this.startX;
let frameDelta = diff / this.speed;
this.frame += Math.round(frameDelta);
if (this.frame < 0) {
this.frame += this.images.length;
} else if (this.frame > this.images.length - 1) {
this.frame = this.frame % this.images.length;
}
}

Your logic is that as long as position.x > this.lastX that you increment this.frame by 1. If you want it to spin faster, then increment it by a larger number. The same goes for decrementing the number.
However, this speed depends on how often changeFrame() is fired, and that can be variable due to browser performance and etc. If you want the most accurate results, you should simply increment/decrement the frame based on how much the position has changed.
If you say, want to change the speed so that for every 10px of cursor movement you increment the frame by one, you can do this:
const diff = positions.x - this.lastX;
// Let's say we increment/decrement the frame for every 10px travelled
const rateOfSpin = 10;
// Number of frames of change, adjusted based on desired rate of spin
const frameDelta = diff / rateOfSpin;
this.frame += frameDelta;
// If we go below zero, then we start from the end
if (this.frame < 0) {
this.frame += this.images.length;
// Otherwise we simply get the modulus
} else if (this.frame > this.images.length) {
this.frame = this.frame % this.images.length;
}

Related

Angular - can't sum point

I want to sum point but now I try write function and console.log(total) but it happens is 'undefined'
app.ts
saveTasks() {
if (this.tasksToSave.length != 0) {
for (let i = 0; this.tasksToSave.length > i; i++) {
this.ticketService.setAddTasks(
this.id,
this.tasksToSave[i]
)
}
}
}
sumPoint() {
let total = 0
if (this.tasksToSave.length != 0) {
for (let i = 0; i < this.tasksToSave.length; i++) {
total = total + this.tasksToSave[i].point
}
}
}
app.html
total = {{total}}
Put the total variable in the export block in the component like below:
export class YourComponent implements OnInit {
...
total: number = 0;
...
sumPoint() {
if (this.tasksToSave.length != 0) {
for (let i = 0; i < this.tasksToSave.length; i++) {
this.total = this.total + this.tasksToSave[i].point
}
}
}
...
}

Time out error using protractor with loops

Brief introduction to the problem. So my project is using BDD Framework (Cucumber) automated with help of Protractor/Selenium using Typescript as scripting language. I passed a table with multiple rows to the step definition and want to run the function in iteration mode using typescript/javascript. I pass the expected dropdowns values and verify it against the application. I came with the below solution with help of one topic on stack overflow. (Using protractor with loops)
But the problem is that it does not work all the time. Many times i have got function time out error.(Error: function timed out after 30000 milliseconds)
Can anyone please let me know what am i missing here? Any help would be greatly appreciated.
Please find below Cucumber and Typescript code.
Cucumber Step Definition_Screenshot
#then(/^.*verify the country data in both the citizenship drop downs$/, 'extratime', 30000)
public VerifyCountryData(table, callback: CallbackStepDefinition): void {
let promises = []
let dropcheck
let dropcheck1
let promise
let noOfRows
var i,j;
var i1,j1;
var k,l;
var funcs = [];
for (i = 0; i < 2; i++) {
let index = i;
funcs[i] = function(index) {
promises.push(element(by.model('vm.citizenships['+index+'].citizenshipCd')).all(by.tagName('option')).getText().then((CitizenValueList) => {
var dropdown = table.rows()[index][1].split(";")
for (i1 = 0; i1 < dropdown.length; i1++) {
dropcheck = false;
for (j1 = 0; j1 < CitizenValueList.length; j1++) {
if (dropdown[i1] === CitizenValueList[j1]) {
dropcheck = true;
break;
}
}
if (!dropcheck) {
callback("Passed value: '" + dropdown[i1] + "' not found")
}
}
for (k = 0; k < CitizenValueList.length; k++) {
dropcheck1 = false;
for (l = 0; l < dropdown.length; l++) {
if (CitizenValueList[k] === dropdown[l]) {
dropcheck1 = true;
break;
}
}
if (!dropcheck1) {
callback("Application value: '" + CitizenValueList[k] + "' not found in expected")
}
}
}))
}.bind(null, i);
}
for (j = 0; j < 2; j++) {
funcs[j]();
}
Promise.all(promises).then(() => {
callback();
}, (error) => {
callback(error);
});
}
}
as far as I can see in your code you loops will take more then 30 seconds, that's the timeout you gave in the #then(/^.*verify the country data in both the citizenship drop downs$/, 'extratime', 30000). If you change it to for example 60000 you have more time for this method.
Upgrading the time is a temporary solution in my opinion, you also need to find the root-cause of exceeding the 30 seconds time limit. One of the problems can be a slow connection which results in not retrieving the webdriver-calls fast enough. Are you testing it locally or against a cloud solution? The experience I have with cloud solutions is that 1 webdriver-call can take up to 1 second. If you compare it to local testing than local webdriver-calls just take a few milliseconds.
About the code. Depending on the version of Typescript you have (I think you need at least version 2.1) you can use async/await. This will remove all the promises.push(..), Promise.all(promises) hell and introduce a more clean code like this
#then(/^.*verify the country data in both the citizenship drop downs$/, 'extratime', 30000)
public async VerifyCountryData(table): Promise < void > {
const citizenValueListOne = await element(by.model('vm.citizenships[1].citizenshipCd')).all(by.tagName('option')).getText();
const dropdownOne = table.rows()[1][1].split(';');
const citizenValueListTwo = await element(by.model('vm.citizenships[2].citizenshipCd')).all(by.tagName('option')).getText();
const dropdownTwo = table.rows()[2][2].split(';');
for (let i1 = 0; i1 < dropdownOne.length; i1++) {
let dropdownOnecheck = false;
for (let j1 = 0; j1 < citizenValueListOne.length; j1++) {
if (dropdownOne[i1] === citizenValueListOne[j1]) {
dropdownOnecheck = true;
break;
}
}
if (!dropdownOnecheck) {
Promise.reject(`Passed value: '${dropdownOne[i1]}' not found`);
}
}
for (let k = 0; k < citizenValueListTwo.length; k++) {
let dropdownTwocheck = false;
for (let l = 0; l < dropdownTwo.length; l++) {
if (citizenValueListTwo[k] === dropdownTwo[l]) {
dropdownTwocheck = true;
break;
}
}
if (!dropdownTwocheck) {
Promise.reject(`Application value: '${citizenValueListTwo[k]}' not found in expected`);
}
}
return Promise.resolve();
}
This can also have an impact on the execution time.
Hope this helps

How to implement methods and state for vue.js component

I'm a beginner in VueJS. And as part of my learning process, I'm building a knob for my Pomodoro app. This is my fiddle.
I copied the knob code from codepen, which is implemented using jquery. As you can see in the fiddle most of the job is done by jquery.
I need to try and do this using Vue.js, using its methods and states.
How to refactor this code to a better Vue.JS code? Any suggestions much appreciated.
Vue.component('timer', {
mounted() {
var knob = $('.knob');
var angle = 0;
var minangle = 0;
var maxangle = 270;
var xDirection = "";
var yDirection = "";
var oldX = 0;
var oldY = 0;
function moveKnob(direction) {
if(direction == 'up') {
if((angle + 2) <= maxangle) {
angle = angle + 2;
setAngle();
}
}
else if(direction == 'down') {
if((angle - 2) >= minangle) {
angle = angle - 2;
setAngle();
}
}
}
function setAngle() {
// rotate knob
knob.css({
'-moz-transform':'rotate('+angle+'deg)',
'-webkit-transform':'rotate('+angle+'deg)',
'-o-transform':'rotate('+angle+'deg)',
'-ms-transform':'rotate('+angle+'deg)',
'transform':'rotate('+angle+'deg)'
});
// highlight ticks
var activeTicks = (Math.round(angle / 10) + 1);
$('.tick').removeClass('activetick');
$('.tick').slice(0,activeTicks).addClass('activetick');
// update % value in text
var pc = Math.round((angle/270)*100);
$('.current-value').text(pc+'%');
}
var RAD2DEG = 180 / Math.PI;
knob.centerX = knob.offset().left + knob.width()/2;
knob.centerY = knob.offset().top + knob.height()/2;
var offset, dragging=false;
knob.mousedown(function(e) {
dragging = true;
offset = Math.atan2(knob.centerY - e.pageY, e.pageX - knob.centerX);
})
$(document).mouseup(function() {
dragging = false
})
$(document).mousemove(function(e) {
if (dragging) {
if (oldX < e.pageX) {
xDirection = "right";
} else {
xDirection = "left";
}
oldX = e.pageX;
if(xDirection === "left") {
moveKnob('down');
} else {
moveKnob('up');
}
return false;
}
})
}
});
This example runs without jQuery.
https://jsfiddle.net/guanzo/d6vashmu/6/
Declare all the variables you need in the data function.
Declare all functions under the methods property.
Declare variables that are derived from other variables in the computed property, such as knobStyle, activeTicks, and currentValue, which are all computed from angle. Whenever angle changes, these 3 computed properties will automatically update.
Regarding the general usage of Vue, you should focus on manipulating the data, and letting Vue update the DOM for you.

needed thumbnail tiles scroller/slideshow/slider

I'm looking for a thumbnail tiles scroller/slideshow/slider
Here is the example http://safari.to/clients
Really appreciate if anyone could help :) Thanks
When you see something on any website, its easy to inspect and see how they are doing it.
The website mentioned by you is doing it using their own script instead of a plug in
See the following code from http://safari.to/assets/js/script.js. You will also need to see how they are styling the sliders by inspecting their CSS code
// Agencies slide
var clients = Math.floor(Math.random() * 2) + 1; // nth-child indices start at 1
if ( clients == 1){
$('.agencies.clients').hide();
}
else
{
$('.brands.clients').hide();
}
$('.agencies menu a').bind({
click: function()
{
if(sliding) return false;
var pointer = $(this);
var width = $('.agencies .scroller li').length * 137;
var current = parseInt($('.agencies .scroller').css('left'));
var distance = 0;
if(pointer.is('.right-pointer'))
{
if(current == -1920) distance = current - 137;
else distance = current - 960;
if((width + current) < 960)
distance = current;
}
else
{
distance = current + 1097;
if(distance > 0)
distance = 0;
}
sliding = true;
$('.scroller').animate({
left: distance + 'px'
}, 300,
function()
{
sliding = false;
});
}
});

Disable carousel overscroll/overdrag in Sencha Touch

At the end or beginning of a Sencha Touch 2 carousel, a user can drag the item past where it should be able to go and display the white background (screenshot here: http://i.imgur.com/MkX0sam.png). I'm trying to disable this functionality, so a user can't drag past the end/beginning of a carousel.
I've attempted to do this with the various scrollable configurations, including the setup that is typically suggested for dealing with overscrolling
scrollable : {
direction: 'horizontal',
directionLock: true,
momentumEasing: {
momentum: {
acceleration: 30,
friction: 0.5
},
bounce: {
acceleration: 0.0001,
springTension: 0.9999,
},
minVelocity: 5
},
outOfBoundRestrictFactor: 0
}
The above configuration, especially outOfBoundRestrictFactor does stop the ability to drag past the end, but it also stops the ability to drag anywhere else in a carousel either...so that doesn't work. I've screwed around with all of the other configurations to no positive effect.
Unfortunately, I haven't been able to find much on modifying the configurations of dragging. Any help here would be awesomesauce.
What you need to do is override the onDrag functionality in Carousel. This is where the logic is to detect which direction the user is dragging, and where you can check if it is the first or last item.
Here is a class that does exactly what you want. The code you are interested in is right at the bottom of the function. The rest is simply taken from Ext.carousel.Carousel.
Ext.define('Ext.carousel.Custom', {
extend: 'Ext.carousel.Carousel',
onDrag: function(e) {
if (!this.isDragging) {
return;
}
var startOffset = this.dragStartOffset,
direction = this.getDirection(),
delta = direction === 'horizontal' ? e.deltaX : e.deltaY,
lastOffset = this.offset,
flickStartTime = this.flickStartTime,
dragDirection = this.dragDirection,
now = Ext.Date.now(),
currentActiveIndex = this.getActiveIndex(),
maxIndex = this.getMaxItemIndex(),
lastDragDirection = dragDirection,
offset;
if ((currentActiveIndex === 0 && delta > 0) || (currentActiveIndex === maxIndex && delta < 0)) {
delta *= 0.5;
}
offset = startOffset + delta;
if (offset > lastOffset) {
dragDirection = 1;
}
else if (offset < lastOffset) {
dragDirection = -1;
}
if (dragDirection !== lastDragDirection || (now - flickStartTime) > 300) {
this.flickStartOffset = lastOffset;
this.flickStartTime = now;
}
this.dragDirection = dragDirection;
// now that we have the dragDirection, we should use that to check if there
// is an item to drag to
if ((dragDirection == 1 && currentActiveIndex == 0) || (dragDirection == -1 && currentActiveIndex == maxIndex)) {
return;
}
this.setOffset(offset);
}
});