Commit 73fa66a2 authored by Ategon's avatar Ategon
Browse files

Merge branch 'feat/user-cursors' of https://sc07.dev/sc07/canvas into feat/user-cursors

parents c349c8af aa3252a5
Loading
Loading
Loading
Loading
Loading
+29 −10
Original line number Diff line number Diff line
@@ -38,6 +38,8 @@ import {
} from "./ColorPickFeedback";
import { CursorPresenceLayer } from "./CursorPresenceLayer";

const KEYBOARD_ZOOM_STEP = 1;
const KEYBOARD_ZOOM_SMALL_STEP = 0.35;
const INSPECT_END_ANIMATION_DURATION = 180;

export function CanvasWrapper() {
@@ -257,12 +259,8 @@ const CanvasInner = () => {
    enable: templateEnable,
  } = useTemplateContext();
  const PanZoom = useContext(RendererContext);
  const {
    captureCanvas,
    captureView,
    captureRegion,
    captureTemplateArea,
  } = useCaptureContext();
  const { captureCanvas, captureView, captureRegion, captureTemplateArea } =
    useCaptureContext();

  useEffect(() => {
    const heldKeys = new Set<string>();
@@ -323,10 +321,8 @@ const CanvasInner = () => {
      velocityY += (targetVelocityY - velocityY) * easing;

      if (Math.abs(velocityX) > 0.5 || Math.abs(velocityY) > 0.5) {
        PanZoom.transform.x +=
          (velocityX * elapsed) / PanZoom.transform.scale;
        PanZoom.transform.y +=
          (velocityY * elapsed) / PanZoom.transform.scale;
        PanZoom.transform.x += (velocityX * elapsed) / PanZoom.transform.scale;
        PanZoom.transform.y += (velocityY * elapsed) / PanZoom.transform.scale;
        const visualX = snapToDevicePixel(PanZoom.transform.x);
        const visualY = snapToDevicePixel(PanZoom.transform.y);
        PanZoom.$move.style.setProperty(
@@ -540,12 +536,30 @@ const CanvasInner = () => {
  }, []);

  useEffect(() => {
    const zoomBy = (step: number) => {
      if (!PanZoom.$zoom || !PanZoom.$move) return;

      const oldScale = PanZoom.transform.scale;
      PanZoom.nudgeScale(step);

      if (oldScale !== PanZoom.transform.scale) PanZoom.update();
    };

    const zoomOut = () => zoomBy(-KEYBOARD_ZOOM_STEP);
    const zoomIn = () => zoomBy(KEYBOARD_ZOOM_STEP);
    const zoomOutSmall = () => zoomBy(-KEYBOARD_ZOOM_SMALL_STEP);
    const zoomInSmall = () => zoomBy(KEYBOARD_ZOOM_SMALL_STEP);

    KeybindManager.on("PIXEL_WHOIS", handlePixelWhois);
    KeybindManager.on("PICK_COLOR", handlePickPixel);
    KeybindManager.on("CAPTURE_CANVAS", captureCanvas);
    KeybindManager.on("CAPTURE_VIEW", captureView);
    KeybindManager.on("CAPTURE_REGION", captureRegion);
    KeybindManager.on("CAPTURE_TEMPLATE", captureTemplateArea);
    KeybindManager.on("ZOOM_OUT", zoomOut);
    KeybindManager.on("ZOOM_IN", zoomIn);
    KeybindManager.on("ZOOM_OUT_SMALL", zoomOutSmall);
    KeybindManager.on("ZOOM_IN_SMALL", zoomInSmall);

    return () => {
      KeybindManager.off("PIXEL_WHOIS", handlePixelWhois);
@@ -554,8 +568,13 @@ const CanvasInner = () => {
      KeybindManager.off("CAPTURE_VIEW", captureView);
      KeybindManager.off("CAPTURE_REGION", captureRegion);
      KeybindManager.off("CAPTURE_TEMPLATE", captureTemplateArea);
      KeybindManager.off("ZOOM_OUT", zoomOut);
      KeybindManager.off("ZOOM_IN", zoomIn);
      KeybindManager.off("ZOOM_OUT_SMALL", zoomOutSmall);
      KeybindManager.off("ZOOM_IN_SMALL", zoomInSmall);
    };
  }, [
    PanZoom,
    handlePixelWhois,
    handlePickPixel,
    captureCanvas,
+2 −2
Original line number Diff line number Diff line
@@ -118,9 +118,9 @@ export const HeaderRight = () => {
      className="header-right box flex flex-col gap-2"
      transition={reduceMotion ? { duration: 0 } : SIDEBAR_SPRING}
    >
      <User />
      {!isMobile && <User />}
      <div className="header-right-actions flex gap-2">
        <div ref={captureMenuRef} className="relative">
        <div ref={captureMenuRef} className="header-share-menu relative">
          <Button
            aria-label="Share"
            aria-expanded={captureMenuOpen}
+22 −13
Original line number Diff line number Diff line
import { usePanel } from "@/contexts/PanelContext";
import { useAppContext } from "../../contexts/AppContext";
import { useDialog } from "../../contexts/DialogContext";
import { useIsCompactPaletteDefault } from "../../hooks/useCompactPalette";
import { useIsMobile } from "../../hooks/useIsMobile";
import { Button } from "../core/Button";
import { Switch } from "../core/Switch";
@@ -10,6 +11,10 @@ export const MiscSettings = () => {
  const Dialog = useDialog();
  const Panel = usePanel();
  const isMobile = useIsMobile();
  const compactPaletteDefault = useIsCompactPaletteDefault();
  const compactPaletteSetting = settings.get["palette.compact"];
  const compactPaletteSelected = compactPaletteSetting ?? compactPaletteDefault;
  const showCompactPaletteSettings = !isMobile;

  return (
    <div className="flex flex-col gap-4 p-2">
@@ -80,15 +85,19 @@ export const MiscSettings = () => {
        >
          Compact Buttons
        </Switch>
        {showCompactPaletteSettings && (
          <Switch
          isSelected={settings.get["palette.compact"]}
            isSelected={compactPaletteSelected}
            onValueChange={(value) => {
              settings.set({ key: "palette.compact", value });
            }}
          >
            Compact Palette
          </Switch>
        {!settings.get["palette.compact"] && (
        )}
        {showCompactPaletteSettings &&
          compactPaletteSetting === undefined &&
          !compactPaletteDefault && (
            <Switch
              className="sidebar-adaptation-setting"
              isSelected={settings.get["ui.compactPaletteForSidebar"]}
+1 −1
Original line number Diff line number Diff line
@@ -8,7 +8,7 @@ export const MobileTemplateButtons = () => {
  if (!url) return null;

  return (
    <div className="md:hidden toolbar-box top-[-10px] right-[10px]">
    <div className="mobile-template-toggle-wrapper md:hidden">
      <Card className="mobile-template-toggle canvas-overlay-card">
        <Switch
          size="sm"
+2 −1
Original line number Diff line number Diff line
@@ -101,6 +101,7 @@ export const CanvasMeta = () => {
  const reduceMotion = useReducedMotion() ?? false;
  const sidebarWidth = useSidebarWidth("Left");
  const compactPalette = useCompactPalette();
  const canvasMetaBottom = !isMobile && compactPalette ? 84 : 76;
  const offsetForSidebar = Boolean(
    !isMobile &&
      Panel.state.info &&
@@ -132,7 +133,7 @@ export const CanvasMeta = () => {
      <motion.div
        animate={{
          x: offsetForSidebar ? sidebarWidth : 0,
          bottom: compactPalette ? 84 : 76,
          bottom: canvasMetaBottom,
        }}
        id="canvas-meta"
        className={`toolbar-box canvas-overlay-card${isCollapsed ? " canvas-meta--collapsed" : ""}`}
Loading