-
Notifications
You must be signed in to change notification settings - Fork 40
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Support for Non-Pixel Units #2
Comments
use zoom 96px = 1in new Ruler(??, {
zoom: 96,
unit: 1,
}); |
This did not work for me. can you please be specific what i can do to fix. this.guides1.zoom = 96; |
@joncursi since you have access to The only issue we are running into while doing this is javascript precision. So if eg. you say you want the ruler to show you 0mm, 25mm, 50mm etc. the @daybrush ideally the calculations in Ruler.tsx use precise |
So for others running into the same issue. A pretty hacky, but actually for reasonable values kinda working solution is to round the final value to the desired steps again, note that you likely want a dynamic steps value depending on your zoom, but eg. on the zoom level shown above you'll note that our desired values are all multiples of 5, so we can snap to that using |
@tom2strobl would you like to make your example of the image above available in your repository or codepen? |
Do you want this codepen? |
That wouldn't be good. I'm working with mm and when scrolling or zooming the page, the rulers don't keep the measures synchronized. I saw that @tom2strobl apparently got around this and wanted to see how he did it! |
@hitaloramon sorry that notification slipped through the gutter. I can't share the repo and am frankly too lazy to put together a full sample codepen—but it's along the lines of this: // arbitrary helper function that does more than you need and lacks other helper functions but I just pasted it in here, you'll figure it out
const pixelToUnit = (
pixel: number | Decimal,
unit: MeasuringUnit,
withUnit = true,
returnAsReactNode = true,
rounding = 0,
fractionsForInches = true
) => {
let pixelNumber = pixel as number
if (typeof pixel !== 'number') {
pixelNumber = pixel.toNumber()
}
if (unit === MeasuringUnit.Pixel) {
return withUnit ? `${pixelNumber}${MeasuringUnitUnits[unit]}` : pixelNumber
}
if (unit === MeasuringUnit.Metric) {
let value = pixelToMillimeter(pixel).toNumber()
// due to javascript imprecision and the fact that 3rd party libs don't implement Decimal, although its hacky
// we need to round in steps of 5 so the value eg. on the ruler is correct
if (rounding) {
value = Math.round(value / rounding) * rounding
}
return withUnit ? `${value}${MeasuringUnitUnits[unit]}` : value
}
if (unit === MeasuringUnit.Imperial) {
const value = fractionsForInches
? floatToFractionString(pixelToInch(pixel).toNumber(), returnAsReactNode)
: pixelToInch(pixel).toNumber()
return withUnit ? `${value}${MeasuringUnitUnits[unit]}` : value
}
throw new Error(`Unknown measuring unit: ${unit}`)
}
// Base unit is dependent on the measuring unit
const BaseUnit = MeasuringUnitBase[measuringUnits]
// by leveraging unit steps and the current zoom, we show more detailed steps when zoomed in
const UnitSteps = BaseUnit.dividedBy(2).toNumber()
const unit = Math.round(BaseUnit.toNumber() / zoom / UnitSteps) * UnitSteps
const textFormat = useCallback(
(px: number) => pixelToUnit(px, measuringUnits, true, false, 5) as string,
[measuringUnits]
)
const dragPosFormat = useCallback(
(px: number) => pixelToUnit(px, measuringUnits, true, false, 1) as string,
[measuringUnits]
)
const baseGuidesProps = useMemo(
() => ({
// [...some more vars I dont list here]
lockGuides,
segment: measuringUnits === MeasuringUnit.Imperial ? 8 : 10,
zoom,
unit,
snapThreshold: 5,
textFormat,
dragPosFormat,
}),
[dragPosFormat, lockGuides, measuringUnits, showRuler, textFormat, theme, unit, zoom]
)
// we take 1cm in inches and convert it to pixels with 300 dpi
const snapMargin = new Decimal(new Decimal(1).dividedBy(ONE_INCH_IN_MM.dividedBy(10))).times(defaultDpi).toNumber()
const horizontalSnaps = useMemo(
() => [0 + snapMargin, pageFormatValues[1] - snapMargin].map(Math.round),
[pageFormatValues, snapMargin]
)
const verticalSnaps = useMemo(
() => [0 + snapMargin, pageFormatValues[0] - snapMargin].map(Math.round),
[pageFormatValues, snapMargin]
)
const jsx = (
<Guides
// [...some more props I dont list here]
{...baseGuidesProps}
snaps={horizontalSnaps}
type="horizontal"
/>
<Guides
// [...some more props I dont list here]
{...baseGuidesProps}
snaps={verticalSnaps}
type="vertical"
/>
) |
I would like my rulers to use a different set of units than pixels. Some examples would be:
It would be great if there was a prop that allowed me to specify a pixel --> custom unit conversion. (E.g. 1 px = 1/72 inch)
The text was updated successfully, but these errors were encountered: