Skip to content
This repository was archived by the owner on Jan 12, 2025. It is now read-only.
/ medium Public archive

Connect CSS and JS worlds with custom properties

License

Notifications You must be signed in to change notification settings

sfi0zy/medium

Repository files navigation

Medium

Connect CSS and JS worlds.

This tool adds CSS custom properties with the current mouse position, scroll position, time, random values etc.

NPM

npm install css.medium.js

CDN

import Medium from 'https://unpkg.com/css.medium.js@1.2.0/css.medium.js';

Usage

JS

Import the library and choose features to use:

import Medium from 'css.medium.js';

const medium = new Medium({
    // All features are disabled by default
    features: {
        xy: true,
        scroll: true,
        time: true,
        random: true,
        math: true,
    },
});

CSS

Use various values from the JS world through CSS custom properties (see the list of the available properties below):

#scroll-indicator {
    transform: scaleX(var(--js-scroll-y-normalized));
}

#cursor {
    transform:
        translateX(var(--js-mouse-x))
        translateY(var(--js-mouse-y));
}

#target {
    transform:
        perspective(10rem)
        rotateY(calc(1deg * var(--js-mouse-relative-cx-normalized)))
        rotateX(calc(-1deg * var(--js-mouse-relative-cy-normalized)));
}

Live example

See live example of how it works:

https://sfi0zy.github.io/medium/

More examples on CodePen:

https://codepen.io/collection/wamGwK

Global CSS custom properties

These custom properties will be added to document.body and will be updated if needed:

Feature: xy

Name Expected values
--js-window-width from 0px to a few thousand px
--js-window-height from 0px to a few thousand px
--js-mouse-x from 0px to window width
--js-mouse-y from 0px to window height
--js-mouse-cx from -(window width / 2) to (window width / 2)
--js-mouse-cy from -(window height / 2) to (window height / 2)
--js-mouse-cd from 0px to (window diagonal / 2)
--js-mouse-x-normalized from 0 to 1
--js-mouse-y-normalized from 0 to 1
--js-mouse-cx-normalized from -1 at the left border to 1 at the right border
--js-mouse-cy-normalized from -1 at the top border to 1 at the bottom border
--js-mouse-cd-normalized from 0 in the center to 1 at the window corner

Feature: scroll

Name Expected values
--js-scroll-y from 0px to a few thousand px
--js-scroll-y-normalized from 0 to 1 at the end of the scroll

Feature: time

Name Expected values
--js-time-s from 0 to Infinity
--js-time-ms from 0 to Infinity

Feature: random

Name Expected values
--js-random-0 from 0 to 1
--js-random-1 same as random-0, all the way to random-99

Feature: math

Name Expected values
--js-math-pi 3.14159

Targets (optional)

By default, all coordinates will be calculated from the top left corner of the window and its center. We can mark a few elements with data-medium-target attribute to add relative coordinates to them as well:

<div data-medium-target>...</div>

Targets will get additional local properties for xy feature:

Name
--js-target-width
--js-target-height
--js-mouse-relative-x
--js-mouse-relative-y
--js-mouse-relative-cx
--js-mouse-relative-cy
--js-mouse-relative-cd
--js-mouse-relative-x-normalized
--js-mouse-relative-y-normalized
--js-mouse-relative-cx-normalized
--js-mouse-relative-cy-normalized
--js-mouse-relative-cd-normalized

They have almost the same logic as the global CSS custom properties, but we use the size and the position of the target element instead of the window in our calculations.

Also, targets will get additional properties for scroll feature:

Name Expected values
--js-target-top from 0px to window height
--js-target-top-normalized from 0 at the top window border to 1 at the bottom
--js-target-cy from -(window height / 2) to (window height / 2)
--js-target-cy-normalized from -1 at the top window border to 1 at the bottom

Note: since target elements can be smaller than the viewport, the coordinates of the mouse can be outside of them sometimes. Because of that, normalized values for target elements aren't limited to the range from 0 to 1 or from -1 to 1. They are fitted to have values of 0 or 1 on the targets borders with the same logic as the global ones and the window borders. The top and cy values for targets are not limited to the viewport and can be outside of that range as well. We can clamp() all these values in CSS if it's required by design.

To activate more target elements later we can use the update method:

medium.update();

Development

git clone git@github.com:sfi0zy/medium.git
cd medium
make install # install local npm packages
make watch # work with browser-sync (you'll need inotifywatch)
make check # run eslint in console
make clean # delete installed packages if you don't need them anymore

License

MIT License

Copyright (c) 2023 Ivan Bogachev

About

Connect CSS and JS worlds with custom properties

Topics

Resources

License

Stars

Watchers

Forks