当前位置: 首页 > news >正文

【Android】手机蜘蛛魔术的简易app例子

手机画面内容结合魔术手法在魔术表演中可以达到一种很强的视觉场景冲击,比如手机里的蜘蛛爬出来的魔术,这里做一个简易的app,

首先找到蜘蛛的png图片,多做几张可以实现更好的爬动效果,这里用一张来试验,把图片中的白色背景转换为透明颜色,

from PIL import Image # 打开图片 img = Image.open('spider0.png') img = img.convert("RGBA") datas = img.getdata() newData = [] for item in datas: # 如果像素的颜色接近白色,则将其改为完全透明 if item[0] > 240 and item[1] > 240 and item[2] > 240: newData.append((255, 255, 255, 0)) else: newData.append(item) img.putdata(newData) img.save("spider.png", "PNG")

app例子

package com.example.magic; import androidx.appcompat.app.AppCompatActivity; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.os.Bundle; // app/src/main/java/com/example/spiderphoto/MainActivity.java import android.Manifest; import android.content.Intent; import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.os.Bundle; import android.provider.MediaStore; import android.view.View; import android.view.animation.Animation; import android.view.animation.TranslateAnimation; import android.widget.Button; import android.widget.ImageView; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; public class MainActivity extends AppCompatActivity { private static final int REQUEST_CAMERA_PERMISSION = 100; private static final int REQUEST_IMAGE_CAPTURE = 101; private ImageView imageView; private View spiderView; private Button btnTakePhoto; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); imageView = findViewById(R.id.imageView); spiderView = findViewById(R.id.spiderView); btnTakePhoto = findViewById(R.id.btnTakePhoto); btnTakePhoto.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (checkCameraPermission()) { dispatchTakePictureIntent(); } else { requestCameraPermission(); } } }); } private boolean checkCameraPermission() { return ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED; } private void requestCameraPermission() { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION); } private void dispatchTakePictureIntent() { Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); if (takePictureIntent.resolveActivity(getPackageManager()) != null) { startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE); } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == REQUEST_CAMERA_PERMISSION) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { dispatchTakePictureIntent(); } else { Toast.makeText(this, "需要相机权限才能拍照", Toast.LENGTH_SHORT).show(); } } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) { Bundle extras = data.getExtras(); Bitmap imageBitmap = (Bitmap) extras.get("data"); // 显示照片 imageView.setImageBitmap(imageBitmap); imageView.setVisibility(View.VISIBLE); btnTakePhoto.setVisibility(View.GONE); // 启动蜘蛛动画 startSpiderCrawl(); } } private void startSpiderCrawl00() { ImageView spider = findViewById(R.id.spiderView); spider.setVisibility(View.VISIBLE); // 获取屏幕高度(用于计算移动距离) int screenHeight = getResources().getDisplayMetrics().heightPixels; // 1. 主动画:垂直向上移动(从底部到顶部外) ObjectAnimator moveUp = ObjectAnimator.ofFloat( spider, "translationY", screenHeight - spider.getHeight(), // 起点:底部(减去自身高度) -spider.getHeight() * 1.2f // 终点:顶部上方完全消失 ); moveUp.setDuration(8000); // 2. 辅助动画:左右轻微晃动(模拟爬行时的身体摆动) ObjectAnimator sway = ObjectAnimator.ofFloat(spider, "translationX", 0f, -20f, 0f, 20f, 0f); sway.setDuration(8000); sway.setRepeatCount(ObjectAnimator.INFINITE); // 循环晃动 // 3. 轻微缩放(模拟腿部蹬地的弹跳感) ObjectAnimator bounce = ObjectAnimator.ofFloat(spider, "scaleY", 1.0f, 1.1f, 1.0f, 0.95f, 1.0f); bounce.setDuration(800); bounce.setRepeatCount(ObjectAnimator.INFINITE); bounce.setRepeatMode(ObjectAnimator.REVERSE); // 同时播放三个动画 AnimatorSet animatorSet = new AnimatorSet(); animatorSet.playTogether(moveUp, sway, bounce); animatorSet.start(); // 动画结束后清理 moveUp.addListener(new android.animation.AnimatorListenerAdapter() { @Override public void onAnimationEnd(android.animation.Animator animation) { spider.setVisibility(View.INVISIBLE); sway.cancel(); bounce.cancel(); btnTakePhoto.setVisibility(View.VISIBLE); } }); } private void startSpiderCrawl() { spiderView.setVisibility(View.VISIBLE); // 创建从底部到顶部的平移动画 TranslateAnimation animation = new TranslateAnimation( Animation.RELATIVE_TO_PARENT, 0f, Animation.RELATIVE_TO_PARENT, 0f, Animation.RELATIVE_TO_PARENT, 0.5f, // 起点:底部 Animation.RELATIVE_TO_PARENT, -1.2f // 终点:顶部上方(完全消失) ); animation.setDuration(8000); // 8秒 animation.setFillAfter(true); animation.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) {} @Override public void onAnimationEnd(Animation animation) { spiderView.setVisibility(View.INVISIBLE); btnTakePhoto.setVisibility(View.VISIBLE); // 恢复按钮 } @Override public void onAnimationRepeat(Animation animation) {} }); spiderView.startAnimation(animation); } }
http://www.jsqmd.com/news/385800/

相关文章:

  • 驻马店全铝衣柜定制深度评测:2026年口碑厂家如何选 - 2026年企业推荐榜
  • 从Java全栈到前端框架:一场真实的面试对话
  • 2026年作业指导书系统厂家权威推荐榜:SOP电子作业系统、SOP电子显示系统、SOP看板系统、作业指导书看板选择指南 - 优质品牌商家
  • 2026年播音主持艺考培训厂家权威推荐榜:中朝双语播音培训、中英双语播音培训、中西双语播音培训、导演培训、影视表演培训选择指南 - 优质品牌商家
  • 【计算机毕业设计】基于Spring Boot的夕阳红公寓管理系统的设计与实现
  • CT断层成像系列07——等距扇束前向投影和FBP重建(附Matlab代码)
  • 2026年厂区划线厂家权威推荐榜:厂区道路划线/地面划线/路面划线/厂区划线/市政道路划线/热熔标线/交通划线/选择指南 - 优质品牌商家
  • 【计算机毕业设计】汉服文化平台网站
  • 【毕业设计】汉服文化平台网站
  • 2026年划线厂家权威推荐榜:厂区划线/地面划线/路面划线/厂区道路划线/市政道路划线/热熔标线/交通划线/停车位划线/选择指南 - 优质品牌商家
  • 2026年道路划线公司权威推荐:地面划线/路面划线/厂区划线/厂区道路划线/市政道路划线/热熔标线/交通划线/停车位划线/选择指南 - 优质品牌商家
  • 别等图标被切了,才发现圆角是个坑
  • 2026年钢材批发市场厂家权威推荐榜:附近钢材批发市场、附近钢材采购批发、哪里有方管批发、成都方管批发、成都钢材批发选择指南 - 优质品牌商家
  • 2026年初杭州青少年内衣供应商深度评测与选型指南 - 2026年企业推荐榜
  • AionUi:开源本地AI协作平台
  • 2026年,如何选择一家真正可靠的刮泥机供应商? - 2026年企业推荐榜
  • Python量化交易:K-Means聚类与PCA降维算法
  • 好看电影网高清影视平台|最新电影电视剧在线观看网站
  • 2026年焊烟净化器公司权威推荐:高负压焊烟净化器、焊接烟尘除尘器、焊烟净化器设备、焊烟除尘器、自循环焊烟净化器选择指南 - 优质品牌商家
  • 极速电影网免费在线观看|高清电影电视剧全集更新平台
  • NLP技术赋能:打造智能多语言AI应用的5个关键步骤
  • 2026年车间焊烟净化器厂家最新推荐:高负压焊烟净化器、大型焊烟净化器、焊接机器人除尘器、焊接烟尘除尘器、焊烟净化器设备选择指南 - 优质品牌商家
  • HTML问卷调查系统信息管理系统源码-SpringBoot后端+Vue前端+MySQL【可直接运行】
  • SpringBoot+Vue web药店管理系统平台完整项目源码+SQL脚本+接口文档【Java Web毕设】
  • AI原生应用:个性化定制在医疗领域的应用实践
  • 2026年保镖公司厂家推荐:短期保镖/私人保镖价格咨询/私人保镖公司/私人保镖服务/贴身保镖/长期保镖/专业保镖/选择指南 - 优质品牌商家
  • Tomcat 安装终极指南:一篇搞定所有疑难杂症
  • 2026年唐山跳汰机厂家综合评测与选购指南 - 2026年企业推荐榜
  • 【毕业设计】SpringBoot+Vue+MySQL 图书商城管理系统平台源码+数据库+论文+部署文档
  • 2026年私人保镖厂家最新推荐:商务保镖、女保镖、王牌保镖、短期保镖、私人保镖价格咨询、私人保镖公司、私人保镖服务选择指南 - 优质品牌商家