diff --git a/extensions/cornerstone/src/Viewport/Overlays/CornerstoneOverlays.tsx b/extensions/cornerstone/src/Viewport/Overlays/CornerstoneOverlays.tsx
index 43ec800c45..34970d5ffd 100644
--- a/extensions/cornerstone/src/Viewport/Overlays/CornerstoneOverlays.tsx
+++ b/extensions/cornerstone/src/Viewport/Overlays/CornerstoneOverlays.tsx
@@ -1,4 +1,5 @@
 import React, { useEffect, useState } from 'react';
+import { SmartScrollbar } from '@ohif/ui';
 
 import ViewportImageScrollbar from './ViewportImageScrollbar';
 import CustomizableViewportOverlay from './CustomizableViewportOverlay';
@@ -45,7 +46,7 @@ function CornerstoneOverlays(props: withAppTypes) {
 
   return (
     <div className="noselect">
-      <ViewportImageScrollbar
+      <SmartScrollbar
         viewportId={viewportId}
         viewportData={viewportData}
         element={element}
diff --git a/extensions/cornerstone/src/Viewport/Overlays/CustomizableViewportOverlay.css b/extensions/cornerstone/src/Viewport/Overlays/CustomizableViewportOverlay.css
index 9694fa4592..c0e8db541f 100644
--- a/extensions/cornerstone/src/Viewport/Overlays/CustomizableViewportOverlay.css
+++ b/extensions/cornerstone/src/Viewport/Overlays/CustomizableViewportOverlay.css
@@ -19,6 +19,7 @@ line, it will be truncated with ellipsis in the end.
 
 .viewport-overlay.right-viewport-scrollbar {
   text-align: right;
+  right: 1.7rem;
 }
 .viewport-overlay.right-viewport-scrollbar .flex.flex-row {
   justify-content: flex-end;
diff --git a/extensions/cornerstone/src/commandsModule.ts b/extensions/cornerstone/src/commandsModule.ts
index 69f51168a7..6b874125d9 100644
--- a/extensions/cornerstone/src/commandsModule.ts
+++ b/extensions/cornerstone/src/commandsModule.ts
@@ -21,6 +21,7 @@ import toggleImageSliceSync from './utils/imageSliceSync/toggleImageSliceSync';
 import { getFirstAnnotationSelected } from './utils/measurementServiceMappings/utils/selection';
 import getActiveViewportEnabledElement from './utils/getActiveViewportEnabledElement';
 import toggleVOISliceSync from './utils/toggleVOISliceSync';
+import shouldPreventScroll from './utils/shouldPreventScroll';
 
 const toggleSyncFunctions = {
   imageSlice: toggleImageSliceSync,
@@ -556,7 +557,7 @@ function commandsModule({
       const options = { imageIndex: jumpIndex };
       cstUtils.jumpToSlice(viewport.element, options);
     },
-    scroll: ({ direction }) => {
+    scroll: ({ direction, isSmartScrolling = false }) => {
       const enabledElement = _getActiveViewportEnabledElement();
 
       if (!enabledElement) {
@@ -566,6 +567,16 @@ function commandsModule({
       const { viewport } = enabledElement;
       const options = { delta: direction };
 
+      if (
+        shouldPreventScroll(
+          !isSmartScrolling,
+          viewport.getCurrentImageIdIndex() + direction,
+          servicesManager
+        )
+      ) {
+        return;
+      }
+
       cstUtils.scroll(viewport, options);
     },
     setViewportColormap: ({
diff --git a/extensions/cornerstone/src/index.tsx b/extensions/cornerstone/src/index.tsx
index e74a0de9ff..5a16c4573b 100644
--- a/extensions/cornerstone/src/index.tsx
+++ b/extensions/cornerstone/src/index.tsx
@@ -40,6 +40,7 @@ import getSOPInstanceAttributes from './utils/measurementServiceMappings/utils/g
 import { findNearbyToolData } from './utils/findNearbyToolData';
 import { createFrameViewSynchronizer } from './synchronizers/frameViewSynchronizer';
 import { getSopClassHandlerModule } from './getSopClassHandlerModule';
+import shouldPreventScroll from './utils/shouldPreventScroll';
 
 const { helpers: volumeLoaderHelpers } = csStreamingImageVolumeLoader;
 const { getDynamicVolumeInfo } = volumeLoaderHelpers ?? {};
@@ -209,6 +210,8 @@ const cornerstoneExtension: Types.Extensions.Extension = {
         exports: {
           toolNames,
           Enums: cs3DToolsEnums,
+          shouldPreventScroll: (keyPressed, imageIdIndex) =>
+            shouldPreventScroll(keyPressed, imageIdIndex, servicesManager),
         },
       },
       {
diff --git a/extensions/cornerstone/src/initCornerstoneTools.js b/extensions/cornerstone/src/initCornerstoneTools.js
index bfabc4a014..9a34a90acf 100644
--- a/extensions/cornerstone/src/initCornerstoneTools.js
+++ b/extensions/cornerstone/src/initCornerstoneTools.js
@@ -42,6 +42,8 @@ import {
 
 import CalibrationLineTool from './tools/CalibrationLineTool';
 import ImageOverlayViewerTool from './tools/ImageOverlayViewerTool';
+import SmartStackScrollMouseWheelTool from './tools/SmartStackScrollMouseWheelTool';
+import SmartStackScrollTool from './tools/SmartStackScrollTool';
 
 export default function initCornerstoneTools(configuration = {}) {
   CrosshairsTool.isAnnotation = false;
@@ -87,6 +89,8 @@ export default function initCornerstoneTools(configuration = {}) {
   addTool(OrientationMarkerTool);
   addTool(WindowLevelRegionTool);
   addTool(PlanarFreehandContourSegmentationTool);
+  addTool(SmartStackScrollMouseWheelTool);
+  addTool(SmartStackScrollTool);
 
   // Modify annotation tools to use dashed lines on SR
   const annotationStyle = {
@@ -142,6 +146,8 @@ const toolNames = {
   OrientationMarker: OrientationMarkerTool.toolName,
   WindowLevelRegion: WindowLevelRegionTool.toolName,
   PlanarFreehandContourSegmentation: PlanarFreehandContourSegmentationTool.toolName,
+  SmartStackScrollMouseWheel: SmartStackScrollMouseWheelTool.toolName,
+  SmartStackScroll: SmartStackScrollTool.toolName,
 };
 
 export { toolNames };
diff --git a/extensions/cornerstone/src/services/ToolGroupService/ToolGroupService.ts b/extensions/cornerstone/src/services/ToolGroupService/ToolGroupService.ts
index 298f28612d..6ad38e6bc3 100644
--- a/extensions/cornerstone/src/services/ToolGroupService/ToolGroupService.ts
+++ b/extensions/cornerstone/src/services/ToolGroupService/ToolGroupService.ts
@@ -252,8 +252,8 @@ export default class ToolGroupService {
     }
 
     if (passive) {
-      passive.forEach(({ toolName }) => {
-        toolGroup.setToolPassive(toolName);
+      passive.forEach(({ toolName, bindings }) => {
+        toolGroup.setToolPassive(toolName, { bindings });
       });
     }
 
diff --git a/extensions/cornerstone/src/tools/SmartStackScrollMouseWheelTool.ts b/extensions/cornerstone/src/tools/SmartStackScrollMouseWheelTool.ts
new file mode 100644
index 0000000000..58e91d845b
--- /dev/null
+++ b/extensions/cornerstone/src/tools/SmartStackScrollMouseWheelTool.ts
@@ -0,0 +1,29 @@
+import { getEnabledElement } from '@cornerstonejs/core';
+import { StackScrollMouseWheelTool, Types } from '@cornerstonejs/tools';
+
+class SmartStackScrollMouseWheelTool extends StackScrollMouseWheelTool {
+  parentMouseWheelCallback: (evt: Types.EventTypes.MouseWheelEventType) => void;
+
+  constructor(toolProps, defaultToolProps) {
+    super(toolProps, defaultToolProps);
+    this.parentMouseWheelCallback = this.mouseWheelCallback;
+    this.mouseWheelCallback = this.smartMouseWheelCallback;
+  }
+
+  smartMouseWheelCallback(evt: Types.EventTypes.MouseWheelEventType): void {
+    const { wheel, element } = evt.detail;
+    const { direction } = wheel;
+    const { invert, shouldPreventScroll } = this.configuration;
+    const { viewport } = getEnabledElement(element);
+    const delta = direction * (invert ? -1 : 1);
+
+    if (shouldPreventScroll(evt.detail.event.ctrlKey, viewport.getCurrentImageIdIndex() + delta)) {
+      return;
+    }
+
+    this.parentMouseWheelCallback(evt);
+  }
+}
+
+SmartStackScrollMouseWheelTool.toolName = 'SmartStackScrollMouseWheel';
+export default SmartStackScrollMouseWheelTool;
diff --git a/extensions/cornerstone/src/tools/SmartStackScrollTool.ts b/extensions/cornerstone/src/tools/SmartStackScrollTool.ts
new file mode 100644
index 0000000000..d94bf62e11
--- /dev/null
+++ b/extensions/cornerstone/src/tools/SmartStackScrollTool.ts
@@ -0,0 +1,32 @@
+import { getEnabledElementByIds } from '@cornerstonejs/core';
+import { StackScrollTool, Types } from '@cornerstonejs/tools';
+
+class SmartStackScrollTool extends StackScrollTool {
+  parentDragCallback: (evt: Types.EventTypes.InteractionEventType) => void;
+
+  constructor(toolProps, defaultToolProps) {
+    super(toolProps, defaultToolProps);
+    this.parentDragCallback = this._dragCallback;
+    this._dragCallback = this._smartDragCallback;
+  }
+
+  _smartDragCallback(evt: Types.EventTypes.InteractionEventType) {
+    const { deltaPoints, viewportId, renderingEngineId } = evt.detail;
+    const { viewport } = getEnabledElementByIds(viewportId, renderingEngineId);
+    const { invert, shouldPreventScroll } = this.configuration;
+    const deltaPointY = deltaPoints.canvas[1];
+    const pixelsPerImage = this._getPixelPerImage(viewport);
+    const deltaY = deltaPointY + this.deltaY;
+    const imageIdIndexOffset = Math.round(deltaY / pixelsPerImage);
+    const delta = invert ? -imageIdIndexOffset : imageIdIndexOffset;
+
+    if (shouldPreventScroll(evt.detail.event.ctrlKey, viewport.getCurrentImageIdIndex() + delta)) {
+      return;
+    }
+
+    return this.parentDragCallback(evt);
+  }
+}
+
+SmartStackScrollTool.toolName = 'SmartStackScroll';
+export default SmartStackScrollTool;
diff --git a/extensions/cornerstone/src/utils/shouldPreventScroll.ts b/extensions/cornerstone/src/utils/shouldPreventScroll.ts
new file mode 100644
index 0000000000..22c5a25e8a
--- /dev/null
+++ b/extensions/cornerstone/src/utils/shouldPreventScroll.ts
@@ -0,0 +1,18 @@
+export default function shouldPreventScroll(
+  keyPressed: boolean,
+  imageIdIndex: number,
+  servicesManager
+): boolean {
+  const { stateSyncService, viewportGridService } = servicesManager.services;
+  const { cachedSlicesPerSeries } = stateSyncService.getState();
+  const { activeViewportId, viewports } = viewportGridService.getState();
+  const cachedSlices = cachedSlicesPerSeries[
+    viewports.get(activeViewportId).displaySetInstanceUIDs[0]
+  ] as number[];
+
+  if (!cachedSlices) {
+    return false;
+  }
+
+  return !keyPressed && !cachedSlices.includes(imageIdIndex);
+}
diff --git a/extensions/default/src/init.ts b/extensions/default/src/init.ts
index 2e5e831c8e..613ac9b12d 100644
--- a/extensions/default/src/init.ts
+++ b/extensions/default/src/init.ts
@@ -61,6 +61,9 @@ export default function init({
   // afterwards.
   stateSyncService.register('viewportsByPosition', { clearOnModeExit: true });
 
+  // Stores the cached frames of each series so that we can prevent scrolling to a slice that is not cached
+  stateSyncService.register('cachedSlicesPerSeries', { clearOnModeExit: true });
+
   // Adds extra custom attributes for use by hanging protocols
   registerHangingProtocolAttributes({ servicesManager });
 
diff --git a/modes/longitudinal/src/initToolGroups.js b/modes/longitudinal/src/initToolGroups.js
index d50bf4fe9c..4634dbfd32 100644
--- a/modes/longitudinal/src/initToolGroups.js
+++ b/modes/longitudinal/src/initToolGroups.js
@@ -21,7 +21,7 @@ function initDefaultToolGroup(
     '@ohif/extension-cornerstone.utilityModule.tools'
   );
 
-  const { toolNames, Enums } = utilityModule.exports;
+  const { toolNames, Enums, shouldPreventScroll } = utilityModule.exports;
 
   const tools = {
     active: [
@@ -37,7 +37,11 @@ function initDefaultToolGroup(
         toolName: toolNames.Zoom,
         bindings: [{ mouseButton: Enums.MouseBindings.Secondary }],
       },
-      { toolName: toolNames.StackScrollMouseWheel, bindings: [] },
+      {
+        toolName: toolNames.SmartStackScrollMouseWheel,
+        bindings: [],
+        configuration: { shouldPreventScroll },
+      },
     ],
     passive: [
       { toolName: toolNames.Length },
@@ -71,7 +75,13 @@ function initDefaultToolGroup(
       { toolName: toolNames.EllipticalROI },
       { toolName: toolNames.CircleROI },
       { toolName: toolNames.RectangleROI },
-      { toolName: toolNames.StackScroll },
+      {
+        toolName: toolNames.SmartStackScroll,
+        bindings: [
+          { mouseButton: Enums.MouseBindings.Primary, modifierKey: Enums.KeyboardBindings.Ctrl },
+        ],
+        configuration: { shouldPreventScroll },
+      },
       { toolName: toolNames.Angle },
       { toolName: toolNames.CobbAngle },
       { toolName: toolNames.Magnify },
diff --git a/modes/longitudinal/src/moreTools.ts b/modes/longitudinal/src/moreTools.ts
index 3c4ca9310d..4c146fbb2c 100644
--- a/modes/longitudinal/src/moreTools.ts
+++ b/modes/longitudinal/src/moreTools.ts
@@ -96,7 +96,7 @@ const moreTools = [
           evaluate: 'evaluate.cornerstoneTool.toggle',
         }),
         createButton({
-          id: 'StackScroll',
+          id: 'SmartStackScroll',
           icon: 'tool-stack-scroll',
           label: 'Stack Scroll',
           tooltip: 'Stack Scroll',
diff --git a/modes/segmentation/src/initToolGroups.ts b/modes/segmentation/src/initToolGroups.ts
index babfe4a113..e75891a5d7 100644
--- a/modes/segmentation/src/initToolGroups.ts
+++ b/modes/segmentation/src/initToolGroups.ts
@@ -11,13 +11,17 @@ const colorsByOrientation = {
 };
 
 function createTools(utilityModule) {
-  const { toolNames, Enums } = utilityModule.exports;
+  const { toolNames, Enums, shouldPreventScroll } = utilityModule.exports;
   return {
     active: [
       { toolName: toolNames.WindowLevel, bindings: [{ mouseButton: Enums.MouseBindings.Primary }] },
       { toolName: toolNames.Pan, bindings: [{ mouseButton: Enums.MouseBindings.Auxiliary }] },
       { toolName: toolNames.Zoom, bindings: [{ mouseButton: Enums.MouseBindings.Secondary }] },
-      { toolName: toolNames.StackScrollMouseWheel, bindings: [] },
+      {
+        toolName: toolNames.SmartStackScrollMouseWheel,
+        bindings: [],
+        configuration: { shouldPreventScroll },
+      },
     ],
     passive: [
       {
@@ -84,7 +88,13 @@ function createTools(utilityModule) {
       { toolName: toolNames.CircleScissors },
       { toolName: toolNames.RectangleScissors },
       { toolName: toolNames.SphereScissors },
-      { toolName: toolNames.StackScroll },
+      {
+        toolName: toolNames.SmartStackScroll,
+        bindings: [
+          { mouseButton: Enums.MouseBindings.Primary, modifierKey: Enums.KeyboardBindings.Ctrl },
+        ],
+        configuration: { shouldPreventScroll },
+      },
       { toolName: toolNames.Magnify },
       { toolName: toolNames.SegmentationDisplay },
       { toolName: toolNames.WindowLevelRegion },
diff --git a/modes/segmentation/src/toolbarButtons.ts b/modes/segmentation/src/toolbarButtons.ts
index 89b4092c66..52f0dc6c56 100644
--- a/modes/segmentation/src/toolbarButtons.ts
+++ b/modes/segmentation/src/toolbarButtons.ts
@@ -165,7 +165,7 @@ const toolbarButtons: Button[] = [
           evaluate: 'evaluate.cornerstoneTool.toggle',
         }),
         createButton({
-          id: 'StackScroll',
+          id: 'SmartStackScroll',
           icon: 'tool-stack-scroll',
           label: 'Stack Scroll',
           tooltip: 'Stack Scroll',
diff --git a/platform/core/src/defaults/hotkeyBindings.js b/platform/core/src/defaults/hotkeyBindings.js
index b4c6098936..d8f44f8d42 100644
--- a/platform/core/src/defaults/hotkeyBindings.js
+++ b/platform/core/src/defaults/hotkeyBindings.js
@@ -111,12 +111,26 @@ const bindings = [
   {
     commandName: 'nextImage',
     label: 'Next Image',
-    keys: ['down'],
+    keys: ['ctrl+down'],
     isEditable: true,
   },
   {
     commandName: 'previousImage',
     label: 'Previous Image',
+    keys: ['ctrl+up'],
+    isEditable: true,
+  },
+  {
+    commandName: 'nextImage',
+    commandOptions: { isSmartScrolling: true },
+    label: 'Smart Next Image',
+    keys: ['down'],
+    isEditable: true,
+  },
+  {
+    commandName: 'previousImage',
+    commandOptions: { isSmartScrolling: true },
+    label: 'Smart Previous Image',
     keys: ['up'],
     isEditable: true,
   },
diff --git a/platform/ui/src/components/ImageScrollbar/ImageScrollbar.css b/platform/ui/src/components/ImageScrollbar/ImageScrollbar.css
index 695e11e9cb..50f495a14f 100644
--- a/platform/ui/src/components/ImageScrollbar/ImageScrollbar.css
+++ b/platform/ui/src/components/ImageScrollbar/ImageScrollbar.css
@@ -1,6 +1,7 @@
 .scroll {
   height: calc(100% - 30px);
   padding: 5px;
+  padding-left: 0;
   position: absolute;
   right: 0;
   top: 30px;
diff --git a/platform/ui/src/components/SmartScrollbar/SmartScrollbar.tsx b/platform/ui/src/components/SmartScrollbar/SmartScrollbar.tsx
new file mode 100644
index 0000000000..0756e5bc7d
--- /dev/null
+++ b/platform/ui/src/components/SmartScrollbar/SmartScrollbar.tsx
@@ -0,0 +1,200 @@
+import React, { useState, useEffect } from 'react';
+import PropTypes from 'prop-types';
+import { Enums, cache, eventTarget } from '@cornerstonejs/core';
+import { utilities as csToolsUtils } from '@cornerstonejs/tools';
+import { ImageScrollbar } from '@ohif/ui';
+import classNames from 'classnames';
+
+const KEYS = { Ctrl: 17 };
+
+function SmartImageScrollbar({
+  viewportData,
+  viewportId,
+  element,
+  imageSliceData,
+  setImageSliceData,
+  scrollbarHeight,
+  servicesManager,
+}: withAppTypes) {
+  const [cachedSlices, setCachedSlices] = useState([]);
+  const [isKeyPressed, setIsKeyPressed] = useState(false);
+
+  const { cineService, cornerstoneViewportService, stateSyncService } = servicesManager.services;
+  const numOfSlices = imageSliceData.numberOfSlices;
+  const scrollbarHeightValue = scrollbarHeight.split('px')[0];
+
+  const onImageScrollbarChange = (imageIndex, viewportId) => {
+    if (!isKeyPressed && !cachedSlices.includes(imageIndex)) {
+      return;
+    }
+
+    const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
+
+    const { isCineEnabled } = cineService.getState();
+
+    if (isCineEnabled) {
+      // on image scrollbar change, stop the CINE if it is playing
+      cineService.stopClip(element, { viewportId });
+      cineService.setCine({ id: viewportId, isPlaying: false });
+    }
+
+    csToolsUtils.jumpToSlice(viewport.element, {
+      imageIndex,
+      debounceLoading: true,
+    });
+  };
+
+  useEffect(() => {
+    if (!viewportData) {
+      return;
+    }
+
+    const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
+
+    if (!viewport) {
+      return;
+    }
+
+    const imageIndex = viewport.getCurrentImageIdIndex();
+    const numberOfSlices = viewport.getNumberOfSlices();
+
+    setImageSliceData({
+      imageIndex: imageIndex,
+      numberOfSlices,
+    });
+  }, [viewportId, viewportData]);
+
+  useEffect(() => {
+    if (!viewportData) {
+      return;
+    }
+    const { viewportType } = viewportData;
+    const eventId =
+      (viewportType === Enums.ViewportType.STACK && Enums.Events.STACK_VIEWPORT_SCROLL) ||
+      (viewportType === Enums.ViewportType.ORTHOGRAPHIC && Enums.Events.VOLUME_NEW_IMAGE) ||
+      Enums.Events.IMAGE_RENDERED;
+
+    const updateIndex = event => {
+      const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
+      const { imageIndex, newImageIdIndex = imageIndex } = event.detail;
+      const numberOfSlices = viewport.getNumberOfSlices();
+      // find the index of imageId in the imageIds
+      setImageSliceData({
+        imageIndex: newImageIdIndex,
+        numberOfSlices,
+      });
+    };
+
+    element.addEventListener(eventId, updateIndex);
+
+    return () => {
+      element.removeEventListener(eventId, updateIndex);
+    };
+  }, [viewportData, element]);
+
+  useEffect(() => {
+    if (viewportData?.viewportType !== Enums.ViewportType.STACK) {
+      return;
+    }
+
+    updateCachedSlices();
+
+    eventTarget.addEventListener(Enums.Events.IMAGE_CACHE_IMAGE_ADDED, updateCachedSlices);
+    eventTarget.addEventListener(Enums.Events.VOLUME_CACHE_VOLUME_ADDED, updateCachedSlices);
+    eventTarget.addEventListener(Enums.Events.IMAGE_CACHE_IMAGE_REMOVED, updateCachedSlices);
+    eventTarget.addEventListener(Enums.Events.VOLUME_CACHE_VOLUME_REMOVED, updateCachedSlices);
+
+    return () => {
+      eventTarget.removeEventListener(Enums.Events.IMAGE_CACHE_IMAGE_ADDED, updateCachedSlices);
+      eventTarget.removeEventListener(Enums.Events.VOLUME_CACHE_VOLUME_ADDED, updateCachedSlices);
+      eventTarget.removeEventListener(Enums.Events.IMAGE_CACHE_IMAGE_REMOVED, updateCachedSlices);
+      eventTarget.removeEventListener(Enums.Events.VOLUME_CACHE_VOLUME_REMOVED, updateCachedSlices);
+    };
+  }, [viewportData, numOfSlices]);
+
+  useEffect(() => {
+    const onKeyDown = evt => {
+      //  Checking the pressed key is Ctrl key
+      evt.keyCode === KEYS.Ctrl && setIsKeyPressed(true);
+    };
+
+    const onKeyUp = evt => {
+      //  Checking the pressed key is Ctrl key
+      evt.keyCode === KEYS.Ctrl && setIsKeyPressed(false);
+    };
+
+    window.addEventListener('keydown', onKeyDown);
+    window.addEventListener('keyup', onKeyUp);
+
+    return () => {
+      window.removeEventListener('keydown', onKeyDown);
+      window.removeEventListener('keyup', onKeyUp);
+    };
+  }, []);
+
+  function updateCachedSlices() {
+    if (!viewportData?.data) {
+      return;
+    }
+
+    const { cachedSlicesPerSeries } = stateSyncService.getState();
+    const { imageIds, displaySetInstanceUID } = viewportData.data[0];
+
+    const cachedImages = [];
+    imageIds.forEach((imageId, index) => {
+      if (cache.isLoaded(imageId)) {
+        cachedImages.push(index);
+      }
+    });
+
+    stateSyncService.store({
+      cachedSlicesPerSeries: { ...cachedSlicesPerSeries, [displaySetInstanceUID]: cachedImages },
+    });
+    setCachedSlices(cachedImages);
+  }
+
+  return (
+    <>
+      {numOfSlices && (
+        <span
+          className="border-primary-light bg-secondary-active absolute right-[3px] top-8 w-5 overflow-hidden rounded-lg border-2"
+          style={{ height: `${+scrollbarHeightValue + 4}px` }}
+        >
+          {[...Array(numOfSlices)].map((_, index) => (
+            <div
+              key={index}
+              className={classNames(
+                'w-full cursor-pointer',
+                cachedSlices.includes(index)
+                  ? 'bg-secondary-light border-primary-light'
+                  : 'border-transparent bg-transparent',
+                index > 0 && 'border-t-[0.5px]',
+                index < numOfSlices - 1 && 'border-b-[0.5px]'
+              )}
+              style={{ height: `${(+scrollbarHeightValue + 2) / numOfSlices}px` }}
+              onClick={() => onImageScrollbarChange(index, viewportId)}
+            ></div>
+          ))}
+        </span>
+      )}
+      <ImageScrollbar
+        onChange={imageIndex => onImageScrollbarChange(imageIndex, viewportId)}
+        max={numOfSlices ? numOfSlices - 1 : 0}
+        height={scrollbarHeight}
+        value={imageSliceData.imageIndex || 0}
+      />
+    </>
+  );
+}
+
+SmartImageScrollbar.propTypes = {
+  viewportData: PropTypes.object,
+  viewportId: PropTypes.string.isRequired,
+  element: PropTypes.instanceOf(Element),
+  scrollbarHeight: PropTypes.string,
+  imageSliceData: PropTypes.object.isRequired,
+  setImageSliceData: PropTypes.func.isRequired,
+  servicesManager: PropTypes.object.isRequired,
+};
+
+export default SmartImageScrollbar;
diff --git a/platform/ui/src/components/SmartScrollbar/index.js b/platform/ui/src/components/SmartScrollbar/index.js
new file mode 100644
index 0000000000..2203817370
--- /dev/null
+++ b/platform/ui/src/components/SmartScrollbar/index.js
@@ -0,0 +1,2 @@
+import SmartScrollbar from './SmartScrollbar';
+export default SmartScrollbar;
diff --git a/platform/ui/src/components/index.js b/platform/ui/src/components/index.js
index 52020efd55..f5d7ea69a4 100644
--- a/platform/ui/src/components/index.js
+++ b/platform/ui/src/components/index.js
@@ -96,6 +96,7 @@ import MeasurementItem from './MeasurementTable/MeasurementItem';
 import LayoutPreset from './LayoutPreset';
 import ActionButtons from './ActionButtons';
 import StudyBrowserSort from './StudyBrowserSort';
+import SmartScrollbar from './SmartScrollbar';
 
 export {
   ActionButtons,
@@ -153,6 +154,7 @@ export {
   SegmentationGroupTable,
   SegmentationGroupTableExpanded,
   SidePanel,
+  SmartScrollbar,
   SplitButton,
   StudyBrowser,
   StudyItem,
diff --git a/platform/ui/src/index.js b/platform/ui/src/index.js
index b240a6e4b5..575873f723 100644
--- a/platform/ui/src/index.js
+++ b/platform/ui/src/index.js
@@ -85,6 +85,7 @@ export {
   SegmentationGroupTable,
   SegmentationGroupTableExpanded,
   SidePanel,
+  SmartScrollbar,
   SplitButton,
   ProgressDropdown,
   LegacySplitButton,