So, I was making a block for image shadow but if you type a input higher than 90, the code crops the image and still scale the sprite size.
Here’s the code:
//% block="shadow $img|with color: $c|length: $leng|rotation: $rot"
//% c.shadow="colorindexpicker"
//% inlineInputMode=inline
//% subcategory="Image"
//% img.shadow="screen_image_picker"
//% subcategory="Image"
export function shadow(img: Image, c: number, leng: number, rot: number) {
let picture = image.create(image.getDimension(img, image.Dimension.Width) + (leng + 1), image.getDimension(img, image.Dimension.Height) + (leng + 1))
let clone = img.clone()
for (let index = 0; index <= leng; index++) {
picture.drawTransparentImage(CyberScripts.OneColorImage(img, c), index * Math.sin(rot * (Math.PI / 180)), index * Math.cos(rot * (Math.PI / 180)))
}
picture.drawTransparentImage(clone, 0, 0)
return picture
}
2 Likes
Im afraid i can only really help if its in blocks, i am bad at JavaScript…
1 Like
you have:
//% subcategory=“Image”
in there twice
but other than that idk
1 Like
Im not sure. I tried this:
//% block="shadow $img|with color: $c|length: $leng|rotation: $rot"
//% c.shadow="colorindexpicker"
//% inlineInputMode=inline
//% subcategory="Image"
//% img.shadow="screen_image_picker"
export function shadow(img: Image, c: number, size: number, rot: number) {
rot = ((rot % 360) + 360) % 360
const r = Math.PI * (rot / 180)
const sin = Math.sin(r), cos = Math.cos(r)
const picture = image.create(
img.width + Math.abs(sin * size) | 0,
img.height + Math.abs(cos * size) | 0
)
const im = OneColorImage(img, c)
let stepX = sin, stepY = cos
for (let i = 0; i < size; i++) {
picture.drawTransparentImage(im, stepX | 0, stepY | 0)
stepX += sin
stepY += cos
}
const index = (rot / 90) | 0
const offsetX = picture.width - img.width
const offsetY = picture.height - img.height
const xPos = [0, 0, offsetX, offsetX][index] || 0
const yPos = [offsetY, 0, 0, offsetY][index] || 0
picture.drawTransparentImage(img, xPos, yPos)
return picture
}
but it didn’t look right (when I used it).
asked Gemini, this works:
function OneColorImage(src: Image, color: number): Image {
const result = src.clone()
for (let c = 1; c <= 15; c++) result.replace(c, color)
return result
}
// vvv FUNCTION HERE vvv
function createDropShadow(img: Image, color: number, offset: number, angleDeg: number): Image {
if (offset <= 0) return img.clone()
const rad = (angleDeg * Math.PI) / 180
const totalShiftX = Math.cos(rad) * offset
const totalShiftY = Math.sin(rad) * offset
const padX = Math.ceil(Math.abs(totalShiftX))
const padY = Math.ceil(Math.abs(totalShiftY))
const canvas = image.create(
img.width + padX,
img.height + padY
)
// Calculate original image offset so it stays in bounds
const origX = totalShiftX < 0 ? padX : 0
const origY = totalShiftY < 0 ? padY : 0
const shadowImg = OneColorImage(img, color)
// Interpolate shadow steps outwards from original image position
for (let i = 1; i <= offset; i++) {
const stepX = origX + (totalShiftX * (i / offset))
const stepY = origY + (totalShiftY * (i / offset))
canvas.drawTransparentImage(shadowImg, Math.round(stepX), Math.round(stepY))
}
// Draw the source image on top
canvas.drawTransparentImage(img, origX, origY)
return canvas
}
// ^^^ FUNCTION HERE ^^^
const sourceImage = assets.image`pizza with hole`
let shadowDistance = 0
let shadowAngle = 45
let cachedRender: Image = sourceImage
let needsUpdate = true
controller.A.onEvent(ControllerButtonEvent.Pressed, function () {
shadowDistance++
needsUpdate = true
})
controller.B.onEvent(ControllerButtonEvent.Pressed, function () {
shadowDistance = Math.max(shadowDistance - 1, 0)
needsUpdate = true
})
game.onUpdate(function () {
if (controller.left.isPressed()) {
shadowAngle -= 2
needsUpdate = true
}
if (controller.right.isPressed()) {
shadowAngle += 2
needsUpdate = true
}
if (needsUpdate) {
cachedRender = createDropShadow(sourceImage, 4, shadowDistance, shadowAngle)
needsUpdate = false
}
})
game.onPaint(function () {
const drawX = 80 - (cachedRender.width >> 1)
const drawY = 60 - (cachedRender.height >> 1)
screen.drawTransparentImage(cachedRender, drawX, drawY)
})
but i want to be assessable to all images
what do you mean? I’m not understanding.
i want to be used to all images
do you mean make your own images? You should need to change the //% lines a little, but this works fine:
(they are in a DELEYE.ts file)
it dident work with multiple colors