diff --git a/packages/mini-editor/src/code.tsx b/packages/mini-editor/src/code.tsx index 0834e936..2cc787f9 100644 --- a/packages/mini-editor/src/code.tsx +++ b/packages/mini-editor/src/code.tsx @@ -16,6 +16,8 @@ type CodeProps = { language: string parentHeight?: number minColumns: number + minZoom: number + maxZoom: number } export function Code({ @@ -27,6 +29,8 @@ export function Code({ language, parentHeight, minColumns, + minZoom, + maxZoom, }: CodeProps) { const { prevLines, @@ -53,17 +57,7 @@ export function Code({
       
         {dimensions ? (
@@ -85,7 +79,8 @@ export function Code({
             }
             prevFocus={prevFocusIndexes}
             nextFocus={nextFocusIndexes}
-            maxZoom={1}
+            minZoom={minZoom}
+            maxZoom={maxZoom}
           />
         ) : (
           <>
diff --git a/packages/mini-editor/src/index.scss b/packages/mini-editor/src/index.scss
index ea02550b..f028da5e 100644
--- a/packages/mini-editor/src/index.scss
+++ b/packages/mini-editor/src/index.scss
@@ -43,11 +43,22 @@
   height: 100%;
   color: #cccccc;
   font-size: 15px;
-  padding: 5px 10px;
+  // padding: 5px 10px;
   line-height: 1.1rem;
   box-sizing: border-box;
 }
 
+.ch-editor-body pre {
+  position: absolute;
+  top: 0;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  padding: 0 16px;
+  margin: 0;
+  overflow: auto;
+}
+
 .ch-editor-body code {
   line-height: 20px;
 }
diff --git a/packages/mini-editor/src/mini-editor.tsx b/packages/mini-editor/src/mini-editor.tsx
index 3d10508a..16e8c88e 100644
--- a/packages/mini-editor/src/mini-editor.tsx
+++ b/packages/mini-editor/src/mini-editor.tsx
@@ -31,6 +31,8 @@ export type MiniEditorProps = {
   steps?: MiniEditorStep[]
   height?: number
   minColumns?: number
+  minZoom?: number
+  maxZoom?: number
   button?: React.ReactNode
   classes?: Classes
 } & React.PropsWithoutRef
@@ -46,6 +48,8 @@ function MiniEditor(props: MiniEditorProps) {
     steps: ogSteps,
     tabs: ogTabs,
     minColumns = 50,
+    minZoom = 0.2,
+    maxZoom = 1,
     height,
     ...rest
   } = props
@@ -101,6 +105,8 @@ function MiniEditor(props: MiniEditorProps) {
           steps={contentSteps}
           parentHeight={height}
           minColumns={minColumns}
+          minZoom={minZoom}
+          maxZoom={maxZoom}
         />
       )}
     
@@ -155,6 +161,8 @@ type ContentProps = {
   steps: ContentStep[]
   parentHeight?: number
   minColumns: number
+  minZoom: number
+  maxZoom: number
 }
 
 function EditorContent({
@@ -163,6 +171,8 @@ function EditorContent({
   steps,
   parentHeight,
   minColumns,
+  minZoom,
+  maxZoom,
 }: ContentProps) {
   const fwdTransitions = useForwardTransitions(steps)
   const bwdTransitions = useBackwardTransitions(steps)
@@ -188,6 +198,8 @@ function EditorContent({
       progress={progress - transitionIndex + 1}
       parentHeight={parentHeight}
       minColumns={minColumns}
+      minZoom={minZoom}
+      maxZoom={maxZoom}
     />
   )
 }
diff --git a/packages/mini-editor/src/use-dimensions.tsx b/packages/mini-editor/src/use-dimensions.tsx
index 804f7465..64e28b88 100644
--- a/packages/mini-editor/src/use-dimensions.tsx
+++ b/packages/mini-editor/src/use-dimensions.tsx
@@ -31,8 +31,6 @@ function useDimensions(
 
   useLayoutEffect(() => {
     if (ref.current) {
-      const rect = ref.current.getBoundingClientRect()
-
       const pll = ref.current.querySelector(
         ".prev-longest-line"
       )
@@ -50,8 +48,8 @@ function useDimensions(
         ? plw! / (pll.textContent?.length || 1)
         : nlw! / (nll!.textContent?.length || 1)
       setDimensions({
-        width: rect.width,
-        height: rect.height,
+        width: getWidthWithoutPadding(ref.current),
+        height: getHeightWithoutPadding(ref.current),
         lineWidths: [
           plw || nlw || DEFAULT_WIDTH,
           nlw || plw || DEFAULT_WIDTH,
@@ -73,6 +71,23 @@ function useDimensions(
   }
 }
 
+function getWidthWithoutPadding(element: HTMLElement) {
+  const computedStyle = getComputedStyle(element)
+  return (
+    element.clientWidth -
+    parseFloat(computedStyle.paddingLeft) -
+    parseFloat(computedStyle.paddingRight)
+  )
+}
+function getHeightWithoutPadding(element: HTMLElement) {
+  const computedStyle = getComputedStyle(element)
+  return (
+    element.clientHeight -
+    parseFloat(computedStyle.paddingTop) -
+    parseFloat(computedStyle.paddingBottom)
+  )
+}
+
 function depsChanged(
   oldDeps: React.DependencyList,
   newDeps: React.DependencyList
diff --git a/packages/smooth-lines/src/index.tsx b/packages/smooth-lines/src/index.tsx
index 24c49750..f3e81414 100644
--- a/packages/smooth-lines/src/index.tsx
+++ b/packages/smooth-lines/src/index.tsx
@@ -35,15 +35,11 @@ function SmoothLines({
   prevFocus,
   nextFocus,
   center,
-  minZoom = 0, // TODO use minZoom
+  minZoom = 0,
   maxZoom = 1.2,
 }: Props) {
   const lines = useLineTransitions(prevLines, nextLines)
 
-  const focusWidth = Array.isArray(lineWidth)
-    ? tweenProp(lineWidth[0], lineWidth[1], progress)
-    : lineWidth
-
   const prevFocusKeys = prevFocus.map(
     index => prevLines[index]?.key
   )
@@ -51,25 +47,39 @@ function SmoothLines({
     index => nextLines[index]?.key
   )
 
-  const [prevZoom, prevDX, prevDY] = getContentProps({
+  const [
+    prevZoom,
+    prevDX,
+    prevDY,
+    prevContentHeight,
+    prevContentWidth,
+  ] = getContentProps({
     containerWidth,
     containerHeight,
     lineWidth: Array.isArray(lineWidth)
       ? lineWidth[0]
       : lineWidth,
     lineHeight,
+    minZoom,
     maxZoom,
     horizontalCenter: !!center,
     focusLineIndexList: prevFocus,
     originalContentHeight: prevLines.length * lineHeight,
   })
-  const [nextZoom, nextDX, nextDY] = getContentProps({
+  const [
+    nextZoom,
+    nextDX,
+    nextDY,
+    nextContentHeight,
+    nextContentWidth,
+  ] = getContentProps({
     containerWidth,
     containerHeight,
     lineWidth: Array.isArray(lineWidth)
       ? lineWidth[1]
       : lineWidth,
     lineHeight,
+    minZoom,
     maxZoom,
     horizontalCenter: !!center,
     focusLineIndexList: nextFocus,
@@ -79,13 +89,29 @@ function SmoothLines({
   const zoom = tweenProp(prevZoom, nextZoom, progress)
   const dx = tweenProp(prevDX, nextDX, progress)
   const dy = tweenProp(prevDY, nextDY, progress)
+  const focusHeight = tweenProp(
+    prevContentHeight,
+    nextContentHeight,
+    progress
+  )
+  const focusWidth = tweenProp(
+    prevContentWidth,
+    nextContentWidth,
+    progress
+  )
 
   return (
     
-      
+      
          contentHeight
       ? (containerHeight - contentHeight) / 2
       : clamp(
           containerHeight / 2 - focusCenter,
-          containerHeight - contentHeight,
+          Math.max(
+            containerHeight - contentHeight,
+            -focusStart // to ensure first focus line is shown when focus is bigger than container
+          ),
           0
         )
 
@@ -149,7 +184,13 @@ function getContentProps({
     ? containerWidth / 2 - (lineWidth * zoom) / 2
     : 0
 
-  return [zoom, dx, dy] as const
+  return [
+    zoom,
+    dx,
+    dy,
+    focusHeight,
+    lineWidth * zoom,
+  ] as const
 }
 
 function Container({
@@ -167,6 +208,7 @@ function Container({
         width,
         height,
         position: "relative",
+        // overflow: "auto",
       }}
     >
       {children}
@@ -178,11 +220,15 @@ function Content({
   dx,
   dy,
   scale,
+  height,
+  width,
   children,
 }: {
   dx: number
   dy: number
   scale: number
+  height: number
+  width: number
   children: React.ReactNode
 }) {
   return (
@@ -191,10 +237,23 @@ function Content({
         position: "absolute",
         top: 0,
         left: 0,
-        transform: `translateX(${dx}px) translateY(${dy}px) scale(${scale})`,
+        transformOrigin: "top left",
+        width: width,
+        height: height,
+        overflow: "hidden",
       }}
     >
-      {children}
+      
+ {children} +
) } diff --git a/packages/storybook/src/mini-editor.story.js b/packages/storybook/src/mini-editor.story.js index 8aebf8a7..bf7effdc 100644 --- a/packages/storybook/src/mini-editor.story.js +++ b/packages/storybook/src/mini-editor.story.js @@ -69,6 +69,7 @@ console.log(1)` progress={progress} backward={backward} minColumns={10} + minZoom={1} /> )} @@ -127,6 +128,7 @@ console.log(8)` steps={steps} progress={progress} backward={backward} + minZoom={0.8} /> )} diff --git a/packages/storybook/src/scrollycoding.story.js b/packages/storybook/src/scrollycoding.story.js index 3bb2a5b9..8f57ec38 100644 --- a/packages/storybook/src/scrollycoding.story.js +++ b/packages/storybook/src/scrollycoding.story.js @@ -87,6 +87,7 @@ function Hike({ }, { minColumns: 46, + minZoom: 0.9, ...codeProps, } ) diff --git a/packages/storybook/src/smooth-lines.story.js b/packages/storybook/src/smooth-lines.story.js index 5e1e7fa5..0969c72d 100644 --- a/packages/storybook/src/smooth-lines.story.js +++ b/packages/storybook/src/smooth-lines.story.js @@ -15,10 +15,23 @@ export default { }, defaultValue: 150, }, + minZoom: { + control: { + type: "range", + min: 0, + max: 1, + step: 0.1, + }, + defaultValue: 0.2, + }, }, } -export const basic = ({ center, containerWidth }) => ( +export const basic = ({ + center, + containerWidth, + minZoom, +}) => ( {progress => (
( lineWidth={lineWidth} prevFocus={[1, 1]} nextFocus={[3, 11]} + minZoom={minZoom} />
)} @@ -86,6 +100,7 @@ export const verticalCenter = ({ export const dynamicLineWidth = ({ center, containerWidth, + minZoom, }) => { const prevLines = [ { element: One, key: 1 }, @@ -126,6 +141,7 @@ export const dynamicLineWidth = ({ lineWidth={[lineWidth, lineWidth * 2]} prevFocus={[1, 1]} nextFocus={[2, 2]} + minZoom={minZoom} /> )}