Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"optimize:png": "find source/images -type f -name '*.png' -print0 | xargs -0 -n 1 -P 6 optipng",
"optimize": "run-p optimize:**",
"server": "pipenv run python network-api/manage.py runserver",
"start": "npm i && npm run build-uncompressed && run-p server watch:**",
"start": "npm i && run-p build-uncompressed server watch:**",
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mostly a dev Quality of Life change - this starts the server way earlier, so you can just reload the tab once webpack finishes the build, instead of getting a "server not found" for like... a minute

"snyk": "snyk test --file=package.json",
"test:procfile": "node test/test-procfile.js",
"test:eslint": "eslint --config ./.eslintrc.yaml \"source/js/**/*.js\" \"source/js/**/*.jsx\" webpack.config.js",
Expand Down
48 changes: 39 additions & 9 deletions source/js/buyers-guide/homepage-c-slider.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,28 @@
import CREEPINESS_LABELS from "./components/creepiness-labels.js";

// Height of a single frame, see the
// ".current-creepiness" rule in homagepage.sccs
const creepStep = 70;
// Height of a single frame in the emoji sprite sheet,
// see the ".current-creepiness" rule in homagepage.sccs
const EMOJI_FRAME_HEIGHT = 70;

// Total number of frames in our sprite sheet,
// see the "./source/images/buyers-guide/faces/sprite.png" file
const totalSteps = 40;
// Total number of frames in our sprite sheet, see the
// "./source/images/buyers-guide/faces/sprite.png" file.
const SPRITE_FRAME_COUNT = 40;

// Our threshold value for which average creepiness ratings
// still count as "happy face" for the purpose of showing
// the emoji while scrolling.
//
// Note: this is a cosmetic value for scroll only.
const MINIMUM_HAPPINESS_RATING = 25;

// Our threshold value beyond which everything is super
// creepy by default.
//
// Note: this is a cosmetic value for scroll only.
const MAXIMUM_CREEPINESS_RATING = 80;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are MINIMUM_HAPPINESS_RATING and MAXIMUM_CREEPINESS_RATING both fixed values unrelated to EMOJI_FRAME_HEIGHT and SPRITE_FRAME_COUNT? If there's any relationship between them I think it's worth adding some inline comments in case we decide to change the values for frame height and frame count in the future.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is zero relation between the two sets of numbers.


// Helper function to determine whether products are
// in view, and so need to be considered for averaging.
function isElementInViewport(element) {
let rect = element.getBoundingClientRect();

Expand All @@ -19,6 +34,18 @@ function isElementInViewport(element) {
);
}

// map a value from one range to another
function map(v, s1,e1, s2,e2) {
return s2 + (v-s1) * (e2-s2) / (e1-s1);
}

// cap a value to a range
function cap(v, m, M) {
m = m || 0;
M = M || 100;
return v < m ? m : v > M ? M : v;
}

export default {
init: () => {
let face = document.querySelector(`.current-creepiness`);
Expand All @@ -40,15 +67,18 @@ export default {

let averageCreepiness = visible.reduce( (tally, v) => tally + parseFloat(v.dataset.creepiness)/n, 0);

// compress the value so that we show a smiley face even for products with a lowish creepiness score.
let mappedAverageCreepiness = cap(map(averageCreepiness, MINIMUM_HAPPINESS_RATING, MAXIMUM_CREEPINESS_RATING, 0, 100), 1, 100);

// The averageCreepiness will be in range [1,100] so we can dec1 the
// valueto make sure we're in frame range [0,frames.length-1]:
let frame = Math.round((totalSteps-1) * (averageCreepiness-1)/100);
let frame = Math.round((SPRITE_FRAME_COUNT-1) * (mappedAverageCreepiness-1)/100);

face.style.backgroundPositionY = `${-frame * creepStep}px`;
face.style.backgroundPositionY = `${-frame * EMOJI_FRAME_HEIGHT}px`;

// Figure out what the corresponding creepiness label should be:
let len = CREEPINESS_LABELS.length;
let bin = Math.floor(len * (averageCreepiness-1)/100);
let bin = Math.floor(len * (mappedAverageCreepiness-1)/100);

if (bin === -1) {
bubbleText.textContent = ``;
Expand Down