<div class="showcase">
<div class="circle"></div>
<div class="configure">
<pre>
<code class="javascript">
const circle = new DirectionAwareShadow({
target: '.circle',
blur: 30,
spread: 0,
offset: .8,
color: 'rgba(79, 1, 119, 0.46)',
inset: false,
reverse: false
});
circle.init();
</code>
</pre>
</div>
</div>
@import url('https://fonts.googleapis.com/css?family=Space+Mono:400,700&display=swap');* {
box-sizing: border-box;
}
* {
box-sizing: border-box;
}
body {
height: 100vh;
display: flex;
flex-direction: column;
background-image: linear-gradient( 90.7deg, rgba(255,253,218,1) 1.9%, rgba(246,210,255,1) 39.3%, rgba(152,222,254,1) 64.7%, rgba(251,255,210,1) 100.8% );
}
.circle {
width: 120px;
flex-shrink: 0;
margin-right: 50px;
height: 120px;
background-image: linear-gradient(43deg, #4158D0 0%, #C850C0 46%, #FFCC70 100%);
border-radius: 20px;
box-shadow: rgba(79, 1, 119, 0.36) 1.2px 22px 30px 0px;
position: relative;
}
.circle:before {
content: "";
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg fill='%23fff' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 502.019 502.019'%3e%3cpath d='M444.501 210.539l-17.676-40.206a88.404 88.404 0 00-3.385-6.878c-7.161-13.093-18.911-22.95-33.088-27.756a59.824 59.824 0 00-43.146 1.801l-8.412 3.658-15.823-35.992c-5.29-12.033-14.965-21.264-27.242-25.992-12.219-4.706-25.509-4.363-37.435.963l-23.937 10.37c-4.167-6.298-9.306-11.049-15.351-14.177-11.874-6.145-26.241-5.589-42.706 1.65l-17.777 7.815-21.639-49.223c-8.288-18.853-23.643-31.785-42.127-35.48-17.351-3.467-35.005 1.43-47.234 13.101-18.429 17.587-23.724 43.993-13.5 67.251l80.667 184.65c-24.236-5.899-52.415-1.223-68.77 13.384-.664.417-1.288.919-1.857 1.504-10.81 11.134-16.141 24.582-15.416 38.889.911 18.004 11.266 35.818 29.943 51.516.082.069.165.137.249.203l162.998 128.287a9.999 9.999 0 0010.209 1.296l233.508-102.652a9.998 9.998 0 005.956-8.531l1.271-20.347c3.39-54.289-6.388-109.307-28.28-159.104zm8.319 157.858l-.891 14.267-222.438 97.785L71.339 355.976c-14.24-12.003-22.096-24.836-22.718-37.116-.407-8.047 2.353-15.514 8.208-22.226.381-.293.745-.616 1.09-.971 14.6-15.038 50.97-16.116 69.865-2.182l40.575 38.97a9.966 9.966 0 006.926 2.788 9.97 9.97 0 007.213-3.073c3.826-3.983 3.698-10.313-.285-14.139l-39.644-38.076L52.342 73.416c-8.261-18.79-.772-35.438 8.989-44.755 7.402-7.066 18.705-10.114 29.506-7.957 12.177 2.434 22.027 10.928 27.738 23.917l68.24 155.229a10 10 0 0013.179 5.13c5.056-2.223 7.353-8.123 5.13-13.179l-38.553-87.698 17.777-7.815c10.657-4.686 19.225-5.425 25.465-2.196 4.429 2.292 8.123 6.749 10.979 13.245l.001.002 40.244 91.546a10 10 0 009.159 5.978 9.962 9.962 0 004.02-.848c5.056-2.223 7.353-8.123 5.13-13.179l-36.198-82.342 23.15-10.029.115-.051c7.039-3.156 14.897-3.361 22.127-.577 7.267 2.799 12.992 8.26 16.121 15.377l47.828 108.795a10 10 0 009.159 5.978 9.962 9.962 0 004.02-.848c5.056-2.223 7.353-8.123 5.13-13.179l-23.956-54.492 8.339-3.627c19.022-8.271 40.822-.872 50.714 17.214a68.83 68.83 0 012.621 5.326l17.676 40.207c20.612 46.888 29.819 98.691 26.628 149.809z'/%3e%3cpath d='M405.593 366.776l-11.595 5.085c-5.058 2.218-7.36 8.116-5.142 13.174a10.002 10.002 0 009.163 5.986 9.967 9.967 0 004.012-.845l11.595-5.085c5.058-2.218 7.36-8.116 5.142-13.174-2.22-5.059-8.119-7.358-13.175-5.141zM358.824 387.551l-123.826 54.31c-5.058 2.218-7.36 8.116-5.142 13.174a10.002 10.002 0 009.163 5.986 9.967 9.967 0 004.012-.845l123.826-54.31c5.058-2.218 7.36-8.116 5.142-13.174-2.22-5.058-8.12-7.359-13.175-5.141z'/%3e%3c/svg%3e");
background-size: 46px;
background-repeat: no-repeat;
background-position: center;
}
.showcase {
max-width: 640px;
margin: auto;
display: flex;
width: 100%;
padding: 30px;
align-items: center;
flex-wrap: wrap;
border-radius: 20px;
}
.hljs {
font-family: 'Space Mono', monospace;
font-size: 14px;
padding: 0 26px;
border-radius: 18px;
flex: 1;
overflow: auto;
line-height: 1.6;
}
pre {
margin: 0;
display: flex;
}
.configure {
flex: 1;
overflow: hidden;
}
View Compiled
class DirectionAwareShadow {
constructor({
target = null,
blur = 0,
spread = 0,
inset = false,
reverse = false,
color = 'currentColor',
offset = 1
} = {}) {
this.target = target ? document.querySelectorAll(target) : target;
this.blur = blur;
this.inset = inset;
this.spread = spread;
this.reverse = reverse;
this.color = color;
this.offset = offset;
}
move() {
this.target.forEach(t =>
t.addEventListener('mousemove', e => this.calc(e))
);
}
px(val) {
return `${val}px`;
}
calc(e) {
const { currentTarget, offsetX, offsetY } = e;
const { offsetHeight, offsetWidth } = currentTarget;
const { color, reverse, offset } = this;
const blur = this.px(this.blur);
const spread = this.px(this.spread);
const inset = this.inset ? 'inset' : '';
const x = ((offsetWidth / 2 - offsetX) * offset) / 2;
const y = ((offsetHeight / 2 - offsetY) * offset) / 2;
const h = this.px(!reverse ? x : x * -1);
const v = this.px(!reverse ? y : y * -1);
currentTarget.style.boxShadow = `${h} ${v} ${blur} ${spread} ${color} ${inset}`;
}
init() {
if (!this.target) {
console.error('[direction-aware shadow] • you should add a target')
return;
}
this.move();
}
}
const circle = new DirectionAwareShadow({
target: '.circle',
blur: 30,
spread: 0,
offset: .8,
color: 'rgba(79, 1, 119, 0.36)',
inset: false,
reverse: false
});
circle.init();
hljs.initHighlightingOnLoad();
View Compiled