Best JavaScript code snippet using playwright-internal
bounceGame.js
Source: bounceGame.js
...99 "prob": 0.25, //def: 0.25100 "duration": 0, //def: 0101 "text": " SPEED BOOST",102 "symbol": " SPD",103 "pushEffect": function pushEffect() { 104 for( var b = 0 ; b < balls.length ; b++ ) {105 balls[b].vx = sign(balls[b].vx)*(abs(balls[b].vx)+0.2)106 balls[b].vy = sign(balls[b].vy)*(abs(balls[b].vy)+0.2)107 balls[b].vx *= 3;108 balls[b].vy *= 3;109 }110 },111 "popEffect": function popEffect() {}112 },113 //f is increased114 1: { //multiply f by 1.25115 "id": "more_force",116 "prob": 0.25, //def: 0.25117 "duration": 5, //def: 5118 "text": " STRENGTH UP",119 "symbol": " STR",120 "pushEffect": function pushEffect() { f *= 1.25 },121 "popEffect": function popEffect() { f /= 1.25 }122 },123 //balls are duplicated124 2: { //+2 balls125 "id": "more_balls",126 "prob": 0.2, //def: 0.2127 "duration": 7, //def: 7128 "text": " EXTRA BALLS",129 "symbol": " +BALLS",130 "pushEffect": function pushEffect() { 131 if (balls.length > 19) {132 return;133 }134 for ( var i = 0 ; i < 2 ; i++ ) {135 balls.push(new Ball(balls[0].r, balls[0].x, balls[0].y, pow(1.1,i+1)*balls[0].vx, pow(1.1,i+1)*balls[0].vy));136 }137 },138 "popEffect": function popEffect() { 139 if (balls.length < 3) {140 return;141 }142 for ( var i = 0 ; i < 2 ; i++ ) {143 balls[0].finish();144 balls.shift();145 }146 }147 },148 //increase in ball size149 3: { //ball.r multiplied by 3150 "id": "large_ball",151 "prob": 0.3, //def: 0.3152 "duration": 8, //def: 8153 "text": " SIZE UP",154 "symbol": " +SIZE",155 "pushEffect": function pushEffect() {156 for( var b = 0 ; b < balls.length ; b++ ) {157 if (balls[b].r * 3 < width/2) {158 balls[b].r *= 3; 159 }160 }161 },162 "popEffect": function popEffect() {163 for( var b = 0 ; b < balls.length ; b++ ) {164 if (balls[b].r / 3 >= width/80) {165 balls[b].r /= 3; 166 }167 }168 }169 }170 },171 "wall": {172 //slows ball down, decreases strength173 0: { //ball speed divided by 5, f divided by 2174 "id": "slow_ball",175 "prob": 0.2, //def: 0.2176 "duration": 5, //def: 5177 "text": " SPEED DOWN",178 "symbol": " SLOW",179 "pushEffect": function pushEffect() {180 for( var b = 0 ; b < balls.length ; b++ ) {181 balls[b].vx /= 5;182 balls[b].vy /= 5;183 }184 f /= 2;185 },186 "popEffect": function popEffect() {187 f *= 2;188 }189 },190 //makes wall untouchable for n seconds191 1: { //5 seconds192 "id": "invisible",193 "prob": 0.15, //def: 0.15194 "duration": 5, //def: 5195 "text": " INVICIBILITY",196 "symbol": " INV",197 "pushEffect": function pushEffect() {198 wall_state = wallStates.none;199 },200 "popEffect": function popEffect() {201 wall_state = wallStates[int(random(0,3.999))];202 }203 },204 //ball slows down more when bouncing205 2: { //hitting wall has more friction206 "id": "sticky",207 "prob": 0.4, //def: 0.4208 "duration": 7, //def: 7209 "text": " STICKY BALL",210 "symbol": " STICKY",211 "pushEffect": function pushEffect() {212 friction *= 2;213 },214 "popEffect": function popEffect() {215 friction /= 2;216 }217 },218 //switching walls can be done in quick succession219 3: {// just add duration // this isn't exactly trivial220 "id": "no_cool_w",221 "prob": 0.25, //def: 0.25222 "duration": 6, //def: 6223 "text": " NO SWITCH COOLDOWN",224 "symbol": " 0 COOL",225 "pushEffect": function pushEffect() {226 wcoolmax = 0;227 },228 "popEffect": function popEffect() {229 wcoolmax = wcooldef;230 }231 }232 },233 "neutral": {234 //ay is set to some huge amount // this causes issues235 0: { //ay multipled by 1.75236 "id": "intense_grav",237 "prob": 0.3, //def: 0.3238 "duration": 4, //def: 4239 "text": " MORE GRAV",240 "symbol": " +G'S",241 "pushEffect": function pushEffect() {242 for( var b = 0 ; b < balls.length ; b++ ) {243 balls[b].ay *= 1.75;244 }245 },246 "popEffect": function popEffect() {247 for( var b = 0 ; b < balls.length ; b++ ) {248 balls[b].ay /= 1.75;249 }250 }251 },252 //ay, ax are set to some small amount253 1: { //ax is divided by 2, ay is divided by 6254 "id": "no_grav",255 "prob": 0.4, //def: 0.4256 "duration": 6, //def: 6257 "text": " ANTI-GRAV",258 "symbol": " 0G'S",259 "pushEffect": function pushEffect() {260 for( var b = 0 ; b < balls.length ; b++ ) {261 balls[b].ax /= 2;262 balls[b].ay /= 6;263 }264 },265 "popEffect": function popEffect() {266 for( var b = 0 ; b < balls.length ; b++ ) {267 balls[b].ax *= 2;268 balls[b].ay *= 6;269 }270 }271 },272 //bizarre movement/size from ball WIP273 2: { //if duplicated, amplify effects by 2x (?)274 "id": "random_ball",275 "prob": 0.1, //def: 0.1276 "duration": 8, //def: 8277 "text": " ???",278 "symbol": "",279 "pushEffect": function pushEffect() {},280 "popEffect": function popEffect() {}281 },282 //wall selection spins ccw/cw when pressed instead WIP283 3: { //just add duration284 "id": "wall_spin",285 "prob": 0.2, //def: 0.2286 "duration": 5, //def: 5287 "text": " CLOCK-WALL",288 "symbol": " CLK",289 "pushEffect": function pushEffect() {},290 "popEffect": function popEffect() {}291 }292 }293}294//framework for buttons295class Button { 296 297 constructor(x, y, w, h, r = (width+height)/70) {298 this.x = x;299 this.y = y;300 this.width = w;301 this.height = h;302 this.r = r;303 this.on_display = false; // may be unneccesary304 this.mouse_over = false;305 }306 //display the button on the screen307 display() {308 rect(this.x, this.y, this.width, this.height, this.r);309 }310 311 //check if button is pressed312 update() {313 if (mouseX > this.x - this.width / 2 && mouseX < this.x + this.width / 2 && mouseY > this.y - this.height / 2 && mouseY < this.y + this.height / 2) {314 this.mouse_over = true;315 }316 else {317 this.mouse_over = false;318 }319 }320 321 finish() {322 this.x = null;323 this.y = null;324 this.width = null;325 this.height = null;326 this.r = null;327 this.on_display = null;328 this.mouse_over = null;329 }330 331}332//framework for the ball objects333class Ball {334 335 constructor(r = width/80, x0 = width/2, y0 = height/4, vx0 = 0, vy0 = 0) { //def: width/80, width/2, height/4, 0, 0336 this.x = x0;337 this.y = y0;338 this.vx = vx0;339 this.vy = vy0;340 this.r = r;341 this.ax = def_ax;342 this.ay = def_ay;343 }344 345 //displays the ball on screen346 display() {347 // prepare fill for ball348 if (flag) {349 fill(240, 130, 150, 100);350 } else {351 fill(210, 190, 250);352 }353 // draw ball354 ellipse(this.x, this.y, 2*this.r, 2*this.r);355 }356 357 update() { //updates position of ball358 359 this.x += this.vx;360 this.y += this.vy;361 if (this.vx > 0) {362 this.vx -= this.ax;363 } else {364 this.vx += this.ax;365 }366 367 // ball movement/bounce logic, point scoring logic368 // bounce from right wall369 if (this.x + this.r > width) {370 if(powerup_exists){371 new_powerup.lifespan *= bounce_penalty; 372 }373 this.vx = -0.95 * abs(this.vx);374 this.vy /= friction;375 fill(180, 50, 60, 40 * pow(this.vx, 2));376 if (wall_state == wallStates.right && !flag) {377 p0 += 1;378 ellipse(this.x+this.r, this.y, 12*this.r, 12*this.r);379 flag = flagtime;380 } else {381 ellipse(this.x+this.r, this.y, 5*this.r, 5*this.r);382 }383 }384 385 // bounce from left wall386 if (this.x - this.r < 0) {387 if(powerup_exists){388 new_powerup.lifespan *= bounce_penalty; 389 }390 this.vx = 0.95 * abs(this.vx);391 this.vy /= friction;392 fill(180, 50, 60, 40 * pow(this.vx, 2));393 if (wall_state == wallStates.left && !flag) {394 p0 += 1;395 ellipse(this.x-this.r, this.y, 12*this.r, 12*this.r);396 flag = flagtime;397 } else {398 ellipse(this.x-this.r, this.y, 5*this.r, 5*this.r);399 }400 }401 402 // bounce from bottom wall403 if (this.y + this.r > height) {404 if(powerup_exists){405 new_powerup.lifespan *= bounce_penalty; 406 }407 this.vy = -0.85 * abs(this.vy);408 this.vx /= friction;409 fill(180, 50, 60, 40 * pow(this.vy, 2));410 if (wall_state == wallStates.bottom && !flag) {411 p0 += 1;412 ellipse(this.x, this.y+this.r, 12*this.r, 12*this.r);413 flag = flagtime;414 } else {415 ellipse(this.x, this.y+this.r, 5*this.r, 5*this.r);416 }417 }418 419 // bounce from top wall420 if (this.y - this.r < 0) {421 if(powerup_exists){422 new_powerup.lifespan *= bounce_penalty; 423 }424 this.vy = 0.85 * abs(this.vy);425 this.vx /= friction;426 fill(180, 50, 60, 40 * pow(this.vy, 2));427 if (wall_state == wallStates.top && !flag) {428 p0 += 1;429 ellipse(this.x, this.y-this.r, 12*this.r, 12*this.r);430 flag = flagtime;431 } else {432 ellipse(this.x, this.y-this.r, 5*this.r, 5*this.r);433 }434 }435 // rolling condition (too close to ground and not bouncing)436 if (this.y + this.r > 0.997 * height && abs(this.vy) < 0.5*abs(ay)) {437 this.vy = 0;438 this.y = height - this.r;439 } else {440 this.vy += this.ay;441 }442 }443 444 //gives the ball a push from the cursor445 impulse(mX, mY) { //may change this to make it circular446 this.vx += 0.02 * f * (this.x - mX);447 this.vy += 0.02 * f * (this.y - mY);448 if(this.x < 0 || this.y < 0 || this.x > width || this.y > height ) {449 this.x = width/2;450 this.y = height/2;451 }452 }453 454 finish() { //deallocator455 this.x = null;456 this.y = null;457 this.vx = null;458 this.vy = null;459 this.r = null;460 this.ax = null;461 this.ay = null;462 }463 464}465//framework for powerup interactive instances466class PowerUp {467 468 constructor() {469 this.birth = t;470 this.lifespan = 60; // def: 6471 this.x = width/2 + random(-width/3, width/3) + random(-width/8, -width/8);472 this.y = height/2 + random(-height/3, height/3) + random(-height/8, height/8);473 this.r = random(width/20, width/15);474 this.explicit = false;475 this.neutral = false;476 this.choice = null;477 this.determine();478 }479 480 // basically, rolls some chances to select which powerup is instantiated481 determine() {482 483 var powerup_prob_array = [];484 var powerup_choice;485 486 //decides if text will be displayed before collection487 if(random(0.0, 1.0) <= power.explicit_chance) {488 this.explicit = true;489 }490 491 //decides if power will be neutral instead of biased492 //either way, takes the powerup entries from the object and creates a temp array of them493 if(random(0.0, 1.0) <= power.n_chance) {494 powerup_prob_array = Object.keys(power.neutral);495 this.choice = power.neutral;496 this.neutral = true;497 }498 else {499 powerup_prob_array = Object.keys(power.ball);500 this.choice = power.ball;501 }502 503 //sets each element in that array to be the defined probability of rolline the powerup, at the given index504 for (var powerup_i in powerup_prob_array) {505 powerup_prob_array[powerup_i] = this.choice[powerup_i].prob;506 }507 //uses a weighted dice roll to determine the chosen power508 powerup_choice = probability(powerup_prob_array);509 this.choice = this.choice[powerup_choice];510 511 powerup_prob_array = null;512 powerup_choice = null;513 514 }515 516 //displays the powerup visually517 display() {518 if(this.neutral){519 fill(255,240,255,20); //white520 } else {521 fill(255,150,170,40); //red522 }523 524 for(var pudr = 0; pudr < 20 ; pudr++ ) {525 ellipse(this.x,this.y,pudr*0.1*this.r,pudr*0.1*this.r);526 ellipse(this.x+random(-this.r/1.7,this.r/1.7),this.y+random(-this.r/1.7,this.r/1.7),pudr*0.05*this.r,pudr*0.05*this.r)527 }528 529 if(this.explicit){530 textSize(12);531 if(this.neutral) {532 fill(120,130,250);533 }534 else {535 fill(250,250,200);536 }537 text(this.choice.symbol, this.x, this.y, 16*this.r, 16*this.r);538 }539 540 }541 542 //checkes if the ball with parameter attributes overlaps with the powerup543 update(mX, mY, R) {544 //powerup is expired545 if ( t - this.birth > this.lifespan ) {546 powerup_exists = false;547 this.finish();548 }549 //power has been collected550 if(distance(this.x,this.y,mX,mY) <= this.r + R ) {551 this.collect();552 }553 }554 555 //when powerup is 'hit', destroy the powerup object and push the id of the powerup to an active powerup tracker556 collect() {557 powerup_exists = false;558 if(this.neutral){559 fill(255,240,255,80); //white560 } else {561 fill(255,150,170,150); //red562 }563 ellipse(this.x, this.y, 5*this.r, 5*this.r);564 fill(255);565 textSize(48);566 text(this.choice.text, width/2, height/2, width, height);567 active_powerups.push(new PowerEffect(this.choice));568 this.finish();569 }570 571 finish() { // deallocator572 this.birth = null;573 this.lifespan = null;574 this.x = null;575 this.y = null;576 this.r = null;577 this.explicit = null;578 this.neutral = null;579 this.choice = null;580 }581 582}583//framework for wall switch pattern minigame584class Sequence {585 586 constructor() {587 this.birth = t;588 this.lifespan = 3; //def: 3589 var random_num = round(randomGaussian(0,2));590 this.length = 5 + random_num*(heaviside(random_num,-2)-heaviside(random_num,4));//default: 5,-2,4591 random_num = null;592 this.order = [];593 this.index = 0;594 this.max_attempts = 3; //default is 3595 this.attempts_left = this.max_attempts;596 this.neutral = false;597 this.choice = null;598 this.generateOrder();599 }600 601 //creates a sequence602 generateOrder() { //0:right, 1:down, 2:left, 3:up603 604 var i = round(random(-0.49,3.49));605 while ( wallStates[i] == wall_state ) {606 i = round(random(-0.49,3.49));607 }608 this.order.push(i);609 for( var i2 = 0; i2 < this.length-1; i2++ ) {610 i = round(random(-0.49,3.49));611 while( i == this.order[i2] ) {612 i = round(random(-0.49,3.49));613 }614 this.order.push(i);615 }616 i = null;617 }618 619 //displays the order on screen620 display() {621 622 for(var i = 0; i < this.length; i++) {623 624 //color the arrows625 if(this.index > i) {626 fill(150,190,225,100+50*cos(10*t));627 }628 else if(this.index < i) {629 fill(150,150,150,100);630 }631 else {632 fill(255,255,255,150+75*cos(10*t));633 }634 635 //draw several arrows representing the sequence636 drawArrow(i*2*width/(3*(this.length-1))+width/6,height/2,width/30,this.order[i]*PI/2);637 638 }639 }640 641 //checks new input against ordering642 update(state) {643 if(wallStates[this.order[this.index]] != state) {644 this.lifespan /= 2;645 this.attempts_left--;646 fill(255,100,100);647 drawArrow((this.index)*2*width/(3*(this.length-1))+width/6,height/2,width/15,this.order[this.index]*PI/2)648 }649 else {650 this.index++;651 this.lifespan += 10;652 this.attempts_left += 2;653 if( this.index >= this.length ) {654 this.complete();655 }656 }657 }658 659 //check if sequence is expired660 check_age() {661 if(t - this.birth > this.lifespan || this.attempts_left <= 0) {662 this.finish();663 }664 }665 666 //when sequence is cleared, push some random powerup onto the active powerups667 complete() {668 669 p1 += round(this.length/2.5);670 this.determine();671 /*fill(150,160,240,30);672 for(var i = 0; i < this.length; i++) {673 drawArrow(i*2*width/(3*(this.length-1))+width/6,height/2,width/8,this.order[i]*PI/2)674 }*/675 fill(255);676 textSize(48);677 text(this.choice.text, width/2, height/2, width, height);678 active_powerups.push(new PowerEffect(this.choice));679 this.finish();680 681 }682 683 // basically, rolls some chances to select which powerup is instantiated684 determine() {685 686 var powerup_prob_array = [];687 var powerup_choice;688 689 //decides if power will be neutral instead of biased690 //either way, takes the powerup entries from the object and creates a temp array of them691 if(random(0.0, 1.0) <= power.n_chance) {692 powerup_prob_array = Object.keys(power.neutral);693 this.choice = power.neutral;694 this.neutral = true;695 }696 else {697 powerup_prob_array = Object.keys(power.wall);698 this.choice = power.wall;699 }700 701 //sets each element in that array to be the defined probability of rolline the powerup, at the given index702 for (var powerup_i in powerup_prob_array) {703 powerup_prob_array[powerup_i] = this.choice[powerup_i].prob;704 }705 //uses a weighted dice roll to determine the chosen power706 powerup_choice = probability(powerup_prob_array);707 this.choice = this.choice[powerup_choice];708 709 powerup_prob_array = null;710 powerup_choice = null;711 712 }713 714 //deallocator715 finish() {716 sequence_exists = false;717 this.birth = null;718 this.lifespan = null;719 this.length = null720 this.order = null;721 this.index = null;722 this.neutral = null;723 this.choice = null;724 this.max_attempts = null;725 this.attempts_left = null;726 }727 728}729//framework for powerup effects730class PowerEffect {731 732 constructor(power) {733 this.power = power //power object734 this.power.pushEffect();735 this.expiry = this.power.duration + t;736 }737 738 //check if power up effect has expired, and undo effect if so739 update() {740 if ( t > this.expiry ) {741 this.power.popEffect();742 this.finish();743 return true;744 }745 return false;746 }747 748 //deallocator...
game.js
Source: game.js
...36 $scope.Status.utility -= 1;37 //Activate passive effect38 if($scope.selectedHexaForPurchase.type == 2 && !$scope.selectedHexaForPurchase.active) {39 $scope.Grid.getGrid().getAffectedSlots(slot).forEach(function(affectedSlot) {40 pushEffect(affectedSlot, slot);41 });42 }43 $scope.canContinuePurchase();44 }45 }46 }47 $scope.sellSlot = function(slot) {48 if(slot.hexaEntity.hexa.type == Hexa.TYPE.DPS) {49 $scope.Status.addCredit(slot.hexaEntity.sellPrice());50 } else if(slot.hexaEntity.hexa.type == Hexa.TYPE.UTILITY) {51 $scope.Status.utility += 1;52 }53 removeEffectOfSlot(slot);54 slot.hexaEntity = undefined;55 }56 var removeEffectOfSlot = function(slot, grid) {57 if(grid == null) {58 grid = $scope.Grid.getGrid();59 }60 grid.getAffectedSlots(slot).forEach(function(affectedSlot) {61 affectedSlot.effects.forEach(function(affectingSlot, index){62 if(affectingSlot.id == slot.id) {63 affectedSlot.effects.splice(index, 1);64 }65 });66 });67 }68 $scope.highlight = function(slot) {69 $scope.Grid.getGrid().getAffectedSlots(slot).forEach(function(highlightedSlot) {70 $scope.highlighted.push(highlightedSlot.id);71 });72 }73 $scope.activateSlot = function(activatedSlot) {74 if(activatedSlot.hexaEntity.hexa.active && activatedSlot.hexaEntity.cooldown == 0) {75 var affected = activatedSlot.getAffectedPositions();76 affected.forEach(function(position) {77 var slot = $scope.Grid.getGrid().getSlotByPos(position);78 if(slot != undefined) {79 pushEffect(slot, activatedSlot);80 }81 });82 activatedSlot.hexaEntity.activateTimers();83 }84 }85 $scope.upgradeSlot = function(slot) {86 if($scope.Status.credit >= slot.hexaEntity.calcUpgrade()) {87 $scope.Status.credit -= slot.hexaEntity.calcUpgrade();88 slot.hexaEntity.upgrade();89 }90 }91 $scope.clearHighlight = function() {92 $scope.highlighted = [];93 }94 $scope.highlighted = [];95 $scope.selectedPurchaseList = 1;96 $scope.click = function() {97 $scope.Progress.currentLevel.dealDamage(5 + $scope.Grid.getGrid().getDPS() * 0.1);98 }99 $scope.toggleProgress = function() {100 $scope.Progress.progressMode = !$scope.Progress.progressMode;101 }102 $scope.canContinuePurchase = function() {103 if($scope.Grid.getGrid().emptySlotCount($scope.Status.tier) == 0104 || ($scope.selectedHexaForPurchase.type == Hexa.TYPE.DPS && $scope.Status.credit < $scope.selectedHexaForPurchase.price)105 || ($scope.selectedHexaForPurchase.type == Hexa.TYPE.UTILITY && $scope.Status.utility < 1)) {106 $scope.selectedHexaForPurchase = undefined;107 }108 }109 $scope.checkAchievedHexas = function() {110 var hexas = $scope.Data.getHexas(Hexa.TYPE.DPS);111 hexas.forEach(function(hexa, index) {112 if(index + 1 != hexas.length && hexa.price <= $scope.Status.credit && $scope.Status.achievedHexas.indexOf(hexas[index + 1].id) == -1) {113 console.log("Achieved hexa: ", hexa.id);114 $scope.Status.achievedHexas.push(hexas[index + 1].id);115 }116 });117 }118 $scope.checkUtility = function() {119 if($scope.Progress.maxLevel == $scope.Progress.currentLevel.level120 && $scope.Progress.currentLevel.level % 10 == 0) {121 $scope.Status.utility += $scope.Grid.grids.length;122 }123 }124 $scope.$on('kill', function(event) {125 console.log('onKill');126 $scope.Status.addCredit($scope.Progress.currentLevel.credit);127 $scope.checkAchievedHexas();128 $scope.checkUtility();129 });130 $scope.$on('purchase', function(event, hexa) {131 console.log('onPurchase', hexa);132 $scope.selectedHexaForPurchase = hexa;133 });134 $scope.$on('changelevel', function(event, level) {135 switch(level) {136 case 30:137 $scope.Status.tier = 2;138 break;139 case 60:140 $scope.Status.tier = 3;141 break;142 }143 });144 $scope.$on('gridchange', function(event) {145 $scope.selectedHexaForPurchase = undefined;146 $scope.selectedSlot = undefined;147 });148 //DPS149 var dpsTimestamp = Date.now();150 var dpsInterval = $interval(function(){151 $scope.Progress.currentLevel.dealDamage($scope.Grid.getDPS(true) * ((Date.now() - dpsTimestamp) / 1000));152 dpsTimestamp = Date.now();153 },100);154 var timerInterval = $interval(function(){155 $scope.Grid.grids.forEach(function(grid) {156 grid.slots.forEach(function(slot){157 if(slot.hexaEntity) {158 if(slot.hexaEntity.cooldown > 0) {159 slot.hexaEntity.cooldown--;160 }161 if(slot.hexaEntity.duration > 0) {162 slot.hexaEntity.duration--;163 if(slot.hexaEntity.duration == 0) {164 removeEffectOfSlot(slot, grid);165 }166 }167 }168 });169 });170 },1000);171 $scope.saveGame = function(){172 var saveObj = {};173 //------174 saveObj.credit = $scope.Status.credit;175 saveObj.utility = $scope.Status.utility;176 saveObj.currentLevel = $scope.Progress.currentLevel.level;177 saveObj.maxLevel = $scope.Progress.maxLevel;178 saveObj.kills = $scope.Progress.currentLevel.kills;179 saveObj.currentHp = $scope.Progress.currentLevel.currentHp;180 saveObj.progressMode = $scope.Progress.progressMode;181 saveObj.achievedHexas = $scope.Status.achievedHexas;182 if($scope.Progress.currentLevel.bossTimer) {183 saveObj.bossTimer = $scope.Progress.currentLevel.bossTimer.time;184 }185 saveObj.tier = $scope.Status.tier;186 var grids = [];187 $scope.Grid.grids.forEach(function(grid) {188 var gridsave = { slots: []};189 grid.slots.forEach(function(slot) {190 var slotsave = { effects: [] };191 if(slot.hexaEntity) {192 slotsave.hexaEntity = {hexaId: slot.hexaEntity.hexa.id, level: slot.hexaEntity.level,193 cooldown: slot.hexaEntity.cooldown, duration: slot.hexaEntity.duration};194 }195 slot.effects.forEach(function(effectslot) {196 slotsave.effects.push(effectslot.id);197 })198 gridsave.slots.push(slotsave);199 });200 grids.push(gridsave);201 })202 saveObj.grids = grids;203 //------204 //console.log("Save: ", saveObj);205 window.localStorage.setItem("hexaclickersave", JSON.stringify(saveObj));206 window.localStorage.setItem("hexaclickersaveversion", $scope.SAVE_VERSION);207 }208 $scope.loadGame = function(){209 var saveVersion = window.localStorage.getItem("hexaclickersaveversion");210 //REWARD211 $scope.rewardOldPlayers(saveVersion);212 var saveObj = JSON.parse(window.localStorage.getItem("hexaclickersave"));213 if(saveObj != undefined && saveVersion != undefined && saveVersion >= $scope.SAVE_VERSION) {214 console.log("LOAD: ", saveObj);215 $scope.Status.credit = saveObj.credit;216 $scope.Status.utility = saveObj.utility;217 $scope.Progress.setLevel(saveObj.currentLevel);218 $scope.Progress.maxLevel = saveObj.maxLevel;219 $scope.Progress.currentLevel.kills = saveObj.kills;220 $scope.Progress.currentLevel.currentHp = saveObj.currentHp;221 $scope.Progress.progressMode = saveObj.progressMode;222 $scope.Status.achievedHexas = saveObj.achievedHexas;223 if(saveObj.bossTimer) {224 $scope.Progress.currentLevel.startBossTimer(saveObj.bossTimer);225 }226 $scope.Status.tier = saveObj.tier;227 if(saveObj.grids.length > 1) {228 for(var i = 0; i < saveObj.grids.length - 1; i++) {229 $scope.Grid.createGrid();230 }231 }232 saveObj.grids.forEach(function(gridsave, gindex){233 gridsave.slots.forEach(function(slotsave, sindex) {234 var slot = $scope.Grid.grids[gindex].slots[sindex];235 if(slotsave.hexaEntity) {236 slot.hexaEntity = new HexaEntity($scope.Data.getHexa(slotsave.hexaEntity.hexaId));237 slot.hexaEntity.level = slotsave.hexaEntity.level;238 slot.hexaEntity.cooldown = slotsave.hexaEntity.cooldown;239 slot.hexaEntity.duration = slotsave.hexaEntity.duration;240 }241 slotsave.effects.forEach(function(id) {242 pushEffect(slot, $scope.Grid.grids[gindex].slots[id]);243 });244 });245 });246 } else {247 console.log('NO SAVE FOUND');248 }249 }250 $scope.SAVE_VERSION = 3;251 $scope.prettify = function(number) {252 return prettify(number);253 }254 var saveInterval = $interval(function(){255 $scope.saveGame();256 }, 1000);...
ReactFiberHooks.js
Source: ReactFiberHooks.js
...134 return workInProgressHook;135}136137// effect对象ä¿åå¨fiber.updateQueue.lastEffect é¾è¡¨138function pushEffect(tag, create, destroy, deps) {139 const effect = {140 tag,141 create,142 destroy,143 deps,144 // ç¯145 next: null146 };147 let componentUpdateQueue = currentlyRenderingFiber.updateQueue;148 if (!componentUpdateQueue) {149 componentUpdateQueue = createFunctionComponentUpdateQueue();150 currentlyRenderingFiber.updateQueue = componentUpdateQueue;151 componentUpdateQueue.lastEffect = effect.next = effect;152 } else {153 const firstEffect = componentUpdateQueue.lastEffect.next;154 componentUpdateQueue.lastEffect.next = effect;155 effect.next = firstEffect;156 componentUpdateQueue.lastEffect = effect;157 }158 return effect;159}160161function areHookInputsEqual(nextDeps, prevDeps) {162 if (prevDeps === null) {163 return false;164 }165 if (nextDeps.length !== prevDeps.length) {166 console.error('åådepsé¿åº¦ä¸ä¸è´');167 }168 for (let i = 0; i < prevDeps.length && i < nextDeps.length; i++) {169 if (Object.is(nextDeps[i], prevDeps[i])) {170 continue;171 }172 return false;173 }174 return true;175}176177// ä¼ ç»useStateç第äºä¸ªåæ°ï¼å¯ä»¥æ¥å å¼ æ åè°å½æ° ä½ä¸ºåæ°178function basicStateReducer(state, action) {179 return typeof action === 'function' ? action(state) : action;180}181182function mountState(initialState) {183 return mountReducer(basicStateReducer, initialState)184}185186function mountReducer(reducer, initialArg, init) {187 const hook = mountWorkInProgressHook();188 let initialState;189 if (init !== undefined) {190 initialState = init(initialArg);191 } else {192 initialState = initialArg;193 }194 hook.memoizedState = hook.baseState = initialState;195196 //queue ç¨äºå¤æ¬¡æ´æ°åä¸ä¸ªhook197 const queue = (hook.queue = {198 pending: null,199 dispatch: null,200 lastRenderedReducer: reducer,201 lastRenderedState: initialState,202 });203 const dispatch = (queue.dispatch = (dispatchAction.bind(204 null,205 currentlyRenderingFiber,206 queue,207 )));208 return [hook.memoizedState, dispatch];209}210211function updateState(initialState) {212 return updateReducer(basicStateReducer, initialState)213}214215function updateReducer(reducer) {216 let hook = updateWorkInProgressHook();217 let queue = hook.queue || {}218 queue.lastRenderedReducer = reducer;219220 let pendingQueue = queue.pending;221 let baseQueue = hook.baseQueue;222223 if (pendingQueue) {224 if (baseQueue) {225 // Merge the pending queue and the base queue.226 const baseFirst = baseQueue.next;227 const pendingFirst = pendingQueue.next;228 baseQueue.next = pendingFirst;229 pendingQueue.next = baseFirst;230 }231 hook.baseQueue = baseQueue = pendingQueue;232 queue.pending = null;233 }234235 if (baseQueue) {236 // éè¦æ´æ°state237 let first = baseQueue.next;238 let newState = hook.baseState;239 // let newBaseState;240 // let newBaseQueueFirst;241 // let newBaseQueueLast;242 let update = first;243 do {244 // TODO ä¼å
级å¤æ245 // TODO æ´æ°baseQueueçé»è¾246 const action = update.action;247 newState = reducer(newState, action);248 update = update.next;249 } while (update && update !== first)250251 hook.memoizedState = newState;252 hook.baseState = newState;253 hook.baseQueue = null;254 queue.lastRenderedState = newState;255 }256 const dispatch = queue.dispatch;257 return [hook.memoizedState, dispatch];258}259260function mountRef(initialValue) {261 const hook = mountWorkInProgressHook();262 const ref = { current: initialValue };263 hook.memoizedState = ref;264 return ref;265}266267function updateRef(initialValue) {268 const hook = updateWorkInProgressHook();269 return hook.memoizedState;270}271272273const HooksDispatcherOnUpdate = {274 useContext: readContext,275 useReducer: updateReducer,276 useState: updateState,277 useEffect(create, deps) {278 const hook = updateWorkInProgressHook();279 const nextDeps = deps === undefined ? null : deps;280 let destroy = undefined;281 if (currentHook) {282283 const prevEffect = currentHook.memoizedState;284 destroy = prevEffect.destroy;285 if (nextDeps !== null) {286 const prevDeps = prevEffect.deps;287 if (areHookInputsEqual(nextDeps, prevDeps)) {288 // depsç¸åï¼ä¸éè¦ä¸ºfiberå¢å effectTag289 pushEffect(HookPassive, create, destroy, nextDeps);290 return;291 }292 }293 }294295 // åådepsä¸åï¼å¢å effectTag296 currentlyRenderingFiber.effectTag |= UpdateEffect | PassiveEffect;297 hook.memoizedState = pushEffect(298 HookHasEffect | HookPassive,299 create,300 destroy,301 nextDeps302 );303 },304 useRef: mountRef305}306307const HooksDispatcherOnMount = {308 useContext: readContext,309 useReducer: mountReducer,310 useState: mountState,311 useEffect(create, deps) {312 const hook = mountWorkInProgressHook();313 const nextDeps = deps === undefined ? null : deps;314 //0b00000000100 0b01000000000 315 currentlyRenderingFiber.effectTag |= UpdateEffect | PassiveEffect;316 // æåeffect对象317 //0b001 0b100 = 0b101318 hook.memoizedState = pushEffect(319 HookHasEffect | HookPassive,320 create,321 undefined,322 nextDeps323 );324 },325 useRef: updateRef326}327328329export function renderWithHooks(workInProgress) {330331 const current = workInProgress.alternate332
...
streamContext.js
Source: streamContext.js
...58 posts: {59 value: [],60 _updatePost(promise) {61 setState((s) => ({ ...s, pending: true }));62 pushEffect([63 promise,64 (post) =>65 setState((s) => {66 const currentPosts = s.posts.value;67 let updatedPosts;68 if (s.posts.value.some((p) => p.id === post.id))69 updatedPosts = currentPosts.map((p) =>70 p.id === post.id ? post : p71 );72 else updatedPosts = [...currentPosts, post];73 return {74 ...s,75 pending: false,76 posts: { ...s.posts, value: updatedPosts },77 };78 }) || post,79 (error) => setState((s) => ({ ...s, pending: false, error })),80 ]);81 return promise;82 },83 of(id, hard = false) {84 const prefetch =85 !hard && this.value.filter((p) => Number(p.id) === Number(id));86 const promise = prefetch.length87 ? Promise.resolve(prefetch[0])88 : api.posts.of(id);89 return this._updatePost(promise);90 },91 add(post) {92 const promise = api.posts.add(post);93 setState((s) => ({ ...s, pending: true }));94 pushEffect([95 promise,96 (post) =>97 setState((s) => ({98 ...s,99 pending: false,100 posts: { ...this, value: [...this.value, post] },101 })) || post,102 printerr, // TODO103 ]);104 return promise;105 },106 remove(post) {107 const promise = api.posts.delete(post.id);108 setState((s) => ({ ...s, pending: true }));109 pushEffect([110 promise,111 () =>112 setState((s) => ({113 ...s,114 pending: false,115 posts: {116 ...this,117 value: remove(s.posts.value, (p) => p.id !== post.id),118 },119 })),120 printerr, // TODO121 ]);122 return promise;123 },124 vote(post, vote) {125 return this._updatePost(api.posts.vote(post.id, vote));126 },127 flag(post, reason, cancel) {128 return this._updatePost(api.posts.flag(post.id, reason, cancel));129 },130 hide(post) {131 return this._updatePost(api.posts.hide(post.id));132 },133 lock(post) {134 return this._updatePost(api.posts.lock(post.id));135 },136 watch(id, payload) {137 return this._updatePost(api.posts.watch(id, payload));138 },139 pollData(id) {140 return api.posts.pollData(id);141 },142 pollVote(postId, answerId) {143 /* Fixme, only update the necessary pollVote */144 const promise = api.posts.pollVote(postId, answerId);145 pushEffect([146 promise,147 ({ answers, userAnswer }) =>148 setState((s) => ({149 ...s,150 posts: {151 ...s.posts,152 value: s.posts.value.map((p) => {153 if (p.id === postId) return { ...p, answers, userAnswer };154 return p;155 }),156 },157 })),158 (error) => setState((s) => ({ ...s, error })),159 ]);160 return promise;161 },162 /* Comments */163 deleteComment(postId, commentId) {164 return api.posts165 .deleteComment(commentId)166 .then(() => this.of(postId, true));167 },168 flagComment(postId, commentId, reason, cancel) {169 return api.posts170 .flagComment(commentId, reason, cancel)171 .then(() => this.of(postId, true))172 },173 lockComment(postId, commentId) {174 return api.posts175 .lockComment(commentId)176 .then(() => this.of(postId, true));177 },178 hideComment(postId, commentId) {179 return api.posts180 .hideComment(commentId)181 .then(() => this.of(postId, true));182 },183 comment(post, comment) {184 return api.posts185 .comment(post.id, comment)186 .then((response) => this.of(post.id, true) || response);187 },188 reply(postId, commentId, reply) {189 return api.posts190 .reply(commentId, reply)191 .then((response) => this.of(postId, true) || response);192 },193 commentVote(postId, commentId, vote) {194 return api.posts195 .commentVote(commentId, vote)196 .then(() => this.of(postId, true));197 },198 },199 kind: {200 available: kinds,201 value: KIND.ALL,202 set(kind) {203 if (this.value === kind) return;204 setState((s) => ({205 ...s,206 pending: true,207 kind: { ...this, value: kind },208 }));209 },210 },211 order: {212 available: orders,213 value: ORDER.RANK.DESC,214 set(order) {215 setState((s) => ({216 ...s,217 pending: true,218 order: { ...this, value: order },219 }));220 },221 },222 tags: {223 available: [],224 value: [],225 add(tag) {226 if (this.value.includes(tag)) return;227 const tags = [...this.value, tag];228 setState((s) => ({229 ...s,230 pending: true,231 tags: { ...s.tags, value: tags },232 }));233 },234 remove(tag) {235 if (!this.value.includes(tag)) return;236 const tags = without(this.value, tag);237 setState((s) => ({238 ...s,239 pending: true,240 tags: { ...s.tags, value: tags },241 }));242 },243 set(tag) {244 const tags = tag instanceof Array ? tag : [tag];245 setState((s) => ({246 ...s,247 pending: true,248 tags: { ...s.tags, value: tags },249 }));250 },251 },252 keywords: {253 value: [],254 add(kw) {255 const keywords = [...this.value, kw];256 setState((s) => ({257 ...s,258 pending: true,259 keywords: { ...s.keywords, value: keywords },260 }));261 },262 remove(kw) {263 if (!this.value.includes(kw)) return;264 const keywords = without(state.keywords.value, kw);265 setState((s) => ({266 ...s,267 pending: true,268 keywords: { ...s.keywords, value: keywords },269 }));270 },271 },272 author: {273 value: null,274 set(author_id) {275 if (this.value === author_id) return;276 setState((s) => ({277 ...s,278 pending: true,279 author: { ...state.author, value: author_id },280 }));281 },282 },283 });284 useEffect(() => {285 // We need to avoid a race condition between the auth loading and our posts list,286 // the auth primes over posts as it may affect those. Therefore in the event the auth is loading,287 // we await for it to end loading288 if (auth.pending) return;289 pushEffect([290 api.posts.where(clean(query(state), true)),291 (posts) =>292 setState((s) => ({293 ...s,294 pending: false,295 posts: { ...s.posts, value: posts },296 })),297 (error) => setState((s) => ({ ...s, pending: false, error })),298 ]);299 }, [300 state.kind.value,301 state.order.value,302 state.tags.value,303 state.keywords.value,304 state.author.value,305 auth.pending,306 ]);307 /* Get the tags on first mount */308 useEffect(309 () =>310 pushEffect([311 setState((s) => ({ ...s, pending: true })) || api.tags(),312 ({ tags }) =>313 setState((state) => ({314 ...state,315 tags: { ...state.tags, available: tags },316 })),317 (error) => setState((s) => ({ ...s, error, pending: false })), // TODO318 ]),319 []320 );321 return (322 <StreamContext.Provider value={state}>{children}</StreamContext.Provider>323 );324}...
$id.js
Source: $id.js
1/* eslint-disable react/jsx-wrap-multilines,comma-dangle */2import React, { Component } from 'react';3import { connect, Link } from 'engine';4import { Table, Breadcrumb, Tooltip, Spin } from 'antd';5import { Auth } from 'hoc';6import { isAuthed, isGod } from 'utils/auth';7import { Layout } from 'components/layout';8import { applyTheme } from 'themes';9import ReportChart from '../components/ReportChart';10import styles from './$id.less';11const tc = applyTheme(styles);12@connect(({ app, reco }) => ({ app, reco }))13@Auth14export default class Reports extends Component {15 state = {16 pushEffect: [],17 datas: [],18 loading: true,19 };20 componentDidMount() {21 this.fetch();22 }23 // è·åæ°æ®24 fetch = () => {25 const { id } = this.props.match.params;26 this.props.dispatch({27 type: 'reco/getReport',28 payload: { projectId: [id] },29 }).then((data) => {30 this.setState({ pushEffect: data, datas: data[0].links, loading: false });31 });32 };33 // æ ¼å¼åæ¶é´34 resetTime = (time) => {35 if (time) {36 const formatFunc = (str) => {37 return str > 9 ? str : '0' + str;38 }39 const date2 = new Date(time);40 const year = date2.getFullYear();41 const mon = formatFunc(date2.getMonth() + 1);42 const day = formatFunc(date2.getDate());43 let hour = date2.getHours();44 const noon = hour >= 12 ? 'PM' : 'AM';45 hour = hour >= 12 ? hour - 12 : hour;46 hour = formatFunc(hour);47 const min = formatFunc(date2.getMinutes());48 const dateStr = year + '-' + mon + '-' + day + ' ' + noon + ' ' + hour + ':' + min;49 return dateStr;50 }51 };52 // 计ç®åç§ç53 computeRate = (a, b) => {54 if (a === 0 || b === 0) {55 return 0;56 } else {57 const rate = Math.round((parseInt(a, 10) * 100) / parseInt(b, 10));58 return `${rate}%`;59 }60 };61 render() {62 const { roles } = this.props.app;63 const { loading, pushEffect } = this.state;64 const { id } = this.props.match.params;65 const projectInfo = [{66 title: '项ç®å称',67 dataIndex: 'title',68 }, {69 title: 'å建æ¶é´',70 dataIndex: 'createTime',71 render: createTime => <span>{this.resetTime(createTime)}</span>,72 }, {73 title: 'å
å«è®ºææ°é',74 render: tasks => <span>{tasks.links.length}</span>,75 }, {76 title: 'é¢ææ¨éæ°é',77 dataIndex: 'query',78 render: (query) => {79 const data = JSON.parse(query);80 return data.parameters.size;81 }82 }];83 const resultsOverview = [{84 title: 'æ»åéé',85 dataIndex: 'statistic.all_send_count',86 className: isGod(roles) ? styles.show : styles.hidden,87 }, {88 title: 'æååé',89 dataIndex: 'statistic.success_send_count',90 }, {91 title: 'æå¼æ¬¡æ°',92 dataIndex: 'statistic.all_open_count',93 }, {94 title: 'æå¼äººæ°',95 dataIndex: 'statistic.unique_open_count',96 }, {97 title: 'é®ä»¶æå¼ç',98 render: text =>99 <Tooltip title="æå¼äººæ°é¤ä»¥é®ä»¶åéæ°">100 {this.computeRate(text.statistic.unique_open_count, text.statistic.success_send_count)}101 </Tooltip>,102 }, {103 title: 'ç¹å»æ¬¡æ°',104 dataIndex: 'statistic.all_click_count',105 }, {106 title: 'ç¹å»äººæ°',107 dataIndex: 'statistic.unique_click_count',108 }, {109 title: 'ç¹å»è·³è½¬ç',110 render: tasks =>111 <Tooltip title="ç¹å»äººæ°é¤ä»¥ç¹å»æ¬¡æ°">112 {this.computeRate(tasks.statistic.unique_click_count, tasks.statistic.unique_open_count)}113 </Tooltip>,114 },115 ];116 const pushEffects = [117 {118 title: 'æ¨é论æ',119 key: '1',120 render: tasks =>121 <a href={`${tasks.url}`}122 target="_blank"><span>{tasks.name}</span>123 </a>,124 width: 200,125 }, {126 title: 'ç¹å»æ¬¡æ°',127 dataIndex: 'statistic.all_click_count',128 }, {129 title: 'ç¹å»äººæ°',130 key: '2',131 render: (record, tasks, index) => {132 const { id } = this.props.match.params;133 return (134 <Link to={`/reco/reports/view/${id}?n=${index}`} target="_blank">135 {tasks.statistic.unique_click_count}136 </Link>137 );138 }139 }, {140 title: 'ç¹å»ç',141 key: '3',142 render: (tasks) => {143 const allCount = tasks.statistic.unique_click_count;144 return (145 <span>146 {this.computeRate(allCount, pushEffect[0].statistic.unique_open_count)}147 </span>148 );149 }150 // TODO å 跳转é¾æ¥151 }];152 return (153 <Layout searchZone={[]} contentClass={tc(['indexPage'])} showNavigator={false}>154 <div className={styles.report}>155 <div className={styles.navbar}>156 <Breadcrumb separator=">">157 <Breadcrumb.Item href="/">项ç®å表</Breadcrumb.Item>158 <Breadcrumb.Item>æ¨éæ¥å</Breadcrumb.Item>159 </Breadcrumb>160 </div>161 <div className={styles.content}>162 <Spin spinning={loading}>163 <div className={styles.projectInfo}>164 <h4>æ¨é项ç®ä¿¡æ¯</h4>165 <Table rowKey={record => record.id} columns={projectInfo}166 dataSource={this.state.pushEffect}167 size="middle" />168 </div>169 <div className={styles.resultsOverview}>170 <h4>æææ»è§</h4>171 <Table rowKey={record => record.id} bordered columns={resultsOverview}172 dataSource={this.state.pushEffect} size="middle" />173 </div>174 <div className={styles.pushEffect}>175 <h4>论ææ¨éææ详æ
</h4>176 <Table rowKey={record => record.id} bordered columns={pushEffects}177 dataSource={this.state.datas}178 size="middle" />179 </div>180 </Spin>181 </div>182 <ReportChart projId={id} />183 </div>184 </Layout>185 );186 }...
authContext.js
Source: authContext.js
...23 if (state.user !== null)24 return;25 setState(s => ({ ...s, pending: true, error: null }));26 const promise = api.auth.login(email, password);27 pushEffect([28 promise,29 data => setState(s => ({30 ...s,31 pending: false,32 user: data.user,33 error: null,34 token: jwtDecode(data.accessToken)35 })) || data,36 error => setState(s => ({ ...s, pending: false, error }))37 ]);38 return promise;39 },40 logout() {41 const promise = api.auth.logout();42 pushEffect([43 promise,44 setState(s => ({ ...s, user: null, token: null, error: null })),45 error => setState(s => ({ ...s, error }))46 ]);47 return promise;48 },49 register(newUser) {50 if (this.user !== null)51 throw new AuthError('User already connected');52 return api.auth.register(newUser);53 }54 })55 useEffect(() => api.auth.session() && pushEffect([56 setState(s => ({ ...s, pending: true, error: null })) || api.auth.refresh(),57 data => setState(state => ({58 ...state,59 error: null,60 pending: false,61 user: data.user,62 token: jwtDecode(data.accessToken)63 })) || data,64 error => setState(state => ({ ...state, pending: false, error, user: null, token: null }))65 ]) || undefined, []);66 // Refresh loop67 useEffect(() => {68 if (!state.token) {69 if (state.timer)70 clearTimeout(state.timer) || setState(s => ({ ...s, timer: null }));71 return;72 }73 const expiration = new Date(state.token.exp * 1000);74 const now = new Date();75 const timer = setTimeout(() => pushEffect([76 api.auth.refresh(),77 data => setState(s => ({78 ...s,79 user: data.user,80 error: null,81 token: jwtDecode(data.accessToken)82 })),83 error => setState(s => ({ ...s, error, user: null, token: null }))84 ]), expiration - now);85 setState(s => ({ ...s, timer }));86 }, [state.token]);87 useDebugValue(state.user ? 'Connected' : 'Anonymous');88 return (89 <AuthContext.Provider value={state}>...
app.js
Source: app.js
...14 15 if (!audio) return;16 showImg(pushedKeyCode);17 playSound(audio);18 pushEffect(pushedKeyCode);19}20function removeEffect (event) {21 console.log(event);22 console.log('transition ended');23 if (event.propertyName == "transform") {24 this.classList.remove("playing"); // thisë ì´ë»ê² ëì¤ë ê±°ì§?25 // pushedKey.classList.remove("playing");26 }27};28function pushEffect (pushedKeyCode) {29 const pushedKey = document.querySelector(`div[data-key="${pushedKeyCode}"]`)30 pushedKey.classList.add("playing");31 const keys = document.querySelectorAll('.key');32 console.log(keys);...
effects.js
Source: effects.js
1const effects = {2 pushEffect: {3 name: "pushEffect",4 apply: function( entity, params )5 {6 if( params.actual === undefined)7 {8 params.actual = {x: entity.position.x, y: entity.position.y};9 params.actualStartTime = Game.getTime();10 }11 let deltaX = params.target.x - params.actual.x;12 let deltaY = params.target.y - params.actual.y;13 let progress = Math.min((Game.getTime() - params.actualStartTime) / params.duration, 1 );14 entity.position.x = params.actual.x + deltaX * progress;15 entity.position.y = params.actual.y + deltaY * progress;16 if(progress === 1)17 {18 entity.lastPosTime = params.actualStartTime + params.duration;19 entity.lastX = entity.targetX = params.target.x;20 entity.lastY = entity.targetY = params.target.y;21 return false;22 }23 return true;24 }25 }...
Using AI Code Generation
1const { chromium } = require('playwright');2(async () => {3 const browser = await chromium.launch();4 const context = await browser.newContext();5 const page = await context.newPage();6 await page.pushEffect('dark');7 await page.screenshot({ path: 'dark.png' });8 await browser.close();9})();10const { chromium } = require('playwright');11(async () => {12 const browser = await chromium.launch();13 const context = await browser.newContext();14 const page = await context.newPage();15 await page.pushEffect('light');16 await page.screenshot({ path: 'light.png' });17 await browser.close();18})();
Using AI Code Generation
1const { chromium } = require('playwright');2(async () => {3 const browser = await chromium.launch();4 const context = await browser.newContext();5 const page = await context.newPage();6 await page.pushEffect('highlight', { selector: 'text=Get started' });7 await page.screenshot({ path: `example.png` });8 await browser.close();9})();10const { chromium } = require('playwright');11(async () => {12 const browser = await chromium.launch();13 const context = await browser.newContext();14 const page = await context.newPage();15 await page.pushEffect('screenshot', { path: `example.png` });16 await browser.close();17})();18const { chromium } = require('playwright');19(async () => {20 const browser = await chromium.launch();21 const context = await browser.newContext();22 const page = await context.newPage();23 await page.pushEffect('trace', { path: `trace.json` });24 await browser.close();25})();26const { chromium } = require('playwright');27(async () => {28 const browser = await chromium.launch();29 const context = await browser.newContext();30 const page = await context.newPage();31 await page.pushEffect('trace-snapshot', { path: `trace-snapshot.json` });32 await browser.close();33})();34const { chromium } = require('playwright');35(async () => {36 const browser = await chromium.launch();37 const context = await browser.newContext();38 const page = await context.newPage();39 await page.pushEffect('video', { path: `video.mp4` });40 await browser.close();41})();42const { chromium } = require('playwright');
Using AI Code Generation
1const { chromium } = require('playwright');2(async () => {3 const browser = await chromium.launch();4 const context = await browser.newContext();5 const page = await context.newPage();6 await page.pushEffect('darkmode', 'true');7 await page.screenshot({ path: 'darkmode.png' });8 await browser.close();9})();
Using AI Code Generation
1const {chromium} = require('playwright');2(async () => {3 const browser = await chromium.launch();4 const context = await browser.newContext();5 const page = await context.newPage();6 await page.evaluate(() => {7 window.playwrightInternal.pushEffect({8 effect: async () => {9 console.log('My effect is running');10 },11 });12 });13 await page.waitForTimeout(5000);14 await browser.close();15})();16const {chromium} = require('playwright');17(async () => {18 const browser = await chromium.launch();19 const context = await browser.newContext();20 const page = await context.newPage();21 await page.evaluate(() => {22 window.playwrightInternal.pushEffect({23 effect: async () => {24 console.log('My effect is running');25 },26 });27 });28 await page.waitForTimeout(5000);29 await browser.close();30})();31const {chromium} = require('playwright');32(async () => {33 const browser = await chromium.launch();34 const context = await browser.newContext();35 const page = await context.newPage();36 await page.evaluate(() => {37 window.playwrightInternal.pushEffect({38 effect: async () => {39 console.log('My effect is running');40 },41 });42 });43 await page.waitForTimeout(5000);44 await browser.close();45})();46const {chromium} = require('playwright');47(async () => {48 const browser = await chromium.launch();49 const context = await browser.newContext();50 const page = await context.newPage();
Using AI Code Generation
1const { chromium } = require("playwright");2(async () => {3 const browser = await chromium.launch();4 const context = await browser.newContext();5 const page = await context.newPage();6 await page.pushEffect("color", {7 });8 await page.screenshot({ path: "example.png" });9 await browser.close();10})();
Using AI Code Generation
1const { chromium } = require('playwright');2(async () => {3 const browser = await chromium.launch();4 const context = await browser.newContext();5 const page = await context.newPage();6 await page.pushEffect('darkMode', true);7 await page.screenshot({ path: `example.png` });8 await browser.close();9})();10{11 "scripts": {12 },13 "dependencies": {14 }15}
Using AI Code Generation
1const {chromium} = require('playwright');2(async () => {3 const browser = await chromium.launch();4 const page = await browser.newPage();5 await page.evaluate(() => {6 window.__playwright__internal__ = {7 pushEffect: (name, value) => {8 console.log(name, value);9 }10 };11 });12 await page.click('text=Learn more');13 await browser.close();14})();
Using AI Code Generation
1const { test, expect } = require('@playwright/test');2test('test', async ({ page }) => {3 await page.waitForSelector('input[name="q"]');4 await page.pushEffect('highlight', 'input[name="q"]', {5 });6 await page.type('input[name="q"]', 'Playwright');7 await page.waitForSelector('input[name="btnK"]');8 await page.pushEffect('highlight', 'input[name="btnK"]', {9 });10 await page.click('input[name="btnK"]');11});
Jest + Playwright - Test callbacks of event-based DOM library
firefox browser does not start in playwright
Is it possible to get the selector from a locator object in playwright?
How to run a list of test suites in a single file concurrently in jest?
Running Playwright in Azure Function
firefox browser does not start in playwright
This question is quite close to a "need more focus" question. But let's try to give it some focus:
Does Playwright has access to the cPicker object on the page? Does it has access to the window object?
Yes, you can access both cPicker and the window object inside an evaluate call.
Should I trigger the events from the HTML file itself, and in the callbacks, print in the DOM the result, in some dummy-element, and then infer from that dummy element text that the callbacks fired?
Exactly, or you can assign values to a javascript variable:
const cPicker = new ColorPicker({
onClickOutside(e){
},
onInput(color){
window['color'] = color;
},
onChange(color){
window['result'] = color;
}
})
And then
it('Should call all callbacks with correct arguments', async() => {
await page.goto(`http://localhost:5000/tests/visual/basic.html`, {waitUntil:'load'})
// Wait until the next frame
await page.evaluate(() => new Promise(requestAnimationFrame))
// Act
// Assert
const result = await page.evaluate(() => window['color']);
// Check the value
})
Check out the latest blogs from LambdaTest on this topic:
Native apps are developed specifically for one platform. Hence they are fast and deliver superior performance. They can be downloaded from various app stores and are not accessible through browsers.
One of the essential parts when performing automated UI testing, whether using Selenium or another framework, is identifying the correct web elements the tests will interact with. However, if the web elements are not located correctly, you might get NoSuchElementException in Selenium. This would cause a false negative result because we won’t get to the actual functionality check. Instead, our test will fail simply because it failed to interact with the correct element.
Smartphones have changed the way humans interact with technology. Be it travel, fitness, lifestyle, video games, or even services, it’s all just a few touches away (quite literally so). We only need to look at the growing throngs of smartphone or tablet users vs. desktop users to grasp this reality.
As part of one of my consulting efforts, I worked with a mid-sized company that was looking to move toward a more agile manner of developing software. As with any shift in work style, there is some bewilderment and, for some, considerable anxiety. People are being challenged to leave their comfort zones and embrace a continuously changing, dynamic working environment. And, dare I say it, testing may be the most ‘disturbed’ of the software roles in agile development.
LambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.
Get 100 minutes of automation test minutes FREE!!